Fix VAOManager desync & Post-splash gap

This commit is contained in:
Algent committed 2026-08-13 17:23:08 +02:00
1 parent 48fcc4c943
commit 824473f093
2 files changed
+28 -11

No files matched your search

@@ -313,7 +313,7 @@ public class GLStateManager {
private static volatile boolean splashComplete = false;
@Getter @Setter private static Thread drawableGLHolder = MainThread;
// Reference to DrawableGL (main display context) - works with both FML and BLS splash
@Setter private static Drawable drawableGL = null;
@Setter private static volatile Drawable drawableGL = null;
private static final ReentrantLock DRAW_LOCK = new ReentrantLock();
@@ -3341,10 +3341,9 @@ public class GLStateManager {
}
CurrentThread = Thread.currentThread();
if (splashComplete) return;
if (drawableGL == null) {
// Lazy-capture DrawableGL reference (Display.getDrawable()) on first opportunity
// Lazy-capture DrawableGL reference (Display.getDrawable()) on first opportunity.
// markSplashComplete clears it, so this re-runs after the splash too.
try {
if (drawable == Display.getDrawable()) {
drawableGL = drawable;
@@ -3356,19 +3355,27 @@ public class GLStateManager {
}
}
if (drawableGL != null && drawable == drawableGL) {
final boolean isDrawableGL = drawableGL != null && drawable == drawableGL;
if (isDrawableGL) {
exitWorkerContext();
// Switching TO DrawableGL - enable caching for this thread
drawableGLHolder = CurrentThread;
} else {
enterWorkerContext();
if (drawableGLHolder == CurrentThread) {
}
if (!splashComplete) {
if (isDrawableGL) {
// 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;
}
}
if (CurrentThread != MainThread && !autoVaoBound.get()) {
// Worker contexts have no VAO of their own; core profile rejects draws without one.
// DrawableGL already carries defaultVAO once initialize() has run, but during the splash
// it may not have, so keep binding there too.
if (CurrentThread != MainThread && !autoVaoBound.get() && (!isDrawableGL || !splashComplete)) {
autoVaoBound.set(Boolean.TRUE);
glBindVertexArray(glGenVertexArrays());
}
@@ -6111,9 +6118,9 @@ public class GLStateManager {
}
final boolean locked = acquireDrawLock();
try {
VAOManager.onBindVertexArrayPre(array);
if (glCtx.boundVAO != array) {
glCtx.boundVAO = array;
VAOManager.onBindVertexArrayPre(array);
RENDER_BACKEND.bindVertexArray(array);
}
} finally {
@@ -19,6 +19,9 @@ public final class VAOManager {
static final Int2ObjectOpenHashMap<VAOData> eboOwners = new Int2ObjectOpenHashMap<>();
private static VAOData current = null;
// Which VAO name `current` reflects. Per-context boundVAO caching can skip a bind that is a
// no-op for that context but still a switch for this global tracker, so it needs its own id.
private static int currentVaoId = -1;
private static int currentVertexFlags = 0;
private static Attrib[] currentAttribs = null;
public static int boundEBO = 0;
@@ -29,6 +32,7 @@ public final class VAOManager {
public static void init(int defaultVAO) {
final VAOData data = new VAOData();
current = data;
currentVaoId = defaultVAO;
currentAttribs = data.attribs;
vaoMap.put(defaultVAO, data);
}
@@ -38,6 +42,9 @@ public final class VAOManager {
}
public static void onBindVertexArrayPre(int vaoId) {
if (vaoId == currentVaoId) return;
currentVaoId = vaoId;
// Save old VAO data
if (current != null) {
current.vertexFlags = currentVertexFlags;
@@ -66,7 +73,10 @@ public final class VAOManager {
final VAOData data = vaoMap.remove(vaoId);
if (data == null) return;
removeEboOwner(data.ebo, data);
if (data == current) current = null;
if (data == current) {
current = null;
currentVaoId = -1;
}
}
public static void onDeleteBuffer(int buffer) {