From e69eeba47c1c7e12080e077b370fdc27fe8da351 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Tue, 22 Oct 2024 12:38:20 -0700 Subject: [PATCH 1/3] Use Moonrise executor for section occlusion tasks --- .../moonrise/common/util/MoonriseCommon.java | 1 + .../render/SectionOcclusionGraphMixin.java | 43 +++++++++++++++++++ src/main/resources/moonrise.mixins.json | 1 + 3 files changed, 45 insertions(+) create mode 100644 src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java diff --git a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java index c125c70a..0d75efbb 100644 --- a/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java +++ b/src/main/java/ca/spottedleaf/moonrise/common/util/MoonriseCommon.java @@ -32,6 +32,7 @@ public void uncaughtException(final Thread thread, final Throwable throwable) { public static final long WORKER_QUEUE_HOLD_TIME = (long)(20.0e6); // 20ms public static final int CLIENT_DIVISION = 0; public static final PrioritisedThreadPool.ExecutorGroup RENDER_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); + public static final PrioritisedThreadPool.ExecutorGroup SECTION_OCCLUSION_EXECUTOR_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(CLIENT_DIVISION, 0); public static final int SERVER_DIVISION = 1; public static final PrioritisedThreadPool.ExecutorGroup PARALLEL_GEN_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); public static final PrioritisedThreadPool.ExecutorGroup RADIUS_AWARE_GROUP = MoonriseCommon.WORKER_POOL.createExecutorGroup(SERVER_DIVISION, 0); diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java new file mode 100644 index 00000000..433fadb7 --- /dev/null +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java @@ -0,0 +1,43 @@ +package ca.spottedleaf.moonrise.mixin.render; + +import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; +import ca.spottedleaf.concurrentutil.util.Priority; +import ca.spottedleaf.moonrise.common.util.MoonriseCommon; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import net.minecraft.client.renderer.SectionOcclusionGraph; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(SectionOcclusionGraph.class) +abstract class SectionOcclusionGraphMixin { + + @Unique + private static final PrioritisedThreadPool.ExecutorGroup.ThreadPoolExecutor SECTION_OCCLUSION_EXECUTOR = MoonriseCommon.SECTION_OCCLUSION_EXECUTOR_GROUP.createExecutor( + -1, MoonriseCommon.WORKER_QUEUE_HOLD_TIME, 0 + ); + + /** + * @reason Change executor to use our thread pool + * Note: even at normal priority, our worker pool will try to share resources equally rather than having it + * be a free-for-all + * @author jpenilla + */ + @Redirect( + method = "scheduleFullUpdate", + at = @At( + value = "INVOKE", + target = "Ljava/util/concurrent/CompletableFuture;runAsync(Ljava/lang/Runnable;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;" + ) + ) + private CompletableFuture changeExecutor(final Runnable runnable, final Executor executor) { + return CompletableFuture.runAsync( + runnable, + (final Runnable task) -> { + SECTION_OCCLUSION_EXECUTOR.queueTask(task, Priority.NORMAL); + } + ); + } +} diff --git a/src/main/resources/moonrise.mixins.json b/src/main/resources/moonrise.mixins.json index a996f60e..75d09b3e 100644 --- a/src/main/resources/moonrise.mixins.json +++ b/src/main/resources/moonrise.mixins.json @@ -128,6 +128,7 @@ "config.MinecraftMixin", "loading_screen.LevelLoadStatusManagerMixin", "profiler.MinecraftMixin", + "render.SectionOcclusionGraphMixin", "render.SectionRenderDispatcherMixin", "serverlist.ClientConnectionMixin", "serverlist.ServerAddressResolverMixin", From b5b6e38cb7a64049c3170ff3fd70a507898f4877 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:09:21 -0700 Subject: [PATCH 2/3] attempt to execute task on #get to minimize blocking --- .../render/SectionOcclusionGraphMixin.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java index 433fadb7..9cada0b0 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java @@ -1,9 +1,11 @@ package ca.spottedleaf.moonrise.mixin.render; +import ca.spottedleaf.concurrentutil.executor.PrioritisedExecutor; import ca.spottedleaf.concurrentutil.executor.thread.PrioritisedThreadPool; import ca.spottedleaf.concurrentutil.util.Priority; import ca.spottedleaf.moonrise.common.util.MoonriseCommon; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import net.minecraft.client.renderer.SectionOcclusionGraph; import org.spongepowered.asm.mixin.Mixin; @@ -33,11 +35,22 @@ abstract class SectionOcclusionGraphMixin { ) ) private CompletableFuture changeExecutor(final Runnable runnable, final Executor executor) { - return CompletableFuture.runAsync( - runnable, - (final Runnable task) -> { - SECTION_OCCLUSION_EXECUTOR.queueTask(task, Priority.NORMAL); + final PrioritisedExecutor.PrioritisedTask[] prioritisedTask = new PrioritisedExecutor.PrioritisedTask[1]; + final CompletableFuture future = new CompletableFuture<>() { + @Override + public Void get() throws InterruptedException, ExecutionException { + prioritisedTask[0].execute(); + return super.get(); } - ); + }; + prioritisedTask[0] = SECTION_OCCLUSION_EXECUTOR.queueTask(() -> { + try { + runnable.run(); + future.complete(null); + } catch (final Throwable throwable) { + future.completeExceptionally(throwable); + } + }, Priority.NORMAL); + return future; } } From 500c0777f84f34da44e59d03a1662e5793695e3f Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Wed, 23 Oct 2024 15:38:59 -0700 Subject: [PATCH 3/3] Raise priority of occlusion task Having this at a higher priority than section render tasks seems to give better results anecdotally --- .../moonrise/mixin/render/SectionOcclusionGraphMixin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java b/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java index 9cada0b0..82d3dbab 100644 --- a/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java +++ b/src/main/java/ca/spottedleaf/moonrise/mixin/render/SectionOcclusionGraphMixin.java @@ -50,7 +50,7 @@ public Void get() throws InterruptedException, ExecutionException { } catch (final Throwable throwable) { future.completeExceptionally(throwable); } - }, Priority.NORMAL); + }, Priority.HIGH); // Higher than SectionRenderDispatcherMixin#changeExecutor return future; } }