And I oobe

- Raise exception when trying to slice outside DrawBuffer bounds
- Count vertices in BufferPlan#execute to account for instance creation
  during Visual updates
- Mark DrawBuffers active by default
This commit is contained in:
Jozufozu 2023-04-17 15:02:45 -07:00
parent 7afa2486ad
commit b30d686785
4 changed files with 29 additions and 19 deletions

View File

@ -40,6 +40,13 @@ public class BatchingDrawTracker {
}
}
public void markInactive(RenderStage stage, DrawBuffer buffer) {
synchronized (activeBuffers) {
activeBuffers.get(stage)
.remove(buffer);
}
}
/**
* Draw and reset all DrawBuffers for the given RenderStage.
*
@ -75,7 +82,9 @@ public class BatchingDrawTracker {
}
public boolean hasStage(RenderStage stage) {
return !activeBuffers.get(stage)
.isEmpty();
synchronized (activeBuffers) {
return !activeBuffers.get(stage)
.isEmpty();
}
}
}

View File

@ -51,15 +51,10 @@ public class BatchingEngine extends AbstractEngine {
var stack = FlwUtil.copyPoseStack(context.stack());
stack.translate(renderOrigin.getX() - cameraPos.x, renderOrigin.getY() - cameraPos.y, renderOrigin.getZ() - cameraPos.z);
double cameraX = cameraPos.x;
double cameraY = cameraPos.y;
double cameraZ = cameraPos.z;
org.joml.Matrix4f proj = MatrixUtil.toJoml(context.viewProjection());
proj.translate((float) (renderOrigin.getX() - cameraX), (float) (renderOrigin.getY() - cameraY), (float) (renderOrigin.getZ() - cameraZ));
FrustumIntersection frustum = new FrustumIntersection(proj);
proj.translate((float) (renderOrigin.getX() - cameraPos.x), (float) (renderOrigin.getY() - cameraPos.y), (float) (renderOrigin.getZ() - cameraPos.z));
var ctx = new FrameContext(context.level(), stack.last(), frustum);
var ctx = new FrameContext(context.level(), stack.last(), new FrustumIntersection(proj));
flush();

View File

@ -11,7 +11,6 @@ import com.jozufozu.flywheel.api.task.Plan;
import com.jozufozu.flywheel.api.task.TaskExecutor;
import com.jozufozu.flywheel.lib.task.NestedPlan;
import com.jozufozu.flywheel.lib.task.Synchronizer;
import com.jozufozu.flywheel.lib.task.UnitPlan;
import net.minecraft.client.renderer.RenderType;
@ -51,7 +50,6 @@ public class BatchingStage {
private final DrawBuffer buffer;
private final List<TransformCall<?>> transformCalls = new ArrayList<>();
private FrameContext ctx;
private int vertexCount;
public BufferPlan(DrawBuffer drawBuffer) {
buffer = drawBuffer;
@ -60,14 +58,7 @@ public class BatchingStage {
public Plan update(FrameContext ctx) {
this.ctx = ctx;
vertexCount = setupAndCountVertices();
if (vertexCount <= 0) {
return UnitPlan.INSTANCE;
}
// Moving this into execute leads to a race condition that causes things to flash in and out of existence.
// Sometimes the main thread decides there's nothing to render in a stage before the worker threads have
// marked a stage as active. Then in the next frame #markActive complains because it's already prepared.
// Mark the tracker active by default...
tracker.markActive(stage, buffer);
return this;
}
@ -78,7 +69,18 @@ public class BatchingStage {
@Override
public void execute(TaskExecutor taskExecutor, Runnable onCompletion) {
// Count vertices here to account for instances being added during Visual updates.
var vertexCount = setupAndCountVertices();
if (vertexCount <= 0) {
// ...then mark it inactive if there's nothing to draw.
tracker.markInactive(stage, buffer);
onCompletion.run();
return;
}
AtomicInteger vertexCounter = new AtomicInteger(0);
buffer.prepare(vertexCount);
var synchronizer = new Synchronizer(transformCalls.size(), () -> {

View File

@ -65,6 +65,10 @@ public class TransformCall<I extends Instance> {
final int baseVertex = vertexCount.getAndAdd(meshVertexCount);
if (baseVertex + meshVertexCount > buffer.getVertexCount()) {
throw new IndexOutOfBoundsException("Vertex count greater than allocated: " + baseVertex + " + " + meshVertexCount + " > " + buffer.getVertexCount());
}
var sub = buffer.slice(baseVertex, meshVertexCount);
mesh.copyTo(sub.ptr());