Fix state leak

This commit is contained in:
Algent committed 2026-08-13 11:33:02 +02:00
1 parent b17bb42c49
commit 48fcc4c943
2 files changed
+52 -10

No files matched your search

@@ -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;
}
@@ -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).
*/