diff --git a/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiMcRenderingFadeMode.java b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiMcRenderingFadeMode.java
index b1b02560d..db393a0cb 100644
--- a/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiMcRenderingFadeMode.java
+++ b/api/src/main/java/com/seibel/distanthorizons/api/enums/config/EDhApiMcRenderingFadeMode.java
@@ -25,7 +25,8 @@ package com.seibel.distanthorizons.api.enums.config;
* between MC and DH rendering.
*
* NONE,
- * NON_COLLIDING,
+ * SINGLE_PASS,
+ * DOUBLE_PASS,
*
* @since API 4.0.0
* @version 2024-10-3
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java
index ed5cbecd4..2636d8bd4 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/logging/f3/F3Screen.java
@@ -26,6 +26,7 @@ import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.RenderBufferHandler;
import com.seibel.distanthorizons.core.render.renderer.generic.GenericObjectRenderer;
+import com.seibel.distanthorizons.core.util.threading.RateLimitedThreadPoolExecutor;
import com.seibel.distanthorizons.core.util.threading.ThreadPoolUtil;
import com.seibel.distanthorizons.core.world.AbstractDhWorld;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
@@ -145,7 +146,28 @@ public class F3Screen
String queueSize = (pool != null) ? NUMBER_FORMAT.format(pool.getQueue().size()) : "-";
String completedCount = (pool != null) ? NUMBER_FORMAT.format(pool.getCompletedTaskCount()) : "-";
- return name+", tasks: "+queueSize+", complete: "+completedCount;
+ String message = name+", Tasks: "+queueSize+", Done: "+completedCount;
+
+ if (pool != null && pool.getClass() == RateLimitedThreadPoolExecutor.class)
+ {
+ RateLimitedThreadPoolExecutor rateLimitedPool = ((RateLimitedThreadPoolExecutor) pool);
+
+ String runTimeAvgStr;
+ double runTimeAvgInMs = rateLimitedPool.getAverageRunTimeInMs();
+ if (!Double.isNaN(runTimeAvgInMs))
+ {
+ runTimeAvgStr = NUMBER_FORMAT.format(runTimeAvgInMs);
+ }
+ else
+ {
+ runTimeAvgStr = ">0";
+ }
+
+ message += ", Avg: "+runTimeAvgStr+"ms";
+ }
+
+
+ return message;
}
diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/threading/RateLimitedThreadPoolExecutor.java b/core/src/main/java/com/seibel/distanthorizons/core/util/threading/RateLimitedThreadPoolExecutor.java
index 4b49ade2c..909267d86 100644
--- a/core/src/main/java/com/seibel/distanthorizons/core/util/threading/RateLimitedThreadPoolExecutor.java
+++ b/core/src/main/java/com/seibel/distanthorizons/core/util/threading/RateLimitedThreadPoolExecutor.java
@@ -20,6 +20,7 @@
package com.seibel.distanthorizons.core.util.threading;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
+import com.seibel.distanthorizons.core.util.objects.RollingAverage;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
@@ -36,6 +37,7 @@ public class RateLimitedThreadPoolExecutor extends ThreadPoolExecutor
/** logs include the thread name by default which can help diagnose deadlocks */
private static final boolean LOG_SEMAPHORE_ACTIONS = false;
+
public volatile double runTimeRatio;
/** When this thread started running its last task */
@@ -51,6 +53,8 @@ public class RateLimitedThreadPoolExecutor extends ThreadPoolExecutor
/** will always be zero if no semaphore is present */
private final AtomicInteger semaphoresAcquired = new AtomicInteger(0);
+ private final RollingAverage runTimeInMsRollingAverage = new RollingAverage(200);
+
//==============//
@@ -85,11 +89,10 @@ public class RateLimitedThreadPoolExecutor extends ThreadPoolExecutor
try
{
long deltaMs = TimeUnit.NANOSECONDS.toMillis(this.lastRunDurationNanoTimeRef.get());
+ this.runTimeInMsRollingAverage.addValue(deltaMs);
Thread.sleep((long) (deltaMs / this.runTimeRatio - deltaMs));
}
- catch (InterruptedException ignored)
- {
- }
+ catch (InterruptedException ignored) { }
}
if (this.activeThreadCountSemaphore != null)
@@ -162,4 +165,7 @@ public class RateLimitedThreadPoolExecutor extends ThreadPoolExecutor
/** only one event handler can be present at a time */
public void setOnTerminatedEventHandler(Runnable runnable) { this.onTerminatedEventHandler = runnable; }
+ /** will return Nan if nothing has been submitted yet */
+ public double getAverageRunTimeInMs() { return this.runTimeInMsRollingAverage.getAverage(); }
+
}
\ No newline at end of file