diff --git a/.vscode/launch.json b/.vscode/launch.json index 92016f42..5d82726e 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "name": "Launch Current File", "request": "launch", "mainClass": "${file}", - "vmArgs": "-Xmx4G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=3G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", + "vmArgs": "-Xmx6G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=5G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", "preLaunchTask": "Install Native Lib" }, { @@ -14,7 +14,7 @@ "name": "Launch Main", "request": "launch", "mainClass": "electrosphere.engine.Main", - "vmArgs": "-Xmx4G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=3G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", + "vmArgs": "-Xmx6G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=5G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", "projectName": "Renderer", "preLaunchTask": "Install Native Lib" }, @@ -23,7 +23,7 @@ "name": "Launch Main (Debug Memory)", "request": "launch", "mainClass": "electrosphere.engine.Main", - "vmArgs": "-Xmx4G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=3G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\" -javaagent:./lwjglx-debug-1.0.0.jar=t;o=trace.log", + "vmArgs": "-Xmx6G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=5G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\" -javaagent:./lwjglx-debug-1.0.0.jar=t;o=trace.log", "projectName": "Renderer", "preLaunchTask": "Install Native Lib" }, @@ -35,7 +35,7 @@ "env": { "ALSOFT_LOGLEVEL": 4 }, - "vmArgs": "-Xmx4G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=3G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", + "vmArgs": "-Xmx6G -Xms1024m -Djava.library.path=./shared-folder -XX:+UseZGC -XX:SoftMaxHeapSize=5G -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=\"./tmp/heap.hprof\"", "projectName": "Renderer" }, { diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 03eae528..fbe4e56f 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1392,6 +1392,8 @@ TransvoxelModelGeneration allocation reduction More allocation reduction Vector pooling Simplify WorldOctTree to reduce lag with large node counts +Increase memory allowance, mostly fixed latency while walking around +AssetManager streaming budget diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java index 8ebeb1d4..36e74b2b 100644 --- a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java +++ b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java @@ -78,6 +78,11 @@ public class AssetManager { //assets queued to be loaded ReentrantLock queuedAssetLock = new ReentrantLock(); List> queuedAssets = new LinkedList>(); + + /** + * Maximum number of queued assets that can be loaded per frame + */ + public static final int MAX_ASSETS_PER_FRAME = 50; @@ -174,15 +179,27 @@ public class AssetManager { LoggerInterface.loggerEngine.DEBUG_LOOP("AssetManager - Load queued assets"); Globals.profiler.beginCpuSample("AssetManager.loadAssetsInQueue - Load queued assets"); queuedAssetLock.lock(); - for(QueuedAsset queuedAsset : queuedAssets){ - queuedAsset.load(); - if(queuedAsset.get() instanceof Model){ - this.modelsLoadedIntoMemory.put(queuedAsset.getPromisedPath(),(Model)queuedAsset.get()); - } else if(queuedAsset.get() instanceof Texture){ - this.texturesLoadedIntoMemory.put(queuedAsset.getPromisedPath(),(Texture)queuedAsset.get()); + if(queuedAssets.size() > MAX_ASSETS_PER_FRAME){ + for(int i = 0; i < MAX_ASSETS_PER_FRAME; i++){ + QueuedAsset queuedAsset = queuedAssets.remove(0); + queuedAsset.load(); + if(queuedAsset.get() instanceof Model){ + this.modelsLoadedIntoMemory.put(queuedAsset.getPromisedPath(),(Model)queuedAsset.get()); + } else if(queuedAsset.get() instanceof Texture){ + this.texturesLoadedIntoMemory.put(queuedAsset.getPromisedPath(),(Texture)queuedAsset.get()); + } } + } else { + for(QueuedAsset queuedAsset : queuedAssets){ + queuedAsset.load(); + if(queuedAsset.get() instanceof Model){ + this.modelsLoadedIntoMemory.put(queuedAsset.getPromisedPath(),(Model)queuedAsset.get()); + } else if(queuedAsset.get() instanceof Texture){ + this.texturesLoadedIntoMemory.put(queuedAsset.getPromisedPath(),(Texture)queuedAsset.get()); + } + } + queuedAssets.clear(); } - queuedAssets.clear(); queuedAssetLock.unlock(); Globals.profiler.endCpuSample(); diff --git a/src/main/java/electrosphere/entity/scene/Scene.java b/src/main/java/electrosphere/entity/scene/Scene.java index 31595632..a2b2070b 100644 --- a/src/main/java/electrosphere/entity/scene/Scene.java +++ b/src/main/java/electrosphere/entity/scene/Scene.java @@ -9,7 +9,6 @@ import electrosphere.logger.LoggerInterface; import electrosphere.util.annotation.Exclude; import java.util.Collection; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; diff --git a/src/main/java/electrosphere/renderer/actor/Actor.java b/src/main/java/electrosphere/renderer/actor/Actor.java index 26f16b58..52efe6ab 100644 --- a/src/main/java/electrosphere/renderer/actor/Actor.java +++ b/src/main/java/electrosphere/renderer/actor/Actor.java @@ -5,6 +5,7 @@ import electrosphere.entity.state.AnimationPriorities; import electrosphere.game.data.common.treedata.TreeDataAnimation; import electrosphere.game.data.creature.type.bonegroups.BoneGroup; import electrosphere.logger.LoggerInterface; +import electrosphere.mem.VectorPool; import electrosphere.renderer.OpenGLState; import electrosphere.renderer.RenderPipelineState; import electrosphere.renderer.actor.ActorUniformMap.UniformValue; @@ -738,8 +739,9 @@ public class Actor { } Globals.profiler.beginAggregateCpuSample("Actor.isWithinFrustumBox"); Sphered sphere = model.getBoundingSphere(); - Vector3d modelPosition = model.getModelMatrix().getTranslation(new Vector3d()); + Vector3d modelPosition = model.getModelMatrix().getTranslation(VectorPool.getD()); boolean check = renderPipelineState.getFrustumIntersection().testSphere((float)(sphere.x + modelPosition.x), (float)(sphere.y + modelPosition.y), (float)(sphere.z + modelPosition.z), (float)sphere.r); + VectorPool.release(modelPosition); Globals.profiler.endCpuSample(); return check; } diff --git a/src/main/java/electrosphere/server/datacell/gridded/GriddedDataCellManager.java b/src/main/java/electrosphere/server/datacell/gridded/GriddedDataCellManager.java index 17a7a2d0..88ba719a 100644 --- a/src/main/java/electrosphere/server/datacell/gridded/GriddedDataCellManager.java +++ b/src/main/java/electrosphere/server/datacell/gridded/GriddedDataCellManager.java @@ -609,7 +609,7 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager Collection groundCells = this.groundDataCells.values(); boolean runMicroSim = Globals.microSimulation != null && Globals.microSimulation.isReady(); for(ServerDataCell cell : groundCells){ - if(runMicroSim){ + if(runMicroSim && this.shouldSimulate(cell)){ Globals.microSimulation.simulate(cell); } @@ -639,6 +639,15 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager Globals.profiler.endCpuSample(); } + /** + * Checks if a server data cell should be simulated or not + * @param cell The cell + * @return true if it should be simulated, false otherwise + */ + private boolean shouldSimulate(ServerDataCell cell){ + return cell.getPlayers().size() > 0; + } + /** * Gets the server terrain manager for this realm if it exists