From cad4753e910ea1971bb4ea523a32e7f58cab3df5 Mon Sep 17 00:00:00 2001 From: mineLdiver Date: Mon, 20 Nov 2023 04:57:26 +0500 Subject: [PATCH] Initial tests --- .../client/render/ChunkBuilderManager.java | 12 +++++ .../client/render/UpdateThread.java | 33 ++++++++++++++ .../multidraw/BlockRenderManagerMixin.java | 24 ++++++++++ .../client/multidraw/ChunkRendererMixin.java | 38 ++++++++++++++-- .../client/multidraw/TessellatorAccessor.java | 18 ++++++++ .../client/multidraw/TessellatorMixin.java | 44 +++++++++++++++++-- src/main/resources/smoothbeta.mixins.json | 2 + 7 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 src/main/java/net/mine_diver/smoothbeta/client/render/ChunkBuilderManager.java create mode 100644 src/main/java/net/mine_diver/smoothbeta/client/render/UpdateThread.java create mode 100644 src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/BlockRenderManagerMixin.java create mode 100644 src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/TessellatorAccessor.java diff --git a/src/main/java/net/mine_diver/smoothbeta/client/render/ChunkBuilderManager.java b/src/main/java/net/mine_diver/smoothbeta/client/render/ChunkBuilderManager.java new file mode 100644 index 0000000..b0cebd3 --- /dev/null +++ b/src/main/java/net/mine_diver/smoothbeta/client/render/ChunkBuilderManager.java @@ -0,0 +1,12 @@ +package net.mine_diver.smoothbeta.client.render; + +import net.mine_diver.smoothbeta.mixin.client.multidraw.TessellatorAccessor; +import net.minecraft.client.render.Tessellator; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class ChunkBuilderManager { + public static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor(); + public static final Tessellator THREAD_TESSELLATOR = TessellatorAccessor.smoothbeta_create(((TessellatorAccessor) Tessellator.INSTANCE).smoothbeta_getBufferSize()); +} diff --git a/src/main/java/net/mine_diver/smoothbeta/client/render/UpdateThread.java b/src/main/java/net/mine_diver/smoothbeta/client/render/UpdateThread.java new file mode 100644 index 0000000..56425df --- /dev/null +++ b/src/main/java/net/mine_diver/smoothbeta/client/render/UpdateThread.java @@ -0,0 +1,33 @@ +package net.mine_diver.smoothbeta.client.render; + +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.Executors; + +public class UpdateThread extends Thread { + private static final Object LOCK = new Object(); + private static final Queue TASKS = new ConcurrentLinkedQueue<>(); + + public static void enqueue(Runnable task) { + TASKS.add(task); + LOCK.notifyAll(); + } + + public UpdateThread() { + setDaemon(true); + } + + @Override + public void run() { +// Executors.newSingleThreadExecutor().execute(); +// while (true) { +// try { +// LOCK.wait(); +// } catch (InterruptedException e) { +// continue; +// } +// Runnable task; +// while ((task = TASKS.poll()) != null) task.run(); +// } + } +} diff --git a/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/BlockRenderManagerMixin.java b/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/BlockRenderManagerMixin.java new file mode 100644 index 0000000..e1fc4f7 --- /dev/null +++ b/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/BlockRenderManagerMixin.java @@ -0,0 +1,24 @@ +package net.mine_diver.smoothbeta.mixin.client.multidraw; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import net.mine_diver.smoothbeta.client.render.ChunkBuilderManager; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.block.BlockRenderManager; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(BlockRenderManager.class) +public class BlockRenderManagerMixin { + @ModifyExpressionValue( + method = "*", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/client/render/Tessellator;INSTANCE:Lnet/minecraft/client/render/Tessellator;", + opcode = Opcodes.GETSTATIC + ) + ) + private static Tessellator smoothbeta_getTessellator(Tessellator tessellator) { + return Thread.currentThread().getName().equals("Minecraft main thread") ? tessellator : ChunkBuilderManager.THREAD_TESSELLATOR; + } +} diff --git a/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/ChunkRendererMixin.java b/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/ChunkRendererMixin.java index c9ae9bc..28c37b2 100644 --- a/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/ChunkRendererMixin.java +++ b/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/ChunkRendererMixin.java @@ -1,10 +1,9 @@ package net.mine_diver.smoothbeta.mixin.client.multidraw; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; import net.fabricmc.loader.api.FabricLoader; -import net.mine_diver.smoothbeta.client.render.SmoothChunkRenderer; -import net.mine_diver.smoothbeta.client.render.SmoothTessellator; -import net.mine_diver.smoothbeta.client.render.SmoothWorldRenderer; -import net.mine_diver.smoothbeta.client.render.VboPool; +import net.mine_diver.smoothbeta.client.render.*; import net.mine_diver.smoothbeta.client.render.gl.VertexBuffer; import net.minecraft.block.entity.BlockEntity; import net.minecraft.class_42; @@ -12,6 +11,7 @@ import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.block.BlockRenderManager; import net.minecraft.client.render.chunk.ChunkBuilder; +import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; @@ -22,6 +22,8 @@ import java.util.HashSet; +import static net.mine_diver.smoothbeta.client.render.ChunkBuilderManager.THREAD_TESSELLATOR; + @Mixin(ChunkBuilder.class) class ChunkRendererMixin implements SmoothChunkRenderer { @Shadow private static Tessellator tessellator; @@ -100,4 +102,32 @@ private void smoothbeta_stopRenderingTerrain(CallbackInfo ci) { smoothbeta_currentBufferIndex = -1; ((SmoothTessellator) tessellator).smoothbeta_stopRenderingTerrain(); } + + @ModifyExpressionValue( + method = "", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/client/render/Tessellator;INSTANCE:Lnet/minecraft/client/render/Tessellator;", + opcode = Opcodes.GETSTATIC + ) + ) + private static Tessellator smoothbeta_returnThreadTessellator(Tessellator value) { + return THREAD_TESSELLATOR; + } + + @Inject( + method = "rebuild", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/client/render/chunk/ChunkBuilder;chunkUpdates:I", + opcode = Opcodes.GETSTATIC + ), + cancellable = true + ) + private void smoothbeta_execute(CallbackInfo ci) { + if (Thread.currentThread().getName().equals("Minecraft main thread")) { + ChunkBuilderManager.EXECUTOR_SERVICE.execute(((ChunkBuilder) (Object) this)::rebuild); + ci.cancel(); + } + } } diff --git a/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/TessellatorAccessor.java b/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/TessellatorAccessor.java new file mode 100644 index 0000000..300ae71 --- /dev/null +++ b/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/TessellatorAccessor.java @@ -0,0 +1,18 @@ +package net.mine_diver.smoothbeta.mixin.client.multidraw; + +import net.minecraft.client.render.Tessellator; +import net.modificationstation.stationapi.api.util.Util; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(Tessellator.class) +public interface TessellatorAccessor { + @Invoker("") + static Tessellator smoothbeta_create(int bufferSize) { + return Util.assertMixin(); + } + + @Accessor("bufferSize") + int smoothbeta_getBufferSize(); +} diff --git a/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/TessellatorMixin.java b/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/TessellatorMixin.java index 475cfcb..7dba80c 100644 --- a/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/TessellatorMixin.java +++ b/src/main/java/net/mine_diver/smoothbeta/mixin/client/multidraw/TessellatorMixin.java @@ -2,10 +2,11 @@ import net.mine_diver.smoothbeta.client.render.SmoothChunkRenderer; import net.mine_diver.smoothbeta.client.render.SmoothTessellator; +import net.mine_diver.smoothbeta.client.render.gl.VertexBuffer; import net.minecraft.client.render.Tessellator; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; +import net.modificationstation.stationapi.api.tick.TickScheduler; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Constant; import org.spongepowered.asm.mixin.injection.Inject; @@ -19,6 +20,13 @@ abstract class TessellatorMixin implements SmoothTessellator { @Shadow protected abstract void reset(); @Shadow private ByteBuffer byteBuffer; + + @Mutable + @Shadow @Final public static Tessellator INSTANCE; + + @Unique + private static Tessellator smoothbeta_vanillaInstance; + @Unique private boolean smoothbeta_renderingTerrain; @Unique @@ -29,6 +37,7 @@ abstract class TessellatorMixin implements SmoothTessellator { public void smoothbeta_startRenderingTerrain(SmoothChunkRenderer chunkRenderer) { smoothbeta_renderingTerrain = true; smoothbeta_chunkRenderer = chunkRenderer; +// INSTANCE = (Tessellator) (Object) this; } @Override @@ -36,6 +45,7 @@ public void smoothbeta_startRenderingTerrain(SmoothChunkRenderer chunkRenderer) public void smoothbeta_stopRenderingTerrain() { smoothbeta_renderingTerrain = false; smoothbeta_chunkRenderer = null; +// INSTANCE = smoothbeta_vanillaInstance; } @Override @@ -54,11 +64,24 @@ public boolean smoothbeta_isRenderingTerrain() { ) private void smoothbeta_uploadTerrain(CallbackInfo ci) { if (!smoothbeta_renderingTerrain) return; - smoothbeta_chunkRenderer.smoothbeta_getCurrentBuffer().upload(byteBuffer); + ByteBuffer byteBuffer1 = clone(byteBuffer); + VertexBuffer vertexBuffer = smoothbeta_chunkRenderer.smoothbeta_getCurrentBuffer(); + TickScheduler.CLIENT_RENDER_START.immediate(() -> vertexBuffer.upload(byteBuffer1)); reset(); ci.cancel(); } + @Unique + private static ByteBuffer clone(ByteBuffer original) { + ByteBuffer clone = ByteBuffer.allocateDirect(original.capacity()); + original.rewind(); + clone.put(original); +// original.rewind(); +// clone.flip(); + return clone; + } + + @ModifyConstant( method = "vertex(DDD)V", constant = @Constant(intValue = 7) @@ -77,4 +100,17 @@ private int smoothbeta_prohibitExtraVertices(int constant) { private int smoothbeta_compactVertices(int constant) { return smoothbeta_renderingTerrain ? 7 : 8; } + + @Inject( + method = "", + at = @At( + value = "FIELD", + target = "Lnet/minecraft/client/render/Tessellator;INSTANCE:Lnet/minecraft/client/render/Tessellator;", + opcode = Opcodes.PUTSTATIC, + shift = At.Shift.AFTER + ) + ) + private static void smoothbeta_setVanillaInstance(CallbackInfo ci) { + smoothbeta_vanillaInstance = INSTANCE; + } } diff --git a/src/main/resources/smoothbeta.mixins.json b/src/main/resources/smoothbeta.mixins.json index 7c8874e..52ef5d5 100644 --- a/src/main/resources/smoothbeta.mixins.json +++ b/src/main/resources/smoothbeta.mixins.json @@ -7,8 +7,10 @@ "client.MinecraftAccessor", "client.MixinEntityRendererDispatcher", "client.MixinTileEntityRenderDispatcher", + "client.multidraw.BlockRenderManagerMixin", "client.multidraw.ChunkRendererMixin", "client.multidraw.RenderListAccessor", + "client.multidraw.TessellatorAccessor", "client.multidraw.TessellatorMixin", "client.multidraw.WorldRendererMixin", "client.multidraw.compat.arsenic.ArsenicTessellatorMixin",