From b0570414679c5ffb0c3b26f3063f6cb31d10ef64 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Thu, 23 Apr 2026 07:16:31 -0500 Subject: [PATCH] Add more locking and volatile buffer ID checks --- .../openGl/glObject/buffer/GLBuffer.java | 56 ++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/common/src/main/java/com/seibel/distanthorizons/common/render/openGl/glObject/buffer/GLBuffer.java b/common/src/main/java/com/seibel/distanthorizons/common/render/openGl/glObject/buffer/GLBuffer.java index 4ba33cfce..d74fe3e73 100644 --- a/common/src/main/java/com/seibel/distanthorizons/common/render/openGl/glObject/buffer/GLBuffer.java +++ b/common/src/main/java/com/seibel/distanthorizons/common/render/openGl/glObject/buffer/GLBuffer.java @@ -62,7 +62,7 @@ public class GLBuffer implements AutoCloseable private static final ThreadPoolExecutor CLEANUP_THREAD = ThreadUtil.makeSingleDaemonThreadPool("GLBuffer Cleanup"); - protected int id = 0; + protected volatile int id = 0; public final int getId() { return this.id; } protected int size = 0; public int getSize() { return this.size; } @@ -123,26 +123,35 @@ public class GLBuffer implements AutoCloseable } - int oldId = this.id; - this.id = GLMC.glGenBuffers(); - - // destroy the old buffer - // after the new one has been created - // to hopefully prevent a rare race conditions where the old ID - // is still used somewhere - if (oldId != 0) + // lock to prevent the render thread from accessing the buffer's ID + // while we are removing it + long writeStamp = renderStampLock.writeLock(); + try { - destroyBufferIdNow(oldId); + int oldId = this.id; + this.id = GLMC.glGenBuffers(); + + // destroy the old buffer + // after the new one has been created + // to hopefully prevent a rare race conditions where the old ID + // is still used somewhere + if (oldId != 0) + { + destroyBufferIdNow(oldId); + } + + + this.bufferStorage = asBufferStorage; + bufferCount.getAndIncrement(); + + PhantomReference phantom = new PhantomReference<>(this, PHANTOM_REFERENCE_QUEUE); + PHANTOM_TO_BUFFER_ID.put(phantom, this.id); + BUFFER_ID_TO_PHANTOM.put(this.id, phantom); + } + finally + { + renderStampLock.unlock(writeStamp); } - - - this.bufferStorage = asBufferStorage; - bufferCount.getAndIncrement(); - - PhantomReference phantom = new PhantomReference<>(this, PHANTOM_REFERENCE_QUEUE); - PHANTOM_TO_BUFFER_ID.put(phantom, this.id); - BUFFER_ID_TO_PHANTOM.put(this.id, phantom); - } protected void destroyAsync() @@ -154,13 +163,11 @@ public class GLBuffer implements AutoCloseable } - long writeStamp = 0; + // lock to prevent the render thread from accessing the buffer's ID + // while we are removing it + long writeStamp = renderStampLock.writeLock(); try { - // lock to prevent the render thread from accessing the buffer's ID - // while we are removing it - writeStamp = renderStampLock.writeLock(); - final int idToDelete = this.id; // saving the ID to a separate variable is necessary so it can be captured by the lambda // mark the old data is invalid before deleting to prevent a rare race condition @@ -354,7 +361,6 @@ public class GLBuffer implements AutoCloseable { // recreate if the buffer storage type changed this.bind(); - destroyBufferIdNow(this.id); this.destroyOldAndCreate(uploadMethod.useBufferStorage); this.bind(); }