From ffe17e4449c0a02b894e76f42727e3efed2fd1ae Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Fri, 17 Dec 2021 02:17:39 -0800 Subject: [PATCH] Use task engine/sync to update instances --- .../backend/instancing/InstanceManager.java | 71 +++++++++++++------ .../backend/instancing/InstanceWorld.java | 23 +++--- .../instancing/batching/BatchingEngine.java | 2 - .../entity/EntityInstanceManager.java | 6 +- .../instancing/tile/TileInstanceManager.java | 6 +- .../crumbling/CrumblingInstanceManager.java | 3 +- 6 files changed, 71 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java index 14c51f360..758168b9b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java @@ -3,6 +3,7 @@ package com.jozufozu.flywheel.backend.instancing; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; @@ -31,11 +32,13 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift protected final Map instances; protected final Object2ObjectOpenHashMap tickableInstances; protected final Object2ObjectOpenHashMap dynamicInstances; + private final TaskEngine taskEngine; protected int frame; protected int tick; - public InstanceManager(MaterialManager materialManager) { + public InstanceManager(TaskEngine taskEngine, MaterialManager materialManager) { + this.taskEngine = taskEngine; this.materialManager = materialManager; this.queuedUpdates = new HashSet<>(64); this.queuedAdditions = new HashSet<>(64); @@ -84,25 +87,39 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift int cY = (int) cameraY; int cZ = (int) cameraZ; - if (tickableInstances.size() > 0) { - tickableInstances.object2ObjectEntrySet().parallelStream().forEach(e -> { - ITickableInstance instance = e.getValue(); - if (!instance.decreaseTickRateWithDistance()) { - instance.tick(); - return; + ArrayList instances = new ArrayList<>(tickableInstances.values()); + int incr = 500; + int size = instances.size(); + int start = 0; + while (start < size) { + int end = Math.min(start + incr, size); + + List sub = instances.subList(start, end); + taskEngine.submit(() -> { + for (ITickableInstance instance : sub) { + tickInstance(cX, cY, cZ, instance); } - - BlockPos pos = instance.getWorldPosition(); - - int dX = pos.getX() - cX; - int dY = pos.getY() - cY; - int dZ = pos.getZ() - cZ; - - if ((tick % getUpdateDivisor(dX, dY, dZ)) == 0) instance.tick(); }); + + start += incr; } } + private void tickInstance(int cX, int cY, int cZ, ITickableInstance instance) { + if (!instance.decreaseTickRateWithDistance()) { + instance.tick(); + return; + } + + BlockPos pos = instance.getWorldPosition(); + + int dX = pos.getX() - cX; + int dY = pos.getY() - cY; + int dZ = pos.getZ() - cZ; + + if ((tick % getUpdateDivisor(dX, dY, dZ)) == 0) instance.tick(); + } + public void beginFrame(Camera info) { frame++; processQueuedAdditions(); @@ -117,14 +134,22 @@ public abstract class InstanceManager implements InstancingEngine.OriginShift int cY = (int) info.getPosition().y; int cZ = (int) info.getPosition().z; - if (dynamicInstances.size() > 0) { - dynamicInstances.object2ObjectEntrySet() - .parallelStream() - .forEach(e -> { - IDynamicInstance dyn = e.getValue(); - if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ)) - dyn.beginFrame(); - }); + ArrayList instances = new ArrayList<>(dynamicInstances.values()); + int incr = 500; + int size = instances.size(); + int start = 0; + while (start < size) { + int end = Math.min(start + incr, size); + + List sub = instances.subList(start, end); + taskEngine.submit(() -> { + for (IDynamicInstance dyn : sub) { + if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ)) + dyn.beginFrame(); + } + }); + + start += incr; } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java index a0050a65f..10862c154 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java @@ -29,12 +29,12 @@ public class InstanceWorld { protected final InstanceManager entityInstanceManager; protected final InstanceManager tileEntityInstanceManager; - protected final BatchExecutor executor; + protected final BatchExecutor taskEngine; public InstanceWorld() { - this.executor = new BatchExecutor(); - this.executor.startWorkers(); + this.taskEngine = new BatchExecutor(); + this.taskEngine.startWorkers(); FlwEngine engine = Backend.getInstance() .getEngine(); @@ -42,19 +42,19 @@ public class InstanceWorld { switch (engine) { case GL33 -> { InstancingEngine manager = InstancingEngine.builder(Contexts.WORLD) - .build(this.executor); + .build(this.taskEngine); - entityInstanceManager = new EntityInstanceManager(manager); - tileEntityInstanceManager = new TileInstanceManager(manager); + entityInstanceManager = new EntityInstanceManager(this.taskEngine, manager); + tileEntityInstanceManager = new TileInstanceManager(this.taskEngine, manager); manager.addListener(entityInstanceManager); manager.addListener(tileEntityInstanceManager); this.engine = manager; } case BATCHING -> { - this.engine = new BatchingEngine(this.executor); - entityInstanceManager = new EntityInstanceManager(this.engine); - tileEntityInstanceManager = new TileInstanceManager(this.engine); + this.engine = new BatchingEngine(this.taskEngine); + entityInstanceManager = new EntityInstanceManager(this.taskEngine, this.engine); + tileEntityInstanceManager = new TileInstanceManager(this.taskEngine, this.engine); } default -> throw new IllegalArgumentException("Unknown engine type"); } @@ -72,7 +72,7 @@ public class InstanceWorld { * Free all acquired resources and invalidate this instance world. */ public void delete() { - this.executor.stopWorkers(); + this.taskEngine.stopWorkers(); engine.delete(); entityInstanceManager.detachLightListeners(); tileEntityInstanceManager.detachLightListeners(); @@ -89,6 +89,8 @@ public class InstanceWorld { public void beginFrame(BeginFrameEvent event) { engine.beginFrame(event.getInfo()); + taskEngine.syncPoint(); + tileEntityInstanceManager.beginFrame(event.getInfo()); entityInstanceManager.beginFrame(event.getInfo()); } @@ -113,6 +115,7 @@ public class InstanceWorld { * Draw the given layer. */ public void renderLayer(RenderLayerEvent event) { + taskEngine.syncPoint(); engine.render(event, event.buffers.bufferSource()); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java index 7d8377ae3..e1dc909af 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java @@ -49,8 +49,6 @@ public class BatchingEngine implements Engine { stack.translate(-event.camX, -event.camY, -event.camZ); - taskEngine.syncPoint(); - for (Map.Entry entry : layers.get(event.getLayer()).entrySet()) { BatchedMaterialGroup group = entry.getValue(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java index 223f725fb..2b3af7808 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstanceManager.java @@ -3,8 +3,10 @@ package com.jozufozu.flywheel.backend.instancing.entity; import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.instancing.AbstractInstance; +import com.jozufozu.flywheel.backend.instancing.BatchExecutor; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry; +import com.jozufozu.flywheel.backend.instancing.TaskEngine; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.Entity; @@ -13,8 +15,8 @@ import net.minecraft.world.level.Level; public class EntityInstanceManager extends InstanceManager { - public EntityInstanceManager(MaterialManager materialManager) { - super(materialManager); + public EntityInstanceManager(TaskEngine executor, MaterialManager materialManager) { + super(executor, materialManager); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileInstanceManager.java index aa4e6c274..c0b65215d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileInstanceManager.java @@ -3,8 +3,10 @@ package com.jozufozu.flywheel.backend.instancing.tile; import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.instancing.AbstractInstance; +import com.jozufozu.flywheel.backend.instancing.BatchExecutor; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry; +import com.jozufozu.flywheel.backend.instancing.TaskEngine; import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockGetter; @@ -13,8 +15,8 @@ import net.minecraft.world.level.block.entity.BlockEntity; public class TileInstanceManager extends InstanceManager { - public TileInstanceManager(MaterialManager materialManager) { - super(materialManager); + public TileInstanceManager(TaskEngine executor, MaterialManager materialManager) { + super(executor, materialManager); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java index 30e427f6b..bea324fd4 100644 --- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java @@ -1,6 +1,7 @@ package com.jozufozu.flywheel.core.crumbling; import com.jozufozu.flywheel.api.MaterialManager; +import com.jozufozu.flywheel.backend.instancing.ImmediateExecutor; import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager; import net.minecraft.core.BlockPos; @@ -8,7 +9,7 @@ import net.minecraft.core.BlockPos; public class CrumblingInstanceManager extends TileInstanceManager { public CrumblingInstanceManager(MaterialManager materialManager) { - super(materialManager); + super(ImmediateExecutor.INSTANCE, materialManager); } @Override