diff --git a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java index 23328a0c0..05b5d58f7 100644 --- a/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java +++ b/glsm/src/main/java/com/gtnewhorizons/angelica/glsm/GLStateManager.java @@ -169,6 +169,9 @@ public class GLStateManager { } static GLContextState enterWorkerContext() { + final GLContextState existing = tlWorkerContext.get(); + if (existing != null) return existing; + final GLContextState st = new GLContextState(); tlWorkerContext.set(st); synchronized (GLStateManager.class) { @@ -3338,11 +3341,6 @@ public class GLStateManager { } CurrentThread = Thread.currentThread(); - if (!splashComplete && CurrentThread != MainThread && !autoVaoBound.get()) { - autoVaoBound.set(Boolean.TRUE); - glBindVertexArray(glGenVertexArrays()); - } - if (splashComplete) return; if (drawableGL == null) { @@ -3359,13 +3357,21 @@ public class GLStateManager { } if (drawableGL != null && drawable == drawableGL) { + exitWorkerContext(); // Switching TO DrawableGL - enable caching for this thread drawableGLHolder = CurrentThread; - } else if (drawableGLHolder == CurrentThread) { - // This thread held DrawableGL but is switching AWAY - disable caching - drawableGLHolder = null; + } else { + enterWorkerContext(); + if (drawableGLHolder == CurrentThread) { + // This thread held DrawableGL but is switching AWAY - disable caching + drawableGLHolder = null; + } + } + + if (CurrentThread != MainThread && !autoVaoBound.get()) { + autoVaoBound.set(Boolean.TRUE); + glBindVertexArray(glGenVertexArrays()); } - // else: Thread switching to non-DrawableGL, wasn't holder - no change needed } public static void releaseContext(Drawable drawable) throws LWJGLException { @@ -3373,6 +3379,7 @@ public class GLStateManager { if (!handled) { drawable.releaseContext(); } + exitWorkerContext(); if (drawableGLHolder == Thread.currentThread()) { drawableGLHolder = null; } diff --git a/glsm/src/test/java/com/gtnewhorizons/angelica/glsm/GLSM_ServerSideState_UnitTest.java b/glsm/src/test/java/com/gtnewhorizons/angelica/glsm/GLSM_ServerSideState_UnitTest.java index ba1894f46..1a903de0e 100644 --- a/glsm/src/test/java/com/gtnewhorizons/angelica/glsm/GLSM_ServerSideState_UnitTest.java +++ b/glsm/src/test/java/com/gtnewhorizons/angelica/glsm/GLSM_ServerSideState_UnitTest.java @@ -106,7 +106,7 @@ public class GLSM_ServerSideState_UnitTest { backgroundError = e; } finally { try { - sharedDrawable.releaseContext(); + GLStateManager.releaseContext(sharedDrawable); } catch (LWJGLException e) { // Ignore on cleanup } @@ -342,6 +342,41 @@ public class GLSM_ServerSideState_UnitTest { } } + @Test + void testDepthStateDoesNotBleedFromSharedDrawable() throws InterruptedException { + final boolean originalDepthTest = GLStateManager.getDepthTest().isEnabled(); + final int originalDepthFunc = GLStateManager.getDepthState().getFunc(); + final boolean originalDepthMask = GLStateManager.getDepthState().isEnabled(); + + try { + GLStateManager.enableDepthTest(); + GLStateManager.glDepthFunc(GL11.GL_LEQUAL); + GLStateManager.glDepthMask(true); + + executeOnSharedDrawable(() -> { + GLStateManager.disableDepthTest(); + GLStateManager.glDepthFunc(GL11.GL_ALWAYS); + GLStateManager.glDepthMask(false); + + assertFalse(GLStateManager.getDepthTest().isEnabled()); + assertEquals(GL11.GL_ALWAYS, GLStateManager.getDepthState().getFunc()); + assertFalse(GLStateManager.getDepthState().isEnabled()); + }); + + assertTrue(GLStateManager.getDepthTest().isEnabled(), "SharedDrawable depth test leaked into the main cache"); + assertEquals(GL11.GL_LEQUAL, GLStateManager.getDepthState().getFunc(), "SharedDrawable depth func leaked into the main cache"); + assertTrue(GLStateManager.getDepthState().isEnabled(), "SharedDrawable depth mask leaked into the main cache"); + } finally { + if (originalDepthTest) { + GLStateManager.enableDepthTest(); + } else { + GLStateManager.disableDepthTest(); + } + GLStateManager.glDepthFunc(originalDepthFunc); + GLStateManager.glDepthMask(originalDepthMask); + } + } + /** * Test glTexParameterf (float parameters like LOD_BIAS). */