From bbd6f2ea89baa5ed0546f3b2278425b2d078c947 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Fri, 8 Nov 2024 07:39:58 -0600 Subject: [PATCH] Move some buffer building logic off the render thread --- .../bufferBuilding/ColumnRenderBuffer.java | 70 ++++++++----------- .../ColumnRenderBufferBuilder.java | 2 +- 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBuffer.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBuffer.java index cc44a96fd..b3d0dde3f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBuffer.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBuffer.java @@ -89,24 +89,48 @@ public class ColumnRenderBuffer implements AutoCloseable //==================// /** Should be run on a DH thread. */ - public void uploadBuffer(LodQuadBuilder builder, EDhApiGpuUploadMethod gpuUploadMethod) throws InterruptedException + public void makeAndUploadBuffers(LodQuadBuilder builder, EDhApiGpuUploadMethod gpuUploadMethod) throws InterruptedException { LodUtil.assertTrue(DhApi.isDhThread(), "Buffer uploading needs to be done on a DH thread to prevent locking up any MC threads."); + // make the buffers + ArrayList opaqueBuffers = builder.makeOpaqueVertexBuffers(); + ArrayList transparentBuffers = builder.makeTransparentVertexBuffers(); + + vbos = resizeBuffer(vbos, opaqueBuffers.size()); + vbosTransparent = resizeBuffer(vbosTransparent, transparentBuffers.size()); + + // upload on MC's render thread CompletableFuture uploadFuture = new CompletableFuture<>(); - MC_CLIENT.executeOnRenderThread(() -> + GLProxy.getInstance().queueRunningOnRenderThread(() -> { try { - this.uploadBuffers(builder, gpuUploadMethod); + uploadBuffersDirect(vbos, opaqueBuffers, gpuUploadMethod); + uploadBuffersDirect(vbosTransparent, transparentBuffers, gpuUploadMethod); + this.buffersUploaded = true; uploadFuture.complete(null); } catch (InterruptedException e) { throw new CompletionException(e); } + finally + { + // all the buffers must be manually freed to prevent memory leaks + + for (ByteBuffer buffer : opaqueBuffers) + { + MemoryUtil.memFree(buffer); + } + + for (ByteBuffer buffer : transparentBuffers) + { + MemoryUtil.memFree(buffer); + } + } }); @@ -126,43 +150,7 @@ public class ColumnRenderBuffer implements AutoCloseable //LOGGER.warn("Error uploading builder ["+builder+"] synchronously. Error: "+e.getMessage(), e); } } - private void uploadBuffers(LodQuadBuilder builder, EDhApiGpuUploadMethod method) throws InterruptedException - { - // uploading mapped buffers used to be done here, - // however due to a memory leak and complication with the previous code, - // now we only allow direct uploading. - // (There's also insufficient data to state whether mapped buffers are necessary - // for DH to upload without stuttering the main thread) - - this.vbos = makeAndUploadBuffers(builder, method, this.vbos, builder.makeOpaqueVertexBuffers()); - this.vbosTransparent = makeAndUploadBuffers(builder, method, this.vbosTransparent, builder.makeTransparentVertexBuffers()); - - this.buffersUploaded = true; - } - /** This resizes and returns the vbo array if necessary based on the amount of data needed for this area. */ - private static GLVertexBuffer[] makeAndUploadBuffers(LodQuadBuilder builder, EDhApiGpuUploadMethod method, GLVertexBuffer[] vbos, ArrayList buffers) throws InterruptedException - { - try - { - vbos = resizeBuffer(vbos, buffers.size()); - uploadBuffersDirect(vbos, buffers, method); - } - finally - { - // all the buffers must be manually freed to prevent memory leaks - if (buffers != null) - { - for (ByteBuffer buffer : buffers) - { - MemoryUtil.memFree(buffer); - } - } - } - - // return the array in case it was resized - return vbos; - } - public static GLVertexBuffer[] resizeBuffer(GLVertexBuffer[] vbos, int newSize) + private static GLVertexBuffer[] resizeBuffer(GLVertexBuffer[] vbos, int newSize) { if (vbos.length == newSize) { @@ -228,8 +216,6 @@ public class ColumnRenderBuffer implements AutoCloseable - - //========// // render // //========// diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java index 61fb96081..e4a661c26 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/bufferBuilding/ColumnRenderBufferBuilder.java @@ -135,7 +135,7 @@ public class ColumnRenderBufferBuilder ColumnRenderBuffer buffer = new ColumnRenderBuffer(new DhBlockPos(DhSectionPos.getMinCornerBlockX(pos), clientLevel.getMinY(), DhSectionPos.getMinCornerBlockZ(pos))); try { - buffer.uploadBuffer(quadBuilder, GLProxy.getInstance().getGpuUploadMethod()); + buffer.makeAndUploadBuffers(quadBuilder, GLProxy.getInstance().getGpuUploadMethod()); if (buffer.buffersUploaded) { return buffer;