From 8f7d263ad9cd6fbbb8c1c302256ddfdc0b5bd009 Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Wed, 8 Apr 2020 14:18:25 +0200 Subject: [PATCH] Fix livelock caused by OF not properly resetting ChunkVisibility This can lead to a livelock when rendering with shaders after exiting a singleplayer world (3/4 chance of breakage on each exit). --- .../shaders/mixin/MixinChunkVisibility.java | 32 +++++++++++++++++++ .../mixins.compat.shaders.replaymod.json | 3 ++ 2 files changed, 35 insertions(+) create mode 100644 src/main/java/com/replaymod/compat/shaders/mixin/MixinChunkVisibility.java diff --git a/src/main/java/com/replaymod/compat/shaders/mixin/MixinChunkVisibility.java b/src/main/java/com/replaymod/compat/shaders/mixin/MixinChunkVisibility.java new file mode 100644 index 00000000..f1c58c07 --- /dev/null +++ b/src/main/java/com/replaymod/compat/shaders/mixin/MixinChunkVisibility.java @@ -0,0 +1,32 @@ +//#if MC>=11500 +package com.replaymod.compat.shaders.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Pseudo +@Mixin(targets = "net/optifine/render/ChunkVisibility", remap = false) +public abstract class MixinChunkVisibility { + @Shadow + private static int counter; + + /** + * OF doesn't properly reset the counter when exiting a world. + * It'll only be reset when getMaxChunkY is called which only happens for + * SP worlds (i.e. not in a replay or MP). + * As a result, it may end up in a non-0 state, which will cause isFinished + * to unconditionally return false, therefore unconditionally setting + * needsTerrainUpdate to true on each call to WorldRenderer.setupTerrain, + * therefore unnecessarily consuming resources and live-locking when + * rendering the shader pass. + */ + @Inject(method = "reset", at = @At("HEAD"), remap = false) + private static void replayModCompat_fixImproperReset(CallbackInfo ci) { + MixinChunkVisibility.counter = 0; + } +} +//#endif diff --git a/src/main/resources/mixins.compat.shaders.replaymod.json b/src/main/resources/mixins.compat.shaders.replaymod.json index 9d1bc2db..133b1106 100644 --- a/src/main/resources/mixins.compat.shaders.replaymod.json +++ b/src/main/resources/mixins.compat.shaders.replaymod.json @@ -4,6 +4,9 @@ "mixins": [], "server": [], "client": [ + //#if MC>=11500 + "MixinChunkVisibility", + //#endif //#if MC>=10800 "MixinShaderEntityRenderer", "MixinShaderRenderChunk",