Fix critical mem leak in BlockDetail + Add spaced out worldGenThread + make worldGenUpdate update once per 10 ticks + Semi-impl proper EarthCurveRatio limits + make worldGenThreads terminate faster + impl temp bypass to stop deadlocks on BufferFactory destroy() + fix chat logging messages with Throwable twice

This commit is contained in:
TomTheFurry
2022-04-17 18:07:50 +08:00
parent ff8b07ac12
commit 0658479921
7 changed files with 43 additions and 35 deletions
@@ -292,7 +292,7 @@ public class Config
@ConfigAnnotations.FileComment
public static String _earthCurveRatio = IAdvancedGraphics.EARTH_CURVE_RATIO_DESC;
@ConfigAnnotations.Entry(minValue = 0, maxValue = 10000)
@ConfigAnnotations.Entry(minValue = 0, maxValue = 5000)
public static int earthCurveRatio = IAdvancedGraphics.EARTH_CURVE_RATIO_MIN_DEFAULT_MAX.defaultValue;
/*
@@ -378,8 +378,8 @@ public class Config
{
@ConfigAnnotations.FileComment
public static String _numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DESC;
@ConfigAnnotations.Entry(minValue = 1, maxValue = 50)
public static int numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DEFAULT.defaultValue;
@ConfigAnnotations.Entry(minValue = 0.1, maxValue = 50.0)
public static double numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DEFAULT.defaultValue;
@ConfigAnnotations.FileComment
public static String _numberOfBufferBuilderThreads = IThreading.NUMBER_OF_BUFFER_BUILDER_THREADS_DESC;
@@ -69,6 +69,8 @@ import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.VoxelShape;
import org.jetbrains.annotations.Nullable;
/*-- WARN: This class should NEVER hold reference to anything large,
as this is never dealloc until the end of runtime!! --*/
public class BlockDetailWrapper extends IBlockDetailWrapper
{
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
@@ -158,10 +160,6 @@ public class BlockDetailWrapper extends IBlockDetailWrapper
return tempColor;
}
private static final Block[] BLOCK_TO_AVOID = {Blocks.AIR, Blocks.CAVE_AIR, Blocks.BARRIER};
private static final Direction[] DIRECTION_ORDER = {Direction.UP, Direction.NORTH, Direction.EAST, Direction.WEST, Direction.SOUTH, Direction.DOWN};
@@ -173,10 +171,11 @@ public class BlockDetailWrapper extends IBlockDetailWrapper
}
final BlockState state;
final BlockPos samplePos;
final LevelReader sampleGetter;
boolean isShapeResolved = false;
//boolean isShapeResolved = false;
//^ Shapes no longer lazy resolved due to memory leaks from needing
// to keep a reference to the block getter
boolean[] dontOccludeFaces = null;
boolean noCollision = false;
boolean noFullFace = false;
@@ -191,15 +190,12 @@ public class BlockDetailWrapper extends IBlockDetailWrapper
public BlockDetailWrapper(BlockState state, BlockPos pos, LevelReader getter) {
this.state = state;
this.samplePos = pos;
this.sampleGetter = getter;
resolveShapes(getter, pos);
//ApiShared.LOGGER.info("Created BlockDetailWrapper for blockstate {} at {}", state, pos);
}
private BlockDetailWrapper() {
this.state = null;
this.samplePos = null;
this.sampleGetter = null;
}
static BlockDetailWrapper make(BlockState bs, BlockPos pos, LevelReader getter) {
@@ -214,8 +210,8 @@ public class BlockDetailWrapper extends IBlockDetailWrapper
}
}
private void resolveShapes() {
if (isShapeResolved) return;
private void resolveShapes(LevelReader sampleGetter, BlockPos samplePos) {
//if (isShapeResolved) return;
if (state.getFluidState().isEmpty()) {
noCollision = state.getCollisionShape(sampleGetter, samplePos).isEmpty();
dontOccludeFaces = new boolean[6];
@@ -242,7 +238,6 @@ public class BlockDetailWrapper extends IBlockDetailWrapper
} else { // Liquid Block
dontOccludeFaces = new boolean[6];
}
isShapeResolved = true;
}
private void resolveColors() {
@@ -261,7 +256,6 @@ public class BlockDetailWrapper extends IBlockDetailWrapper
quads = Minecraft.getInstance().getModelManager().getBlockModelShaper().
getBlockModel(state).getQuads(state, null, random);
}
if (quads != null && !quads.isEmpty()) {
needPostTinting = quads.get(0).isTinted();
needShade = quads.get(0).isShade();
@@ -278,13 +272,11 @@ public class BlockDetailWrapper extends IBlockDetailWrapper
ColorMode.getColorMode(state.getBlock()));
}
} else { // Liquid Block
needPostTinting = true;
needShade = false;
tintIndex = 0;
baseColor = calculateColorFromTexture(Minecraft.getInstance().getModelManager().getBlockModelShaper().getParticleIcon(state),
ColorMode.getColorMode(state.getBlock()));
}
isColorResolved = true;
}
@@ -314,21 +306,21 @@ public class BlockDetailWrapper extends IBlockDetailWrapper
@Override
public boolean hasFaceCullingFor(LodDirection dir)
{
resolveShapes();
//resolveShapes();
return !dontOccludeFaces[dir.ordinal()];
}
@Override
public boolean hasNoCollision()
{
resolveShapes();
//resolveShapes();
return noCollision;
}
@Override
public boolean noFaceIsFullFace()
{
resolveShapes();
//resolveShapes();
return noFullFace;
}
@@ -546,11 +546,12 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
@Override
public int getEarthCurveRatio()
{
return Config.Client.Graphics.AdvancedGraphics.earthCurveRatio;
return (int) ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.earthCurveRatio").value;
}
@Override
public void setEarthCurveRatio(int newEarthCurveRatio)
{
if (newEarthCurveRatio < 50) newEarthCurveRatio = 0;
ConfigGui.editSingleOption.getEntry("client.graphics.advancedGraphics.earthCurveRatio").value = newEarthCurveRatio;
ConfigGui.editSingleOption.saveOption("client.graphics.advancedGraphics.earthCurveRatio");
}
@@ -715,12 +716,12 @@ public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
public static class Threading implements IThreading
{
@Override
public int getNumberOfWorldGenerationThreads()
public double getNumberOfWorldGenerationThreads()
{
return Config.Client.Advanced.Threading.numberOfWorldGenerationThreads;
}
@Override
public void setNumberOfWorldGenerationThreads(int newNumberOfWorldGenerationThreads)
public void setNumberOfWorldGenerationThreads(double newNumberOfWorldGenerationThreads)
{
ConfigGui.editSingleOption.getEntry("client.advanced.threading.numberOfWorldGenerationThreads").value = newNumberOfWorldGenerationThreads;
ConfigGui.editSingleOption.saveOption("client.advanced.threading.numberOfWorldGenerationThreads");
@@ -256,7 +256,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
}
public ExecutorService executors = Executors.newFixedThreadPool(
CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads(), threadFactory);
CONFIG.client().advanced().threading()._getWorldGenerationThreadPoolSize(), threadFactory);
public <T> T joinSync(CompletableFuture<T> f) {
if (!unsafeThreadingRecorded && !f.isDone()) {
@@ -273,7 +273,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY));
}
public boolean tryAddPoint(int px, int pz, int range, Steps target, boolean genAllDetails)
public boolean tryAddPoint(int px, int pz, int range, Steps target, boolean genAllDetails, double runTimeRatio)
{
int boxSize = range * 2 + 1;
int x = Math.floorDiv(px, boxSize) * boxSize + range;
@@ -285,7 +285,7 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
return false;
}
// System.out.println(x + ", "+z);
events.add(new GenerationEvent(new ChunkPos(x, z), range, this, target, genAllDetails));
events.add(new GenerationEvent(new ChunkPos(x, z), range, this, target, genAllDetails, runTimeRatio));
return true;
}
@@ -43,16 +43,19 @@ public final class GenerationEvent
final ChunkPos pos;
final int range;
final Future<?> future;
long nanotime;
long creationNanotime;
final int id;
final Steps target;
final LightGenerationMode lightMode;
final PrefEvent pEvent = new PrefEvent();
final boolean genAllDetails;
final double runTimeRatio;
public GenerationEvent(ChunkPos pos, int range, BatchGenerationEnvironment generationGroup, Steps target, boolean genAllDetails)
public GenerationEvent(ChunkPos pos, int range, BatchGenerationEnvironment generationGroup,
Steps target, boolean genAllDetails, double runTimeRatio)
{
nanotime = System.nanoTime();
creationNanotime = System.nanoTime();
this.pos = pos;
this.range = range;
id = generationFutureDebugIDs++;
@@ -62,14 +65,24 @@ public final class GenerationEvent
this.lightMode = mode;
this.genAllDetails = genAllDetails;
this.runTimeRatio = runTimeRatio;
future = generationGroup.executors.submit(() ->
{
long startTime = System.nanoTime();
BatchGenerationEnvironment.isDistantGeneratorThread.set(true);
try {
generationGroup.generateLodFromList(this);
} finally {
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
if (!Thread.interrupted() && runTimeRatio < 1.0) {
long endTime = System.nanoTime();
try {
long deltaMs = TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
Thread.sleep((long) (deltaMs/runTimeRatio - deltaMs));
} catch (InterruptedException ignored) {
}
}
}
});
}
@@ -82,7 +95,7 @@ public final class GenerationEvent
public boolean hasTimeout(int duration, TimeUnit unit)
{
long currentTime = System.nanoTime();
long delta = currentTime - nanotime;
long delta = currentTime - creationNanotime;
return (delta > TimeUnit.NANOSECONDS.convert(duration, unit));
}
@@ -117,7 +130,7 @@ public final class GenerationEvent
public void refreshTimeout()
{
nanotime = System.nanoTime();
creationNanotime = System.nanoTime();
LodUtil.checkInterruptsUnchecked();
}
@@ -28,6 +28,7 @@ import com.google.common.collect.Sets;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.common.wrappers.worldGeneration.ThreadedParameters;
import com.seibel.lod.core.util.LodUtil;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.util.Mth;
#if POST_MC_1_17_1
@@ -82,6 +83,7 @@ public final class StepNoise {
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
#endif
LodUtil.checkInterruptsUnchecked(); // Speed up termination responsiveness
}
}
}
+1 -1
Submodule core updated: d2fef22719...a3022d2c64