From 83540cf2d5553c8a7c893d8bc0379ac66f382c11 Mon Sep 17 00:00:00 2001 From: TomTheFurry Date: Thu, 26 May 2022 10:33:24 +0800 Subject: [PATCH] Clean up some stuff --- .../a7/UncheckedInterruptedException.java | 29 ++++++++++++++++ .../a7/datatype/column/ColumnDatatype.java | 6 ++-- .../datatype/column/ColumnRenderBuffer.java | 33 +++++++++++-------- 3 files changed, 52 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/seibel/lod/core/objects/a7/UncheckedInterruptedException.java diff --git a/src/main/java/com/seibel/lod/core/objects/a7/UncheckedInterruptedException.java b/src/main/java/com/seibel/lod/core/objects/a7/UncheckedInterruptedException.java new file mode 100644 index 000000000..a00e89b02 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/objects/a7/UncheckedInterruptedException.java @@ -0,0 +1,29 @@ +package com.seibel.lod.core.objects.a7; + +public class UncheckedInterruptedException extends RuntimeException { + public UncheckedInterruptedException(String message) { + super(message); + } + public UncheckedInterruptedException(Throwable cause) { + super(cause); + } + public UncheckedInterruptedException(String message, Throwable cause) { + super(message, cause); + } + public UncheckedInterruptedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + public UncheckedInterruptedException() { + super(); + } + + public static void throwIfInterrupted() { + if (Thread.currentThread().isInterrupted()) { + throw new UncheckedInterruptedException(); + } + } + + public static UncheckedInterruptedException convert(InterruptedException e) { + return new UncheckedInterruptedException(e); + } +} diff --git a/src/main/java/com/seibel/lod/core/objects/a7/datatype/column/ColumnDatatype.java b/src/main/java/com/seibel/lod/core/objects/a7/datatype/column/ColumnDatatype.java index adf2b807d..1557ffd01 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/datatype/column/ColumnDatatype.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/datatype/column/ColumnDatatype.java @@ -258,6 +258,7 @@ public class ColumnDatatype implements RenderDataSource, IColumnDatatype { } private CompletableFuture inBuildRenderBuffer = null; + private ColumnRenderBuffer usedBuffer = null; private void tryBuildBuffer(LodQuadTree quadTree) { @@ -269,7 +270,7 @@ public class ColumnDatatype implements RenderDataSource, IColumnDatatype { data[direction.ordinal()-2] = ((ColumnDatatype) section.getRenderContainer()); } } - inBuildRenderBuffer = ColumnRenderBuffer.build( this, data); + inBuildRenderBuffer = ColumnRenderBuffer.build(usedBuffer, this, data); } } private void cancelBuildBuffer() { @@ -302,7 +303,8 @@ public class ColumnDatatype implements RenderDataSource, IColumnDatatype { @Override public boolean trySwapRenderBuffer(LodQuadTree quadTree, AtomicReference referenceSlot) { if (inBuildRenderBuffer != null && inBuildRenderBuffer.isDone()) { - referenceSlot.set(inBuildRenderBuffer.join()); + RenderBuffer oldBuffer = referenceSlot.getAndSet(inBuildRenderBuffer.join()); + if (oldBuffer != null && oldBuffer instanceof ColumnRenderBuffer) usedBuffer = (ColumnRenderBuffer) oldBuffer; inBuildRenderBuffer = null; return true; } else { diff --git a/src/main/java/com/seibel/lod/core/objects/a7/datatype/column/ColumnRenderBuffer.java b/src/main/java/com/seibel/lod/core/objects/a7/datatype/column/ColumnRenderBuffer.java index 4650c9baa..0d44dc7c1 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/datatype/column/ColumnRenderBuffer.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/datatype/column/ColumnRenderBuffer.java @@ -12,6 +12,7 @@ import com.seibel.lod.core.enums.rendering.DebugMode; import com.seibel.lod.core.enums.rendering.GLProxyContext; import com.seibel.lod.core.logging.ConfigBasedLogger; import com.seibel.lod.core.logging.DhLoggerBuilder; +import com.seibel.lod.core.objects.a7.UncheckedInterruptedException; import com.seibel.lod.core.objects.a7.render.RenderBuffer; import com.seibel.lod.core.render.GLProxy; import com.seibel.lod.core.render.LodRenderProgram; @@ -31,7 +32,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import static com.seibel.lod.core.render.GLProxy.GL_LOGGER; -import static com.seibel.lod.core.render.LodRenderer.EVENT_LOGGER; public class ColumnRenderBuffer extends RenderBuffer { @@ -127,13 +127,12 @@ public class ColumnRenderBuffer extends RenderBuffer { } } - public boolean uploadBuffer(LodQuadBuilder builder, GpuUploadMethod method) throws InterruptedException { + public void uploadBuffer(LodQuadBuilder builder, GpuUploadMethod method) throws InterruptedException { if (method.useEarlyMapping) { _uploadBuffersMapped(builder, method); } else { _uploadBuffersDirect(builder, method); } - return true; } @Override @@ -181,7 +180,7 @@ public class ColumnRenderBuffer extends RenderBuffer { } - public static CompletableFuture build(ColumnDatatype data, ColumnDatatype[] adjData) { + public static CompletableFuture build(ColumnRenderBuffer usedBuffer, ColumnDatatype data, ColumnDatatype[] adjData) { EVENT_LOGGER.trace("RenderRegion startBuild @ {}", data.sectionPos); return CompletableFuture.supplyAsync(() -> { try { @@ -190,13 +189,13 @@ public class ColumnRenderBuffer extends RenderBuffer { // FIXME: Clamp also to the max world height. skyLightCullingBelow = Math.max(skyLightCullingBelow, LodBuilder.MIN_WORLD_HEIGHT); LodQuadBuilder builder = new LodQuadBuilder(true, skyLightCullingBelow); - Runnable buildRun = ()->{ - makeLodRenderData(builder, data, adjData); - }; - buildRun.run(); + makeLodRenderData(builder, data, adjData); EVENT_LOGGER.trace("RenderRegion end QuadBuild @ {}", data.sectionPos); return builder; - } catch (Throwable e3) { + } catch (UncheckedInterruptedException e) { + throw e; + } + catch (Throwable e3) { EVENT_LOGGER.error("\"LodNodeBufferBuilder\" was unable to build quads: ", e3); throw e3; } @@ -208,22 +207,26 @@ public class ColumnRenderBuffer extends RenderBuffer { GpuUploadMethod method = GLProxy.getInstance().getGpuUploadMethod(); GLProxyContext oldContext = glProxy.getGlContext(); glProxy.setGlContext(GLProxyContext.LOD_BUILDER); - ColumnRenderBuffer buffer = new ColumnRenderBuffer(); + ColumnRenderBuffer buffer = usedBuffer!=null ? usedBuffer : new ColumnRenderBuffer(); try { buffer.uploadBuffer(builder, method); + EVENT_LOGGER.trace("RenderRegion end Upload @ {}", data.sectionPos); + return buffer; + } catch (Exception e) { + buffer.close(); + throw e; } finally { - glProxy.setGlContext(oldContext); //FIXME: Close buffer on exception? + glProxy.setGlContext(oldContext); } - EVENT_LOGGER.trace("RenderRegion end Upload @ {}", data.sectionPos); - return buffer; } catch (InterruptedException e) { - throw new RuntimeException(e); + throw UncheckedInterruptedException.convert(e); } catch (Throwable e3) { EVENT_LOGGER.error("\"LodNodeBufferBuilder\" was unable to upload buffer: ", e3); throw e3; } }, BUFFER_UPLOADER).handle((v, e) -> { if (e != null) { + usedBuffer.close(); return null; } else { return v; @@ -242,6 +245,8 @@ public class ColumnRenderBuffer extends RenderBuffer { int dataSize = 1 << detailLevel; for (int x = 0; x < dataSize; x++) { for (int z = 0; z < dataSize; z++) { + UncheckedInterruptedException.throwIfInterrupted(); + ColumnArrayView posData = region.getVerticalDataView(x, z); if (posData.size() == 0 || !DataPointUtil.doesItExist(posData.get(0)) || DataPointUtil.isVoid(posData.get(0)))