Skip to content

Commit

Permalink
Remove use of empty build tasks, submit empty data directly to result…
Browse files Browse the repository at this point in the history
… queue (#821)
  • Loading branch information
embeddedt authored Dec 28, 2024
1 parent 19635e2 commit 95f8afc
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -552,25 +552,39 @@ public void updateChunks() {
continue;
}

// Do not allow distant chunks to block rendering
if (this.alwaysDeferChunkUpdates || !this.isChunkPrioritized(render)) {
this.builder.deferRebuild(render);
CompletableFuture<ChunkBuildResult<T>> futureTask = this.builder.scheduleRebuildTaskAsync(render);

if (futureTask != null) {
this.dirty = true;

// Do not allow distant chunks to block rendering
if (this.alwaysDeferChunkUpdates || !this.isChunkPrioritized(render)) {
this.builder.handleCompletion(futureTask);
} else {
futures.add(futureTask);
}

submitted++;
// Limit quantity of updates submitted if we are deferring all important builds
if (this.alwaysDeferChunkUpdates && submitted >= budget)
break;
} else {
futures.add(this.builder.scheduleRebuildTaskAsync(render));
// Immediately submit empty data to the queue and do not count this against the budget
this.builder.enqueueUpload(new ChunkBuildResult<>(render, ChunkRenderData.EMPTY));
}

this.dirty = true;
submitted++;
// Limit quantity of updates submitted if we are deferring all important builds
if (this.alwaysDeferChunkUpdates && submitted >= budget)
break;
}

while (submitted < budget && !this.rebuildQueue.isEmpty()) {
ChunkRenderContainer<T> render = this.rebuildQueue.dequeue();

this.builder.deferRebuild(render);
submitted++;
CompletableFuture<ChunkBuildResult<T>> futureTask = this.builder.scheduleRebuildTaskAsync(render);
if(futureTask != null) {
this.builder.handleCompletion(futureTask);
submitted++;
} else {
// Immediately submit empty data to the queue and do not count this against the budget
this.builder.enqueueUpload(new ChunkBuildResult<>(render, ChunkRenderData.EMPTY));
}
}

// always do at least one sort
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderBackend;
import me.jellysquid.mods.sodium.client.render.chunk.ChunkRenderContainer;
import me.jellysquid.mods.sodium.client.render.chunk.tasks.ChunkRenderBuildTask;
import me.jellysquid.mods.sodium.client.render.chunk.tasks.ChunkRenderEmptyBuildTask;
import me.jellysquid.mods.sodium.client.render.chunk.tasks.ChunkRenderRebuildTask;
import me.jellysquid.mods.sodium.client.render.chunk.tasks.ChunkRenderTranslucencySortTask;
import me.jellysquid.mods.sodium.client.render.pipeline.context.ChunkRenderCacheLocal;
Expand All @@ -26,6 +25,7 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.joml.Vector3d;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.Deque;
Expand Down Expand Up @@ -294,7 +294,10 @@ private static int getMaxThreadCount() {
return Runtime.getRuntime().availableProcessors();
}

private void handleCompletion(CompletableFuture<ChunkBuildResult<T>> future) {
/**
* Add a completion handler to the given future task so that the result will be processed on the main thread.
*/
public void handleCompletion(CompletableFuture<ChunkBuildResult<T>> future) {
future.whenComplete((res, ex) -> {
if (ex != null) {
this.failureQueue.add(ex);
Expand All @@ -304,16 +307,6 @@ private void handleCompletion(CompletableFuture<ChunkBuildResult<T>> future) {
});
}

/**
* Creates a rebuild task and defers it to the work queue. When the task is completed, it will be moved onto the
* completed uploads queued which will then be drained during the next available synchronization point with the
* main thread.
* @param render The render to rebuild
*/
public void deferRebuild(ChunkRenderContainer<T> render) {
handleCompletion(this.scheduleRebuildTaskAsync(render));
}

/**
* Creates a rebuild task and defers it to the work queue. When the task is completed, it will be moved onto the
* completed uploads queued which will then be drained during the next available synchronization point with the
Expand All @@ -330,16 +323,24 @@ public void deferSort(ChunkRenderContainer<T> render) {
* synchronization point on the main thread.
* @param result The build task's result
*/
private void enqueueUpload(ChunkBuildResult<T> result) {
public void enqueueUpload(ChunkBuildResult<T> result) {
this.uploadQueue.add(result);
}

/**
* Schedules the rebuild task asynchronously on the worker pool, returning a future wrapping the task.
* @param render The render to rebuild
* @return a future representing the rebuild task, or null if the chunk section is empty
*/
@Nullable
public CompletableFuture<ChunkBuildResult<T>> scheduleRebuildTaskAsync(ChunkRenderContainer<T> render) {
return this.schedule(this.createRebuildTask(render));
ChunkRenderBuildTask<T> task = this.createRebuildTask(render);

if(task != null) {
return this.schedule(task);
} else {
return null;
}
}

/**
Expand All @@ -360,7 +361,7 @@ private ChunkRenderBuildTask<T> createRebuildTask(ChunkRenderContainer<T> render
ChunkRenderContext context = WorldSlice.prepare(this.world, render.getChunkPos(), this.sectionCache);

if (context == null) {
return new ChunkRenderEmptyBuildTask<>(render);
return null;
} else {
return new ChunkRenderRebuildTask<>(render, context, render.getRenderOrigin()).withCameraPosition(this.cameraPosition);
}
Expand Down

This file was deleted.

0 comments on commit 95f8afc

Please sign in to comment.