From f4c3ad8bb5757c9eced925d4965ffe97f8740a64 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Sat, 28 Aug 2021 20:32:58 +0200 Subject: [PATCH] Fixed the garbage collector being called too much --- .../seibel/lod/builders/LodBufferBuilder.java | 48 +++++++++++++++++-- .../com/seibel/lod/objects/LodDimension.java | 5 +- .../com/seibel/lod/objects/LodRegion.java | 23 +++++++-- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java index 7484ce7e7..90fbfd10a 100644 --- a/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBufferBuilder.java @@ -17,6 +17,10 @@ */ package com.seibel.lod.builders; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.locks.ReentrantLock; + import java.util.ArrayList; import java.util.HashSet; import java.util.List; @@ -29,6 +33,7 @@ import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.locks.ReentrantLock; +import org.apache.commons.lang3.mutable.MutableBoolean; import org.lwjgl.opengl.GL11; import com.seibel.lod.handlers.LodConfig; @@ -106,6 +111,8 @@ public class LodBufferBuilder */ private ReentrantLock bufferLock = new ReentrantLock(); + private Object[][] setsToRender; + private RegionPos lastRegionPos; public LodBufferBuilder() { @@ -161,7 +168,19 @@ public class LodBufferBuilder // =====================// // RENDERING PART // // =====================// - ConcurrentMap> adjMap = new ConcurrentSkipListMap<>(); + + RegionPos newRegionPos = new RegionPos(playerChunkPos); + if(lastRegionPos == null) + lastRegionPos = newRegionPos; + + if (setsToRender == null) + setsToRender = new Object[lodDim.regions.length][lodDim.regions.length]; + + if (setsToRender.length != lodDim.regions.length || lastRegionPos == newRegionPos) + { + lastRegionPos = newRegionPos; + setsToRender = new Object[lodDim.regions.length][lodDim.regions.length]; + } for (int xRegion = 0; xRegion < lodDim.regions.length; xRegion++) { @@ -178,9 +197,15 @@ public class LodBufferBuilder // changed while we were running this method if (currentBuffer == null || (currentBuffer != null && !currentBuffer.building())) return; + + if (setsToRender[xRegion][zRegion] == null) + { + setsToRender[xRegion][zRegion] = new ConcurrentHashMap(); + } + ConcurrentMap nodeToRender = (ConcurrentMap) setsToRender[xRegion][zRegion]; + Callable dataToRenderThread = () -> { - Set nodeToRender = new HashSet<>(); lodDim.getDataToRender( nodeToRender, regionPos, @@ -188,8 +213,21 @@ public class LodBufferBuilder playerBlockPosRounded.getZ()); LevelPos adjPos = new LevelPos(); - for (LevelPos posToRender : nodeToRender) + for (LevelPos posToRender : nodeToRender.keySet()) { + if (!nodeToRender.get(posToRender).booleanValue()) + { + nodeToRender.remove(posToRender); + continue; + } + nodeToRender.get(posToRender).setFalse(); + // skip any chunks that Minecraft is going to render + + if (renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())) + { + continue; + } + LevelPos chunkPos = posToRender.getConvertedLevelPos(LodUtil.CHUNK_DETAIL_LEVEL); // skip any chunks that Minecraft is going to render @@ -209,7 +247,7 @@ public class LodBufferBuilder { adjPos.changeParameters(posToRender.detailLevel, posToRender.posX + x * 2 - 1, posToRender.posZ); if (!renderer.vanillaRenderedChunks.contains(adjPos.getChunkPos()) - && (nodeToRender.contains(adjPos) || disableFix)) + && (nodeToRender.containsKey(adjPos) || disableFix)) adjData[0][x] = lodDim.getData(adjPos); } @@ -217,7 +255,7 @@ public class LodBufferBuilder { adjPos.changeParameters(posToRender.detailLevel, posToRender.posX, posToRender.posZ + z * 2 - 1); if (!renderer.vanillaRenderedChunks.contains(adjPos.getChunkPos()) - && (nodeToRender.contains(adjPos) || disableFix)) + && (nodeToRender.containsKey(adjPos) || disableFix)) adjData[1][z] = lodDim.getData(adjPos); } LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPos, lodData, adjData, diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 9397f5156..7072deebf 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -40,6 +41,7 @@ import net.minecraft.util.math.ChunkPos; import net.minecraft.world.DimensionType; import net.minecraft.world.server.ServerChunkProvider; import net.minecraft.world.server.ServerWorld; +import org.apache.commons.lang3.mutable.MutableBoolean; /** @@ -513,9 +515,8 @@ public class LodDimension * * @return list of nodes */ - public void getDataToRender(Set dataToRender, RegionPos regionPos, int playerPosX, int playerPosZ) + public void getDataToRender(ConcurrentMap dataToRender, RegionPos regionPos, int playerPosX, int playerPosZ) { - LevelPos regionLevelPos = new LevelPos(LodUtil.REGION_DETAIL_LEVEL, regionPos.x, regionPos.z); try { LodRegion region = getRegion(regionPos); diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index cb2fc8c87..307a45254 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -2,6 +2,7 @@ package com.seibel.lod.objects; import java.io.Serializable; import java.util.*; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentSkipListSet; @@ -13,6 +14,7 @@ import com.seibel.lod.util.LodUtil; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; +import org.apache.commons.lang3.mutable.MutableBoolean; /** * STANDARD TO FOLLOW @@ -275,7 +277,7 @@ public class LodRegion implements Serializable /** * @return */ - public void getDataToRender(Set dataToRender, int playerPosX, int playerPosZ) + public void getDataToRender(ConcurrentMap dataToRender, int playerPosX, int playerPosZ) { LevelPos levelPos = new LevelPos(LodUtil.REGION_DETAIL_LEVEL, 0, 0); getDataToRender(dataToRender, levelPos, playerPosX, playerPosZ); @@ -284,7 +286,7 @@ public class LodRegion implements Serializable /** * @return */ - private void getDataToRender(Set dataToRender, LevelPos levelPos, int playerPosX, int playerPosZ) + private void getDataToRender(ConcurrentMap dataToRender, LevelPos levelPos, int playerPosX, int playerPosZ) { int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - levelPos.detailLevel); @@ -301,7 +303,14 @@ public class LodRegion implements Serializable return; else if (supposedLevel == detailLevel) { - dataToRender.add(new LevelPos(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size)); + if (dataToRender.containsKey(levelPos)) + { + //levelPos.changeParameters(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size); + dataToRender.get(new LevelPos(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size)).setTrue(); + }else + { + dataToRender.put(new LevelPos(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size), new MutableBoolean(true)); + } } else //case where (detailLevel > supposedLevel) { int childPosX = posX * 2; @@ -329,12 +338,18 @@ public class LodRegion implements Serializable } } else { - dataToRender.add(new LevelPos(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size)); + + levelPos.changeParameters(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size); + if (dataToRender.containsKey(levelPos)) + dataToRender.get(levelPos).setTrue(); + else + dataToRender.put(new LevelPos(detailLevel, posX + regionPosX * size, posZ + regionPosZ * size), new MutableBoolean(true)); } } return; } + /** * @param levelPos */