Shader lighting, fixes for loosing tasks in MultiThreadPrioritySemaphore, limit render generation rebuilds based on model queue and failure rate, fix native memory leak in ModelFactory (related to raw download stream)
This commit is contained in:
@@ -70,6 +70,7 @@ public class VoxyCommands {
|
||||
}
|
||||
|
||||
VoxyCommon.shutdownInstance();
|
||||
System.gc();
|
||||
VoxyCommon.createInstance();
|
||||
if (wr!=null) {
|
||||
((IGetVoxyRenderSystem)wr).createRenderer();
|
||||
|
||||
@@ -77,6 +77,7 @@ public class VoxyRenderSystem {
|
||||
//Keep the world loaded, NOTE: this is done FIRST, to keep and ensure that even if the rest of loading takes more
|
||||
// than timeout, we keep the world acquired
|
||||
world.acquireRef();
|
||||
System.gc();
|
||||
|
||||
//Fking HATE EVERYTHING AAAAAAAAAAAAAAAA
|
||||
int[] oldBufferBindings = new int[10];
|
||||
|
||||
@@ -33,7 +33,7 @@ public class ModelBakerySubsystem {
|
||||
while (this.isRunning) {
|
||||
this.factory.processAllThings();
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
@@ -913,14 +913,14 @@ public class ModelFactory {
|
||||
}
|
||||
|
||||
public void free() {
|
||||
this.bakery.free();
|
||||
this.downstream.free();
|
||||
while (!this.rawBakeResults.isEmpty()) {
|
||||
this.rawBakeResults.poll().rawData.free();
|
||||
}
|
||||
while (!this.uploadResults.isEmpty()) {
|
||||
this.uploadResults.poll().free();
|
||||
}
|
||||
this.downstream.free();
|
||||
this.bakery.free();
|
||||
}
|
||||
|
||||
public int getBakedCount() {
|
||||
|
||||
@@ -79,7 +79,7 @@ public class RenderGenerationService {
|
||||
return new Pair<>(() -> {
|
||||
this.processJob(factory, seenMissed);
|
||||
}, factory::free);
|
||||
}, 10, "Section mesh generation service");
|
||||
}, 10, "Section mesh generation service", ()->modelBakery.getProcessingCount()<400||RenderGenerationService.MESH_FAILED_COUNTER.get()<500);
|
||||
}
|
||||
|
||||
public void setResultConsumer(Consumer<BuiltSection> consumer) {
|
||||
@@ -354,14 +354,12 @@ public class RenderGenerationService {
|
||||
}
|
||||
|
||||
private long lastChangedTime = 0;
|
||||
private int failedCounter = 0;
|
||||
public void addDebugData(List<String> debug) {
|
||||
if (System.currentTimeMillis()-this.lastChangedTime > 1000) {
|
||||
this.failedCounter = 0;
|
||||
if (System.currentTimeMillis()-this.lastChangedTime > 100) {
|
||||
MESH_FAILED_COUNTER.set(0);
|
||||
this.lastChangedTime = System.currentTimeMillis();
|
||||
}
|
||||
this.failedCounter += MESH_FAILED_COUNTER.getAndSet(0);
|
||||
debug.add("RSSQ/TFC: " + this.taskQueueCount.get() + "/" + this.failedCounter);//render section service queue, Task Fail Counter
|
||||
debug.add("RSSQ/TFC: " + this.taskQueueCount.get() + "/" + MESH_FAILED_COUNTER.get());//render section service queue, Task Fail Counter
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,17 @@ public class RawDownloadStream {
|
||||
}
|
||||
|
||||
public void free() {
|
||||
glFinish();
|
||||
this.tick();
|
||||
GlFence fence = new GlFence();
|
||||
while (!fence.signaled()) {
|
||||
glFinish();
|
||||
}
|
||||
fence.free();
|
||||
this.tick();
|
||||
if (this.frames.size() != 0) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
this.frames.forEach(a->a.fence.free());
|
||||
this.downloadBuffer.free();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import me.cortex.voxy.common.util.TrackedObject;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
//Basiclly acts as a priority based mutlti semaphore
|
||||
// allows the pooling of multiple threadpools together while prioritizing the work the original was ment for
|
||||
@@ -51,7 +53,9 @@ public class MultiThreadPrioritySemaphore {
|
||||
if (this.localSemaphore.tryAcquire()) {//We prioritize locals first
|
||||
return;
|
||||
}
|
||||
this.man.tryRun(this);
|
||||
if (this.man.tryRun(this)) {//Returns true if it captured a local job
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.localSemaphore.acquireUninterruptibly();
|
||||
if (!this.blockSemaphore.tryAcquire()) {
|
||||
@@ -87,11 +91,11 @@ public class MultiThreadPrioritySemaphore {
|
||||
}
|
||||
|
||||
private final Semaphore pooledSemaphore = new Semaphore(0);
|
||||
private final Runnable executor;
|
||||
private final IntSupplier executor;
|
||||
|
||||
private volatile Block[] blocks = new Block[0];
|
||||
|
||||
public MultiThreadPrioritySemaphore(Runnable executor) {
|
||||
public MultiThreadPrioritySemaphore(IntSupplier executor) {
|
||||
this.executor = executor;
|
||||
}
|
||||
|
||||
@@ -136,7 +140,22 @@ public class MultiThreadPrioritySemaphore {
|
||||
}
|
||||
}*/
|
||||
//Run the pooled job
|
||||
this.executor.run();
|
||||
return true;
|
||||
while (true) {
|
||||
int status = this.executor.getAsInt();
|
||||
if (status == 0) return false;//We finished pure and true
|
||||
if (status == 1) return false;// we didnt run a job because there either wasnt any or no services exist
|
||||
if (2 <= status) {//2 and 3 mean failed to find a service that can currently run, but should try again after a delay
|
||||
try {
|
||||
if (block.localSemaphore.tryAcquire(10, TimeUnit.MILLISECONDS)) {//Await 10 millis for a local job to come in
|
||||
//We do this confusing thing
|
||||
block.blockSemaphore.tryAcquire();//Try acquire the block that we just got
|
||||
this.pooledRelease(1);//We need to release back into the pool
|
||||
return true;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,48 +58,49 @@ public class ServiceManager {
|
||||
return newService;
|
||||
}
|
||||
|
||||
public boolean runAJob() {//Executes a single job on the current thread
|
||||
while (true) {
|
||||
if (this.services.length == 0 || this.totalJobs.get() == 0) return false;
|
||||
if (this.runAJob0()) return true;
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
public int tryRunAJob() {//Executes a single job on the current thread
|
||||
if (this.services.length == 0 || this.totalJobs.get() == 0) return 1;
|
||||
return this.runAJob0();
|
||||
}
|
||||
|
||||
private boolean runAJob0() {//Executes a single job on the current thread
|
||||
if (this.services.length == 0) return false;
|
||||
private int runAJob0() {//Executes a single job on the current thread
|
||||
if (this.services.length == 0) return 1;
|
||||
var ctx = this.accelerationContext.get();
|
||||
outer:
|
||||
while (true) {
|
||||
long skipMsk = 0;
|
||||
var services = this.services;//Capture the current services array
|
||||
if (services.length == 0) return false;
|
||||
if (this.totalJobs.get()==0) return false;
|
||||
if (services.length == 0) return 1;
|
||||
if (this.totalJobs.get()==0) return 1;
|
||||
long totalWeight = 0;
|
||||
int shiftFactor = (ctx.shiftFactor++)&Integer.MAX_VALUE;//We cycle and shift the starting service when choosing to prevent bias
|
||||
int c = shiftFactor;
|
||||
Service selectedService = null;
|
||||
for (var service:services) {
|
||||
for (int i = 0; i < services.length; i++) {
|
||||
var service = services[i];
|
||||
if (!service.isLive()) {
|
||||
Thread.yield();
|
||||
continue outer;//We need to refetch the array and start over
|
||||
}
|
||||
boolean sc = c--<=0;
|
||||
if (service.limiter!=null && !service.limiter.getAsBoolean()) continue;
|
||||
if (service.limiter!=null && !service.limiter.getAsBoolean()) {
|
||||
skipMsk |= 1L<<i;
|
||||
continue;
|
||||
}
|
||||
long jc = service.numJobs();
|
||||
if (sc&&jc!=0&&selectedService==null) selectedService=service;
|
||||
totalWeight += jc * service.weight;
|
||||
}
|
||||
if (totalWeight == 0) return false;
|
||||
if (totalWeight == 0) return skipMsk!=0?3:2;
|
||||
|
||||
long sample = ctx.rand(totalWeight);//Random number
|
||||
|
||||
for (int i = 0; i < services.length; i++) {
|
||||
var service = services[(i+shiftFactor)%services.length];
|
||||
if (service.limiter!=null && !service.limiter.getAsBoolean()) continue;
|
||||
if (service.limiter!=null && (((skipMsk&(1L<<i))!=0)|| !service.limiter.getAsBoolean())) {
|
||||
skipMsk |= 1L<<i;
|
||||
continue;
|
||||
}
|
||||
sample -= service.numJobs() * service.weight;
|
||||
if (sample<=0) {
|
||||
selectedService = service;
|
||||
@@ -108,7 +109,7 @@ public class ServiceManager {
|
||||
}
|
||||
|
||||
if (selectedService == null) {
|
||||
return false;
|
||||
return skipMsk!=0?3:2;
|
||||
}
|
||||
|
||||
if (!selectedService.isLive()) {
|
||||
@@ -124,7 +125,7 @@ public class ServiceManager {
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
|
||||
@@ -18,7 +18,7 @@ public class UnifiedServiceThreadPool {
|
||||
public UnifiedServiceThreadPool() {
|
||||
this.dedicatedPool = new ThreadGroup("Voxy Dedicated Service");
|
||||
this.serviceManager = new ServiceManager(this::release);
|
||||
this.groupSemaphore = new MultiThreadPrioritySemaphore(this.serviceManager::runAJob);
|
||||
this.groupSemaphore = new MultiThreadPrioritySemaphore(this.serviceManager::tryRunAJob);
|
||||
|
||||
this.selfBlock = this.groupSemaphore.createBlock();
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ uint getFace() {
|
||||
#ifdef PATCHED_SHADER
|
||||
vec2 getLightmap() {
|
||||
//return clamp(vec2(interData.y&0xFu, (interData.y>>4)&0xFu)/16, vec2(4.0f/255), vec2(252.0f/255));
|
||||
return vec2(interData.y&0xFu, (interData.y>>4)&0xFu)/15;
|
||||
return clamp((vec2((interData.y>>4)&0xFu, interData.y&0xFu))/16, vec2(8.0f/256), vec2(248.0f/256));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -190,7 +190,9 @@ void main() {
|
||||
tint = uint2vec4RGBA(interData.z).yzwx;
|
||||
}
|
||||
|
||||
voxy_emitFragment(VoxyFragmentParameters(colour, tile, texPos, getFace(), modelId, getLightmap().yx, tint, model.customId));
|
||||
uint face = getFace();
|
||||
face ^= uint((face&1u)!=uint(gl_FrontFacing!=((face>>1)!=0u)));
|
||||
voxy_emitFragment(VoxyFragmentParameters(colour, tile, texPos, face, modelId, getLightmap(), tint, model.customId));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user