Fixed multiple major RAM issues. Next one is the 100/s reload issue...
This commit is contained in:
@@ -11,11 +11,13 @@ import com.seibel.lod.core.a7.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.a7.render.RenderBuffer;
|
||||
import com.seibel.lod.core.a7.save.io.render.RenderMetaFile;
|
||||
import com.seibel.lod.core.enums.ELodDirection;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.objects.LodDataView;
|
||||
import com.seibel.lod.core.a7.level.ILevel;
|
||||
import com.seibel.lod.core.a7.render.LodQuadTree;
|
||||
import com.seibel.lod.core.a7.render.LodRenderSection;
|
||||
import com.seibel.lod.core.a7.datatype.LodRenderSource;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@@ -27,6 +29,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static final boolean DO_SAFETY_CHECKS = true;
|
||||
public static final byte SECTION_SIZE_OFFSET = 6;
|
||||
public static final int SECTION_SIZE = 1 << SECTION_SIZE_OFFSET;
|
||||
@@ -253,7 +256,7 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
|
||||
|
||||
private void tryBuildBuffer(IClientLevel level, LodQuadTree quadTree) {
|
||||
if (inBuildRenderBuffer == null) {
|
||||
if (inBuildRenderBuffer == null && !ColumnRenderBuffer.isBusy()) {
|
||||
ColumnRenderSource[] data = new ColumnRenderSource[ELodDirection.ADJ_DIRECTIONS.length];
|
||||
for (ELodDirection direction : ELodDirection.ADJ_DIRECTIONS) {
|
||||
LodRenderSection section = quadTree.getSection(sectionPos.getAdjacent(direction)); //FIXME: Handle traveling through different detail levels
|
||||
@@ -266,6 +269,7 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
}
|
||||
private void cancelBuildBuffer() {
|
||||
if (inBuildRenderBuffer != null) {
|
||||
LOGGER.info("Cancelling build of render buffer for {}", sectionPos);
|
||||
inBuildRenderBuffer.cancel(true);
|
||||
inBuildRenderBuffer = null;
|
||||
}
|
||||
@@ -275,7 +279,7 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
@Override
|
||||
public void enableRender(IClientLevel level, LodQuadTree quadTree) {
|
||||
this.level = level;
|
||||
tryBuildBuffer(level, quadTree);
|
||||
//tryBuildBuffer(level, quadTree);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -285,7 +289,7 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
|
||||
@Override
|
||||
public boolean isRenderReady() {
|
||||
return (inBuildRenderBuffer != null && inBuildRenderBuffer.isDone());
|
||||
return inBuildRenderBuffer == null || inBuildRenderBuffer.isDone();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -293,15 +297,23 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
cancelBuildBuffer();
|
||||
}
|
||||
|
||||
//FIXME: Temp Hack
|
||||
private long lastNs = -1;
|
||||
private static final long SWAP_TIMEOUT = /* 10 sec */ 10_000_000_000L;
|
||||
|
||||
@Override
|
||||
public boolean trySwapRenderBuffer(LodQuadTree quadTree, AtomicReference<RenderBuffer> referenceSlot) {
|
||||
if (lastNs != -1 && System.nanoTime() - lastNs < SWAP_TIMEOUT) {
|
||||
return false;
|
||||
}
|
||||
if (inBuildRenderBuffer != null && inBuildRenderBuffer.isDone()) {
|
||||
lastNs = System.nanoTime();
|
||||
LOGGER.info("Swapping render buffer for {}", sectionPos);
|
||||
RenderBuffer oldBuffer = referenceSlot.getAndSet(inBuildRenderBuffer.join());
|
||||
if (oldBuffer instanceof ColumnRenderBuffer) usedBuffer = (ColumnRenderBuffer) oldBuffer;
|
||||
inBuildRenderBuffer = null;
|
||||
return true;
|
||||
} else {
|
||||
} else if (inBuildRenderBuffer == null && !ColumnRenderBuffer.isBusy()) {
|
||||
tryBuildBuffer(level, quadTree);
|
||||
}
|
||||
return false;
|
||||
|
||||
+17
-7
@@ -28,10 +28,8 @@ import org.lwjgl.opengl.GL32;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Iterator;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static com.seibel.lod.core.render.GLProxy.GL_LOGGER;
|
||||
|
||||
@@ -40,6 +38,7 @@ public class ColumnRenderBuffer extends RenderBuffer {
|
||||
//TODO: Make the pool use configurable number of threads
|
||||
public static final ExecutorService BUFFER_BUILDERS = LodUtil.makeThreadPool(4, "BufferBuilder");
|
||||
public static final ExecutorService BUFFER_UPLOADER = LodUtil.makeSingleThreadPool("ColumnBufferUploader");
|
||||
public static final int MAX_CONCURRENT_CALL = 8;
|
||||
|
||||
public static final ConfigBasedLogger EVENT_LOGGER = new ConfigBasedLogger(LogManager.getLogger(),
|
||||
() -> Config.Client.Advanced.Debugging.DebugSwitch.logRendererBufferEvent.get());
|
||||
@@ -180,9 +179,19 @@ public class ColumnRenderBuffer extends RenderBuffer {
|
||||
});
|
||||
}
|
||||
|
||||
private static long getCurrentJobsCount() {
|
||||
long jobs = ((ThreadPoolExecutor) BUFFER_BUILDERS).getQueue().stream().filter(t -> !((Future<?>) t).isDone()).count();
|
||||
jobs += ((ThreadPoolExecutor) BUFFER_UPLOADER).getQueue().stream().filter(t -> !((Future<?>) t).isDone()).count();
|
||||
return jobs;
|
||||
}
|
||||
|
||||
public static boolean isBusy() {
|
||||
return getCurrentJobsCount() > MAX_CONCURRENT_CALL;
|
||||
}
|
||||
|
||||
public static CompletableFuture<ColumnRenderBuffer> build(IClientLevel clientLevel, ColumnRenderBuffer usedBuffer, ColumnRenderSource data, ColumnRenderSource[] adjData) {
|
||||
EVENT_LOGGER.trace("RenderRegion startBuild @ {}", data.sectionPos);
|
||||
if (isBusy()) return null;
|
||||
LOGGER.info("RenderRegion startBuild @ {}", data.sectionPos);
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
try {
|
||||
EVENT_LOGGER.trace("RenderRegion start QuadBuild @ {}", data.sectionPos);
|
||||
@@ -201,7 +210,7 @@ public class ColumnRenderBuffer extends RenderBuffer {
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e3) {
|
||||
EVENT_LOGGER.error("\"LodNodeBufferBuilder\" was unable to build quads: ", e3);
|
||||
LOGGER.error("\"LodNodeBufferBuilder\" was unable to build quads: ", e3);
|
||||
throw e3;
|
||||
}
|
||||
}, BUFFER_BUILDERS)
|
||||
@@ -229,10 +238,11 @@ public class ColumnRenderBuffer extends RenderBuffer {
|
||||
} catch (InterruptedException e) {
|
||||
throw UncheckedInterruptedException.convert(e);
|
||||
} catch (Throwable e3) {
|
||||
EVENT_LOGGER.error("\"LodNodeBufferBuilder\" was unable to upload buffer: ", e3);
|
||||
LOGGER.error("\"LodNodeBufferBuilder\" was unable to upload buffer: ", e3);
|
||||
throw e3;
|
||||
}
|
||||
}, BUFFER_UPLOADER).handle((v, e) -> {
|
||||
LOGGER.info("RenderRegion endBuild @ {}", data.sectionPos);
|
||||
if (e != null) {
|
||||
usedBuffer.close();
|
||||
return null;
|
||||
|
||||
@@ -74,7 +74,7 @@ public class LodRenderSection {
|
||||
}
|
||||
|
||||
public boolean canRender() {
|
||||
return isLoaded() && lodRenderSource.isRenderReady();
|
||||
return isLoaded() && isRenderEnabled && lodRenderSource.isRenderReady();
|
||||
}
|
||||
|
||||
public boolean isLoaded() {
|
||||
|
||||
@@ -193,10 +193,12 @@ public class DataMetaFile extends MetaFile {
|
||||
if (e != null) {
|
||||
LOGGER.error("Uncaught error loading file {}: ", path, e);
|
||||
future.complete(null);
|
||||
data.set(null);
|
||||
} else {
|
||||
future.complete(f);
|
||||
new DataObjTracker(f);
|
||||
data.set(new SoftReference<>(f));
|
||||
}
|
||||
future.complete(f);
|
||||
new DataObjTracker(f);
|
||||
data.set(new SoftReference<>(f));
|
||||
});
|
||||
return future;
|
||||
}
|
||||
@@ -215,6 +217,7 @@ public class DataMetaFile extends MetaFile {
|
||||
for (ChunkSizedData chunk : _backQueue.queue) {
|
||||
data.update(chunk);
|
||||
}
|
||||
_backQueue.queue.clear();
|
||||
write(data);
|
||||
LOGGER.info("Updated Data file at {} for sect {} with {} chunk writes.", path, pos, count);
|
||||
} else localVer = localVersion.get();
|
||||
|
||||
@@ -145,7 +145,7 @@ public class LocalDataFileHandler implements IDataSourceProvider {
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<Void> flushAndSave() {
|
||||
ArrayList<CompletableFuture<Void>> futures = new ArrayList<CompletableFuture<Void>>();
|
||||
ArrayList<CompletableFuture<Void>> futures = new ArrayList<>();
|
||||
for (DataMetaFile metaFile : files.values()) {
|
||||
futures.add(metaFile.flushAndSave(fileReaderThread));
|
||||
}
|
||||
@@ -167,7 +167,6 @@ public class LocalDataFileHandler implements IDataSourceProvider {
|
||||
@Override
|
||||
public void close() {
|
||||
DataMetaFile.debugCheck();
|
||||
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,9 +134,11 @@ public class RenderMetaFile extends MetaFile {
|
||||
if (e != null) {
|
||||
LOGGER.error("Uncaught error loading file {}: ", path, e);
|
||||
future.complete(null);
|
||||
data.set(null);
|
||||
} else {
|
||||
future.complete(renderSource);
|
||||
data.set(new SoftReference<>(renderSource));
|
||||
}
|
||||
future.complete(renderSource);
|
||||
data.set(new SoftReference<>(renderSource));
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
@@ -433,7 +433,7 @@ public class LodUtil
|
||||
throw new AssertFailureException("Assert Not Reach failed:\n " + formatLog(message, args));
|
||||
}
|
||||
public static ExecutorService makeSingleThreadPool(String name, int relativePriority) {
|
||||
return Executors.newSingleThreadExecutor(new LodThreadFactory(name, Thread.NORM_PRIORITY+relativePriority));
|
||||
return Executors.newFixedThreadPool(1, new LodThreadFactory(name, Thread.NORM_PRIORITY+relativePriority));
|
||||
}
|
||||
public static ExecutorService makeSingleThreadPool(Class<?> clazz, int relativePriority) {
|
||||
return makeSingleThreadPool(clazz.getSimpleName(), relativePriority);
|
||||
|
||||
Reference in New Issue
Block a user