Continues work
This commit is contained in:
@@ -88,7 +88,7 @@ public class ModelBakerySubsystem {
|
|||||||
do {
|
do {
|
||||||
this.factory.addEntry(i);
|
this.factory.addEntry(i);
|
||||||
j++;
|
j++;
|
||||||
if (budget<(System.nanoTime() - start)+1000)
|
if (25<j)//budget<(System.nanoTime() - start)+1000
|
||||||
break;
|
break;
|
||||||
i = this.blockIdQueue.poll();
|
i = this.blockIdQueue.poll();
|
||||||
} while (i != null);
|
} while (i != null);
|
||||||
|
|||||||
@@ -56,13 +56,15 @@ public class ChunkBoundRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addSection(long pos) {
|
public void addSection(long pos) {
|
||||||
|
if (!this.remQueue.remove(pos)) {
|
||||||
this.addQueue.add(pos);
|
this.addQueue.add(pos);
|
||||||
this.remQueue.remove(pos);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeSection(long pos) {
|
public void removeSection(long pos) {
|
||||||
|
if (!this.addQueue.remove(pos)) {
|
||||||
this.remQueue.add(pos);
|
this.remQueue.add(pos);
|
||||||
this.addQueue.remove(pos);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Bind and render, changing as little gl state as possible so that the caller may configure how it wants to render
|
//Bind and render, changing as little gl state as possible so that the caller may configure how it wants to render
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
DownloadStream.INSTANCE.tick();
|
DownloadStream.INSTANCE.tick();
|
||||||
|
|
||||||
this.nodeManager.tick(this.traversal.getNodeBuffer());
|
this.nodeManager.tick(this.traversal.getNodeBuffer());
|
||||||
|
//glFlush();
|
||||||
|
|
||||||
this.nodeCleaner.tick(this.traversal.getNodeBuffer());//Probably do this here??
|
this.nodeCleaner.tick(this.traversal.getNodeBuffer());//Probably do this here??
|
||||||
|
|
||||||
@@ -184,6 +185,8 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
this.world.getMapper().setBiomeCallback(null);
|
this.world.getMapper().setBiomeCallback(null);
|
||||||
this.world.getMapper().setStateCallback(null);
|
this.world.getMapper().setStateCallback(null);
|
||||||
|
|
||||||
|
this.nodeManager.stop();
|
||||||
|
|
||||||
this.modelService.shutdown();
|
this.modelService.shutdown();
|
||||||
this.renderGen.shutdown();
|
this.renderGen.shutdown();
|
||||||
this.viewportSelector.free();
|
this.viewportSelector.free();
|
||||||
@@ -191,8 +194,6 @@ public class RenderService<T extends AbstractSectionRenderer<J, Q>, J extends Vi
|
|||||||
this.traversal.free();
|
this.traversal.free();
|
||||||
this.nodeCleaner.free();
|
this.nodeCleaner.free();
|
||||||
|
|
||||||
this.nodeManager.stop();
|
|
||||||
|
|
||||||
this.geometryData.free();
|
this.geometryData.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -266,6 +266,9 @@ public class RenderGenerationService {
|
|||||||
|
|
||||||
|
|
||||||
public void enqueueTask(long pos) {
|
public void enqueueTask(long pos) {
|
||||||
|
if (!this.threads.isAlive()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
boolean[] isOurs = new boolean[1];
|
boolean[] isOurs = new boolean[1];
|
||||||
long stamp = this.taskMapLock.writeLock();
|
long stamp = this.taskMapLock.writeLock();
|
||||||
BuildTask task = this.taskMap.computeIfAbsent(pos, p->{
|
BuildTask task = this.taskMap.computeIfAbsent(pos, p->{
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import it.unimi.dsi.fastutil.ints.IntConsumer;
|
import it.unimi.dsi.fastutil.ints.IntConsumer;
|
||||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.longs.LongConsumer;
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
import it.unimi.dsi.fastutil.longs.LongOpenHashSet;
|
||||||
import me.cortex.voxy.client.core.gl.GlBuffer;
|
import me.cortex.voxy.client.core.gl.GlBuffer;
|
||||||
import me.cortex.voxy.client.core.rendering.ISectionWatcher;
|
import me.cortex.voxy.client.core.rendering.ISectionWatcher;
|
||||||
@@ -13,6 +12,7 @@ import me.cortex.voxy.client.core.rendering.section.geometry.BasicAsyncGeometryM
|
|||||||
import me.cortex.voxy.client.core.rendering.section.geometry.BasicSectionGeometryData;
|
import me.cortex.voxy.client.core.rendering.section.geometry.BasicSectionGeometryData;
|
||||||
import me.cortex.voxy.client.core.rendering.section.geometry.IGeometryData;
|
import me.cortex.voxy.client.core.rendering.section.geometry.IGeometryData;
|
||||||
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||||
|
import me.cortex.voxy.common.Logger;
|
||||||
import me.cortex.voxy.common.util.MemoryBuffer;
|
import me.cortex.voxy.common.util.MemoryBuffer;
|
||||||
import me.cortex.voxy.common.world.WorldSection;
|
import me.cortex.voxy.common.world.WorldSection;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
@@ -30,16 +30,19 @@ import static me.cortex.voxy.client.core.rendering.section.geometry.BasicSection
|
|||||||
// this is done off thread to reduce the amount of work done on the render thread, improving frame stability and reducing runtime overhead
|
// this is done off thread to reduce the amount of work done on the render thread, improving frame stability and reducing runtime overhead
|
||||||
public class AsyncNodeManager {
|
public class AsyncNodeManager {
|
||||||
private static final VarHandle RESULT_HANDLE;
|
private static final VarHandle RESULT_HANDLE;
|
||||||
|
private static final VarHandle RESULT_CACHE_1_HANDLE;
|
||||||
|
private static final VarHandle RESULT_CACHE_2_HANDLE;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
RESULT_HANDLE = MethodHandles.lookup().findVarHandle(AsyncNodeManager.class, "results", SyncResults.class);
|
RESULT_HANDLE = MethodHandles.lookup().findVarHandle(AsyncNodeManager.class, "results", SyncResults.class);
|
||||||
|
RESULT_CACHE_1_HANDLE = MethodHandles.lookup().findVarHandle(AsyncNodeManager.class, "resultCache1", SyncResults.class);
|
||||||
|
RESULT_CACHE_2_HANDLE = MethodHandles.lookup().findVarHandle(AsyncNodeManager.class, "resultCache2", SyncResults.class);
|
||||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Thread thread;
|
private final Thread thread;
|
||||||
private final StampedLock lock = new StampedLock();
|
|
||||||
public final int maxNodeCount;
|
public final int maxNodeCount;
|
||||||
private volatile boolean running = true;
|
private volatile boolean running = true;
|
||||||
|
|
||||||
@@ -50,10 +53,14 @@ public class AsyncNodeManager {
|
|||||||
private final AtomicInteger workCounter = new AtomicInteger();
|
private final AtomicInteger workCounter = new AtomicInteger();
|
||||||
|
|
||||||
private volatile SyncResults results = null;
|
private volatile SyncResults results = null;
|
||||||
|
private volatile SyncResults resultCache1 = new SyncResults();
|
||||||
|
private volatile SyncResults resultCache2 = new SyncResults();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//locals for during iteration
|
//locals for during iteration
|
||||||
private final IntOpenHashSet tlnIdChange = new IntOpenHashSet();//"Encoded" add/remove id, first bit indicates if its add or remove, 1 is add
|
private final IntOpenHashSet tlnIdChange = new IntOpenHashSet();//"Encoded" add/remove id, first bit indicates if its add or remove, 1 is add
|
||||||
|
private boolean needsWaitForSync = false;
|
||||||
|
|
||||||
public AsyncNodeManager(int maxNodeCount, ISectionWatcher watcher, IGeometryData geometryData) {
|
public AsyncNodeManager(int maxNodeCount, ISectionWatcher watcher, IGeometryData geometryData) {
|
||||||
//Note the current implmentation of ISectionWatcher is threadsafe
|
//Note the current implmentation of ISectionWatcher is threadsafe
|
||||||
@@ -64,10 +71,13 @@ public class AsyncNodeManager {
|
|||||||
|
|
||||||
this.maxNodeCount = maxNodeCount;
|
this.maxNodeCount = maxNodeCount;
|
||||||
this.thread = new Thread(()->{
|
this.thread = new Thread(()->{
|
||||||
|
try {
|
||||||
while (this.running) {
|
while (this.running) {
|
||||||
this.run();
|
this.run();
|
||||||
}
|
}
|
||||||
//TODO: cleanup here? maybe?
|
} catch (Exception e) {
|
||||||
|
Logger.error("Critical error occurred in async processor, things will be broken", e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.thread.setName("Async Node Manager");
|
this.thread.setName("Async Node Manager");
|
||||||
|
|
||||||
@@ -91,15 +101,32 @@ public class AsyncNodeManager {
|
|||||||
});
|
});
|
||||||
this.manager.setTLNCallbacks(id->{
|
this.manager.setTLNCallbacks(id->{
|
||||||
if (!this.tlnIdChange.remove(id)) {
|
if (!this.tlnIdChange.remove(id)) {
|
||||||
this.tlnIdChange.add(id|(1<<31));
|
if (!this.tlnIdChange.add(id|(1<<31))) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, id -> {
|
}, id -> {
|
||||||
if (!this.tlnIdChange.remove(id|(1<<31))) {
|
if (!this.tlnIdChange.remove(id|(1<<31))) {
|
||||||
this.tlnIdChange.add(id);
|
if (!this.tlnIdChange.add(id)) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SyncResults getMakeResultObject() {
|
||||||
|
SyncResults resultSet = (SyncResults)RESULT_CACHE_1_HANDLE.getAndSet(this, null);
|
||||||
|
if (resultSet == null) {//Not in the first object
|
||||||
|
resultSet = (SyncResults)RESULT_CACHE_2_HANDLE.getAndSet(this, null);
|
||||||
|
}
|
||||||
|
if (resultSet == null) {
|
||||||
|
throw new IllegalStateException("There should always be an object in the result set cache pair");
|
||||||
|
}
|
||||||
|
//Reset everything to default
|
||||||
|
resultSet.reset();
|
||||||
|
return resultSet;
|
||||||
|
}
|
||||||
|
|
||||||
private void run() {
|
private void run() {
|
||||||
if (this.workCounter.get() == 0) {
|
if (this.workCounter.get() == 0) {
|
||||||
LockSupport.park();
|
LockSupport.park();
|
||||||
@@ -114,7 +141,7 @@ public class AsyncNodeManager {
|
|||||||
|
|
||||||
//This is a funny thing, wait a bit, this allows for better batching, but this thread is independent of everything else so waiting a bit should be mostly ok
|
//This is a funny thing, wait a bit, this allows for better batching, but this thread is independent of everything else so waiting a bit should be mostly ok
|
||||||
try {
|
try {
|
||||||
Thread.sleep(20);
|
Thread.sleep(10);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
@@ -165,7 +192,7 @@ public class AsyncNodeManager {
|
|||||||
job.release();
|
job.release();
|
||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
for (int limit = 0; limit < 100; limit++) {//Limit uploading
|
for (int limit = 0; limit < 200; limit++) {//Limit uploading
|
||||||
var job = this.geometryUpdateQueue.poll();
|
var job = this.geometryUpdateQueue.poll();
|
||||||
if (job == null)
|
if (job == null)
|
||||||
break;
|
break;
|
||||||
@@ -214,9 +241,20 @@ public class AsyncNodeManager {
|
|||||||
} while (true);
|
} while (true);
|
||||||
|
|
||||||
if (this.workCounter.addAndGet(-workDone) < 0) {
|
if (this.workCounter.addAndGet(-workDone) < 0) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(1);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
//Due to synchronization "issues", wait a millis (give up this time slice)
|
||||||
|
if (this.workCounter.get() < 0) {
|
||||||
throw new IllegalStateException("Work counter less than zero");
|
throw new IllegalStateException("Work counter less than zero");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (workDone == 0) {//Nothing happened, which is odd, but just return
|
||||||
|
return;
|
||||||
|
}
|
||||||
//=====================
|
//=====================
|
||||||
//process output events and atomically sync to results
|
//process output events and atomically sync to results
|
||||||
|
|
||||||
@@ -259,7 +297,7 @@ public class AsyncNodeManager {
|
|||||||
|
|
||||||
//TODO: also note! this can be done for the processing of rendered out block models!!
|
//TODO: also note! this can be done for the processing of rendered out block models!!
|
||||||
// (it might be able to also be put in this thread, maybe? but is proabably worth putting in own thread for latency reasons)
|
// (it might be able to also be put in this thread, maybe? but is proabably worth putting in own thread for latency reasons)
|
||||||
|
if (this.needsWaitForSync) {
|
||||||
while (RESULT_HANDLE.get(this) != null && this.running) {
|
while (RESULT_HANDLE.get(this) != null && this.running) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
@@ -267,12 +305,14 @@ public class AsyncNodeManager {
|
|||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var prev = (SyncResults) RESULT_HANDLE.getAndSet(this, null);
|
var prev = (SyncResults) RESULT_HANDLE.getAndSet(this, null);
|
||||||
SyncResults results = null;
|
SyncResults results = null;
|
||||||
if (prev == null) {
|
if (prev == null) {
|
||||||
results = new SyncResults();
|
this.needsWaitForSync = false;
|
||||||
|
results = this.getMakeResultObject();
|
||||||
//Clear old data (if it exists), create a new result set
|
//Clear old data (if it exists), create a new result set
|
||||||
results.tlnDelta.addAll(this.tlnIdChange);
|
results.tlnDelta.addAll(this.tlnIdChange);
|
||||||
this.tlnIdChange.clear();
|
this.tlnIdChange.clear();
|
||||||
@@ -288,8 +328,9 @@ public class AsyncNodeManager {
|
|||||||
var iter = this.tlnIdChange.intIterator();
|
var iter = this.tlnIdChange.intIterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
int val = iter.nextInt();
|
int val = iter.nextInt();
|
||||||
results.tlnDelta.remove(val ^ (1 << 31));//Remove opposite
|
if (!results.tlnDelta.remove(val ^ (1 << 31))) {//Remove opposite
|
||||||
results.tlnDelta.add(val);//Add this
|
results.tlnDelta.add(val);//Add this if not added
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.tlnIdChange.clear();
|
this.tlnIdChange.clear();
|
||||||
}
|
}
|
||||||
@@ -336,6 +377,7 @@ public class AsyncNodeManager {
|
|||||||
this.geometryManager.writeMetadata(val, placeId*32L + results.geometryIdUpdateData.address);
|
this.geometryManager.writeMetadata(val, placeId*32L + results.geometryIdUpdateData.address);
|
||||||
}
|
}
|
||||||
ids.clear();
|
ids.clear();
|
||||||
|
this.needsWaitForSync |= results.geometryIdUpdateMap.size()>250;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Node updates
|
//Node updates
|
||||||
@@ -353,6 +395,7 @@ public class AsyncNodeManager {
|
|||||||
this.manager.writeNode(val, placeId*16L + results.nodeIdUpdateData.address);
|
this.manager.writeNode(val, placeId*16L + results.nodeIdUpdateData.address);
|
||||||
}
|
}
|
||||||
ids.clear();
|
ids.clear();
|
||||||
|
this.needsWaitForSync |= results.nodeIdUpdateMap.size()>=512;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,8 +473,14 @@ public class AsyncNodeManager {
|
|||||||
if (doCommit) {
|
if (doCommit) {
|
||||||
UploadStream.INSTANCE.commit();
|
UploadStream.INSTANCE.commit();
|
||||||
}
|
}
|
||||||
results.nodeIdUpdateData.free();
|
|
||||||
results.geometryIdUpdateData.free();
|
//Insert the result set into the cache
|
||||||
|
if (!RESULT_CACHE_1_HANDLE.compareAndSet(this, null, results)) {
|
||||||
|
//Failed to insert into result set 1, insert it into result set 2
|
||||||
|
if (!RESULT_CACHE_2_HANDLE.compareAndSet(this, null, results)) {
|
||||||
|
throw new IllegalStateException("Could not insert result into cache");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -461,28 +510,35 @@ public class AsyncNodeManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submitRequestBatch(MemoryBuffer batch) {
|
public void submitRequestBatch(MemoryBuffer batch) {//Only called from render thread
|
||||||
this.requestBatchQueue.add(batch);
|
this.requestBatchQueue.add(batch);
|
||||||
this.addWork();
|
this.addWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submitChildChange(WorldSection section) {
|
public void submitChildChange(WorldSection section) {
|
||||||
|
if (!this.running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
section.acquire();//We must acquire the section before putting in the queue
|
section.acquire();//We must acquire the section before putting in the queue
|
||||||
this.childUpdateQueue.add(section);
|
this.childUpdateQueue.add(section);
|
||||||
this.addWork();
|
this.addWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submitGeometryResult(BuiltSection geometry) {
|
public void submitGeometryResult(BuiltSection geometry) {
|
||||||
|
if (!this.running) {
|
||||||
|
geometry.free();
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.geometryUpdateQueue.add(geometry);
|
this.geometryUpdateQueue.add(geometry);
|
||||||
this.addWork();
|
this.addWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void submitRemoveBatch(MemoryBuffer batch) {
|
public void submitRemoveBatch(MemoryBuffer batch) {//Only called from render thread
|
||||||
this.removeBatchQueue.add(batch);
|
this.removeBatchQueue.add(batch);
|
||||||
this.addWork();
|
this.addWork();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTopLevel(long section) {
|
public void addTopLevel(long section) {//Only called from render thread
|
||||||
if (!this.running) throw new IllegalStateException("Not running");
|
if (!this.running) throw new IllegalStateException("Not running");
|
||||||
long stamp = this.tlnLock.writeLock();
|
long stamp = this.tlnLock.writeLock();
|
||||||
int state = this.tlnAdd.add(section)?1:0;
|
int state = this.tlnAdd.add(section)?1:0;
|
||||||
@@ -495,7 +551,7 @@ public class AsyncNodeManager {
|
|||||||
this.tlnLock.unlockWrite(stamp);
|
this.tlnLock.unlockWrite(stamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeTopLevel(long section) {
|
public void removeTopLevel(long section) {//Only called from render thread
|
||||||
if (!this.running) throw new IllegalStateException("Not running");
|
if (!this.running) throw new IllegalStateException("Not running");
|
||||||
long stamp = this.tlnLock.writeLock();
|
long stamp = this.tlnLock.writeLock();
|
||||||
int state = this.tlnRem.add(section)?1:0;
|
int state = this.tlnRem.add(section)?1:0;
|
||||||
@@ -548,7 +604,23 @@ public class AsyncNodeManager {
|
|||||||
buffer.free();
|
buffer.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: CLEANUP the sync data!
|
if (RESULT_HANDLE.get(this) != null) {
|
||||||
|
var result = (SyncResults)RESULT_HANDLE.getAndSet(this, null);
|
||||||
|
result.geometryUploads.forEach((a,b)->b.free());
|
||||||
|
result.nodeIdUpdateData.free();
|
||||||
|
result.geometryIdUpdateData.free();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RESULT_CACHE_1_HANDLE.get(this) != null) {//Clear cache 1
|
||||||
|
var result = (SyncResults)RESULT_CACHE_1_HANDLE.getAndSet(this, null);
|
||||||
|
result.nodeIdUpdateData.free();
|
||||||
|
result.geometryIdUpdateData.free();
|
||||||
|
}
|
||||||
|
if (RESULT_CACHE_2_HANDLE.get(this) != null) {//Clear cache 2
|
||||||
|
var result = (SyncResults)RESULT_CACHE_2_HANDLE.getAndSet(this, null);
|
||||||
|
result.nodeIdUpdateData.free();
|
||||||
|
result.geometryIdUpdateData.free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Results object, which is to be synced between the render thread and worker thread
|
//Results object, which is to be synced between the render thread and worker thread
|
||||||
@@ -579,5 +651,13 @@ public class AsyncNodeManager {
|
|||||||
this.geometryIdUpdateMap.defaultReturnValue(-1);
|
this.geometryIdUpdateMap.defaultReturnValue(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
this.nodeIdUpdateMap.clear();
|
||||||
|
this.currentMaxNodeId = 0;
|
||||||
|
this.tlnDelta.clear();
|
||||||
|
this.geometrySectionCount = 0;
|
||||||
|
this.geometryUploads.clear();
|
||||||
|
this.geometryIdUpdateMap.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,7 +132,9 @@ public class HierarchicalOcclusionTraverser {
|
|||||||
//Use clear buffer, yes know is a bad idea, TODO: replace
|
//Use clear buffer, yes know is a bad idea, TODO: replace
|
||||||
//Add the new top level node to the queue
|
//Add the new top level node to the queue
|
||||||
glClearNamedBufferSubData(this.topNodeIds.id, GL_R32UI, aid*4L, 4, GL_RED_INTEGER, GL_UNSIGNED_INT, new int[]{id});
|
glClearNamedBufferSubData(this.topNodeIds.id, GL_R32UI, aid*4L, 4, GL_RED_INTEGER, GL_UNSIGNED_INT, new int[]{id});
|
||||||
this.topNode2idxMapping.put(id, aid);
|
if (this.topNode2idxMapping.put(id, aid) != -1) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
this.idx2topNodeMapping[aid] = id;
|
this.idx2topNodeMapping[aid] = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class ServiceSlice extends TrackedObject {
|
|||||||
//Tells the system that a single instance of this service needs executing
|
//Tells the system that a single instance of this service needs executing
|
||||||
public void execute() {
|
public void execute() {
|
||||||
if (!this.alive) {
|
if (!this.alive) {
|
||||||
Logger.error("Tried to do work on a dead service: " + this.name);
|
Logger.error("Tried to do work on a dead service: " + this.name, new Throwable());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.jobCount.release();
|
this.jobCount.release();
|
||||||
|
|||||||
Reference in New Issue
Block a user