Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove use of empty build tasks, submit empty data directly to result queue #821

Merged
merged 1 commit into from
Dec 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.