Skip to content

Commit 5c983a7

Browse files
committed
Robust reload on pipeline state change
- Revert LightDataManager.reload() change from 2 days ago
1 parent 462c059 commit 5c983a7

File tree

8 files changed

+83
-42
lines changed

8 files changed

+83
-42
lines changed

src/main/java/grondag/canvas/apiimpl/CanvasState.java

+62-19
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import grondag.canvas.material.property.TextureMaterialState;
3535
import grondag.canvas.perf.ChunkRebuildCounters;
3636
import grondag.canvas.perf.Timekeeper;
37+
import grondag.canvas.pipeline.Pipeline;
3738
import grondag.canvas.pipeline.PipelineManager;
3839
import grondag.canvas.pipeline.config.PipelineLoader;
3940
import grondag.canvas.shader.GlMaterialProgramManager;
@@ -46,27 +47,69 @@
4647
import grondag.canvas.terrain.util.ChunkColorCache;
4748

4849
public class CanvasState {
49-
public static void recompileIfNeeded(boolean forceRecompile) {
50-
while (CanvasMod.RECOMPILE.consumeClick()) {
51-
forceRecompile = true;
50+
public static void handleRecompileKeybind() {
51+
final boolean recompilePressed = CanvasMod.RECOMPILE.consumeClick();
52+
53+
while (true) {
54+
// consume all clicks
55+
if (!CanvasMod.RECOMPILE.consumeClick()) {
56+
break;
57+
}
58+
}
59+
60+
if (recompilePressed) {
61+
recompile(false);
62+
}
63+
}
64+
65+
public static void recompile() {
66+
recompile(false);
67+
}
68+
69+
private static int loopCounter = 0;
70+
71+
private static boolean recompilePipeline() {
72+
final boolean prevColorLightsState = Pipeline.coloredLightsEnabled();
73+
final boolean prevAdvancedCullingState = Pipeline.advancedTerrainCulling();
74+
75+
PipelineLoader.reload(Minecraft.getInstance().getResourceManager());
76+
PipelineManager.reload();
77+
78+
final boolean coloredLightsChanged = Pipeline.coloredLightsEnabled() && !prevColorLightsState;
79+
final boolean requireCullingRebuild = Pipeline.advancedTerrainCulling() && !prevAdvancedCullingState;
80+
81+
return coloredLightsChanged || requireCullingRebuild;
82+
}
83+
84+
private static void recompile(boolean alreadyReloaded) {
85+
CanvasMod.LOG.info(I18n.get("info.canvas.recompile"));
86+
87+
final boolean requireReload = recompilePipeline();
88+
89+
if (!alreadyReloaded && loopCounter < 2 && requireReload) {
90+
CanvasMod.LOG.info(I18n.get("info.canvas.recompile_needs_reload"));
91+
loopCounter++;
92+
Minecraft.getInstance().levelRenderer.allChanged();
93+
return;
5294
}
5395

54-
if (forceRecompile) {
55-
CanvasMod.LOG.info(I18n.get("info.canvas.recompile"));
56-
PipelineLoader.reload(Minecraft.getInstance().getResourceManager());
57-
PipelineManager.reload();
58-
LightDataManager.reload();
59-
PreReleaseShaderCompat.reload();
60-
MaterialProgram.reload();
61-
GlShaderManager.INSTANCE.reload();
62-
GlProgramManager.INSTANCE.reload();
63-
GlMaterialProgramManager.INSTANCE.reload();
64-
// LightmapHdTexture.reload();
65-
// LightmapHd.reload();
66-
TextureMaterialState.reload();
67-
ShaderDataManager.reload();
68-
Timekeeper.configOrPipelineReload();
96+
LightDataManager.reload();
97+
PreReleaseShaderCompat.reload();
98+
MaterialProgram.reload();
99+
GlShaderManager.INSTANCE.reload();
100+
GlProgramManager.INSTANCE.reload();
101+
GlMaterialProgramManager.INSTANCE.reload();
102+
// LightmapHdTexture.reload();
103+
// LightmapHd.reload();
104+
TextureMaterialState.reload();
105+
ShaderDataManager.reload();
106+
Timekeeper.configOrPipelineReload();
107+
108+
if (loopCounter > 1) {
109+
CanvasMod.LOG.warn("Reloading recursively twice or more. This isn't supposed to happen.");
69110
}
111+
112+
loopCounter = 0;
70113
}
71114

72115
public static void reload() {
@@ -79,6 +122,6 @@ public static void reload() {
79122
ChunkColorCache.invalidate();
80123
AoFace.clampExteriorVertices(Configurator.clampExteriorVertices);
81124

82-
recompileIfNeeded(true);
125+
recompile(true);
83126
}
84127
}

src/main/java/grondag/canvas/config/CanvasConfigScreen.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ private void save() {
528528
Timekeeper.configOrPipelineReload();
529529
}
530530

531-
ConfigManager.saveUserInput(reload ? RELOAD_EVERYTHING : DONT_RELOAD);
531+
ConfigManager.saveCanvasConfig(reload ? RELOAD_EVERYTHING : DONT_RELOAD);
532532

533533
if (requiresRestart) {
534534
this.minecraft.setScreen(new ConfigRestartScreen(this.parent));

src/main/java/grondag/canvas/config/ConfigManager.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public static void savePipelineOptions(OptionConfig[] options) {
120120
CanvasMod.LOG.error("Error loading pipeline config. Using default values.");
121121
}
122122

123-
CanvasState.recompileIfNeeded(true);
123+
CanvasState.recompile();
124124
}
125125

126126
private static void saveConfig() {
@@ -163,12 +163,12 @@ static void loadConfig() {
163163
Configurator.readFromConfig(config, true);
164164
}
165165

166-
static void saveUserInput(Reload reload) {
166+
static void saveCanvasConfig(Reload reload) {
167167
saveConfig();
168168

169169
switch (reload) {
170170
case RELOAD_EVERYTHING -> Minecraft.getInstance().levelRenderer.allChanged();
171-
case RELOAD_PIPELINE -> CanvasState.recompileIfNeeded(true);
171+
case RELOAD_PIPELINE -> CanvasState.recompile();
172172
case DONT_RELOAD -> { }
173173
}
174174
}

src/main/java/grondag/canvas/config/PipelineOptionScreen.java

+1-9
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
package grondag.canvas.config;
2222

23-
import static grondag.canvas.config.ConfigManager.Reload.RELOAD_EVERYTHING;
2423
import static grondag.canvas.config.ConfigManager.Reload.RELOAD_PIPELINE;
2524

2625
import java.util.List;
@@ -40,7 +39,6 @@
4039
import grondag.canvas.config.gui.BaseButton;
4140
import grondag.canvas.config.gui.BaseScreen;
4241
import grondag.canvas.config.gui.ListWidget;
43-
import grondag.canvas.pipeline.Pipeline;
4442
import grondag.canvas.pipeline.config.PipelineConfig;
4543
import grondag.canvas.pipeline.config.PipelineConfigBuilder;
4644
import grondag.canvas.pipeline.config.PipelineLoader;
@@ -118,14 +116,8 @@ protected void init() {
118116
}
119117

120118
private void savePipelineSelection(ResourceLocation newPipelineId) {
121-
final var newPipeline = PipelineLoader.get(newPipelineId.toString());
122-
123-
boolean shadowsChanged = Pipeline.shadowsEnabled() != newPipeline.shadowsEnabled;
124-
boolean coloredLightsChanged = Pipeline.coloredLightsEnabled() != newPipeline.coloredLightsEnabled;
125-
boolean needRegionsReloaded = (shadowsChanged && !Configurator.advancedTerrainCulling) || coloredLightsChanged;
126-
127119
Configurator.pipelineId = newPipelineId.toString();
128-
ConfigManager.saveUserInput(needRegionsReloaded ? RELOAD_EVERYTHING : RELOAD_PIPELINE);
120+
ConfigManager.saveCanvasConfig(RELOAD_PIPELINE);
129121
}
130122

131123
private void save() {

src/main/java/grondag/canvas/light/color/LightDataManager.java

+12-7
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,21 @@ public static LightRegionAccess allocate(BlockPos regionOrigin) {
5050
}
5151

5252
public static void reload() {
53-
if (INSTANCE != null) {
54-
INSTANCE.close();
55-
INSTANCE = null;
56-
}
57-
5853
if (Pipeline.coloredLightsEnabled()) {
5954
assert Pipeline.config().coloredLights != null;
6055

61-
INSTANCE = new LightDataManager();
56+
// NB: this is a shader recompile, not chunk storage reload. DON'T destroy existing instance.
57+
if (INSTANCE == null) {
58+
INSTANCE = new LightDataManager();
59+
}
60+
6261
INSTANCE.useOcclusionData = Pipeline.config().coloredLights.useOcclusionData;
62+
} else {
63+
// If colored lights state change, we can clean this up as the next state change will trigger chunk storage reload.
64+
if (INSTANCE != null) {
65+
INSTANCE.close();
66+
INSTANCE = null;
67+
}
6368
}
6469
}
6570

@@ -341,7 +346,7 @@ public void end() {
341346
minUpdateTimeNanos = Math.min(elapsedNanos, minUpdateTimeNanos);
342347
maxUpdateTimeNanos = Math.max(elapsedNanos, maxUpdateTimeNanos);
343348
totalUpdateTimeNanos += elapsedNanos;
344-
totalUpdatePerformed ++;
349+
totalUpdatePerformed++;
345350

346351
if (System.nanoTime() - startTimeOverall > 10000000000L) {
347352
CanvasMod.LOG.info("Colored Lights profiler output:");

src/main/java/grondag/canvas/render/world/CanvasWorldRenderer.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,7 @@ public void renderLevel(PoseStack viewMatrixStack, float tickDelta, long frameSt
851851
BufferSynchronizer.checkPoint();
852852
DirectBufferAllocator.update();
853853
TransferBuffers.update();
854-
CanvasState.recompileIfNeeded(false);
854+
CanvasState.handleRecompileKeybind();
855855
FlawlessFramesController.handleToggle();
856856

857857
if (wasFabulous != Pipeline.isFabulous()) {

src/main/java/grondag/canvas/shader/data/AccessibilityData.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public class AccessibilityData {
4141

4242
public static void onCloseOptionScreen() {
4343
if (AccessibilityData.checkChanged() && Minecraft.getInstance().level != null) {
44-
CanvasState.recompileIfNeeded(true);
44+
CanvasState.recompile();
4545
}
4646
}
4747

src/main/resources/assets/canvas/lang/en_us.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,6 @@
204204
"config.canvas.help.trace_texture_load": "Log significant events of texture/sprite atlas loading.;For debugging use. Will spam the log.",
205205
"config.canvas.value.bloom_toggle": "Enable Bloom",
206206
"config.canvas.help.bloom_toggle": "Renders glow effect around light sources.;Modest impact on performance.",
207-
"info.canvas.recompile": "Recompiling shaders"
207+
"info.canvas.recompile": "Recompiling shaders",
208+
"info.canvas.recompile_needs_reload": "Found a state change that requires reload during recompilation. Reloading renderer..."
208209
}

0 commit comments

Comments
 (0)