From 9184be84c88244584804565237e3aeaec06cd47e Mon Sep 17 00:00:00 2001 From: FalsePattern Date: Sun, 26 Nov 2023 21:05:42 +0100 Subject: [PATCH] rewrote some logic to be allocation-free --- .../threadedupdates/RenderBlocksMixin.java | 44 +++++++++++++------ .../modules/occlusion/OcclusionRenderer.java | 5 ++- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/main/java/com/falsepattern/falsetweaks/mixin/mixins/client/threadedupdates/RenderBlocksMixin.java b/src/main/java/com/falsepattern/falsetweaks/mixin/mixins/client/threadedupdates/RenderBlocksMixin.java index 950ad3d8..fc46e9c0 100644 --- a/src/main/java/com/falsepattern/falsetweaks/mixin/mixins/client/threadedupdates/RenderBlocksMixin.java +++ b/src/main/java/com/falsepattern/falsetweaks/mixin/mixins/client/threadedupdates/RenderBlocksMixin.java @@ -24,7 +24,9 @@ import lombok.val; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Constant; import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyConstant; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; @@ -37,12 +39,20 @@ @Mixin(RenderBlocks.class) public abstract class RenderBlocksMixin { - @Inject(method = "renderBlockByRenderType", - at = @At(value = "INVOKE", - target = "Lnet/minecraft/block/Block;setBlockBoundsBasedOnState(Lnet/minecraft/world/IBlockAccess;III)V"), - cancellable = true, - locals = LocalCapture.CAPTURE_FAILHARD) - private void cancelRenderDelegatedToDifferentThread(Block block, int x, int y, int z, CallbackInfoReturnable cir, int renderType) { + private int returnBoolCancel; + /** + * @author FalsePattern + * @reason CallbackInfoReturnable from a regular injection is really expensive and allocation spammy, + * so we sidestep it by shuffling data through a field + */ + @Redirect(method = "renderBlockByRenderType", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/block/Block;getRenderType()I", + ordinal = 0), + require = 1) + private int cancelRenderDelegatedToDifferentThread1(Block block) { + returnBoolCancel = 0; + int renderType = block.getRenderType(); int pass = ForgeHooksClient.getWorldRenderPass(); boolean mainThread = Thread.currentThread() == ThreadedChunkUpdateHelper.MAIN_THREAD; @@ -51,17 +61,23 @@ private void cancelRenderDelegatedToDifferentThread(Block block, int x, int y, i val task = ((IRendererUpdateResultHolder) ThreadedChunkUpdateHelper.lastWorldRenderer).ft$getRendererUpdateTask(); if (task != null && !task.cancelled && renderableOffThread && pass >= 0) { - cir.setReturnValue(task.result[pass].renderedSomething); - } - } else { - if (!renderableOffThread) { - cir.setReturnValue(false); + returnBoolCancel = task.result[pass].renderedSomething ? 1 : 0; + return -1; } + } else if (!renderableOffThread) { + return -1; } + return renderType; + } - if (cir.isCancelled()) { - OptiFineCompat.popEntity(); - } + //Minecraft Dev plugin for intellij incorrectly assumes this to the "0" in the switch + //In reality, this replaces the "return false;" statement in the -1 case + @ModifyConstant(method = "renderBlockByRenderType", + constant = @Constant(intValue = 0, + ordinal = 0), + require = 1) + private int fakeReturn(int value) { + return returnBoolCancel; } @Inject(method = "renderBlockByRenderType", diff --git a/src/main/java/com/falsepattern/falsetweaks/modules/occlusion/OcclusionRenderer.java b/src/main/java/com/falsepattern/falsetweaks/modules/occlusion/OcclusionRenderer.java index 7b72e00d..c5ba2cdf 100644 --- a/src/main/java/com/falsepattern/falsetweaks/modules/occlusion/OcclusionRenderer.java +++ b/src/main/java/com/falsepattern/falsetweaks/modules/occlusion/OcclusionRenderer.java @@ -140,7 +140,10 @@ public void internalMarkBlockUpdate(int x1, int y1, int z1, int x2, int y2, int OcclusionCompat.DragonAPICompat.ChangePacketRenderer$onChunkRerender(x1, y1, z1, x2, y2, z2, worldrenderer); OcclusionHelpers.worker.dirty = true; } else { - for(IRenderGlobalListener l : eventListeners) l.onDirtyRendererChanged(worldrenderer); + int size = eventListeners.size(); + for(int m = -1; ++m < size;) { + eventListeners.get(m).onDirtyRendererChanged(worldrenderer); + } } } }