Cache arrays used by RenderableBoxGroup
This commit is contained in:
+91
@@ -0,0 +1,91 @@
|
||||
package com.seibel.distanthorizons.core.render.renderer.generic;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.RemovalNotification;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
/**
|
||||
* @see RenderableBoxGroup
|
||||
*/
|
||||
public class RenderBoxArrayCache
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
public static final int ARRAY_LENGTH_WIDTH = 24;
|
||||
public static final int ARRAY_ID_WIDTH = 8;
|
||||
|
||||
public static final int ARRAY_LENGTH_OFFSET = 0;
|
||||
public static final int ARRAY_ID_OFFSET = ARRAY_LENGTH_OFFSET + ARRAY_LENGTH_WIDTH;
|
||||
|
||||
public static final int ARRAY_LENGTH_MASK = (int) Math.pow(2, ARRAY_LENGTH_WIDTH) - 1;
|
||||
public static final int ARRAY_ID_MASK = (int) Math.pow(2, ARRAY_ID_WIDTH) - 1;
|
||||
|
||||
|
||||
private static final ConcurrentMap<Integer, float[]> FLOAT_ARRAY_BY_KEY = CacheBuilder.newBuilder()
|
||||
// This number needs to be high enough so that
|
||||
// the number of generic object groups won't cause array thrashing.
|
||||
// For now 512 should be way more than needed, unless
|
||||
// someone adds a boatload of random generic objects.
|
||||
.maximumSize(512)
|
||||
.removalListener((RemovalNotification<Integer, float[]> notification) -> { /* TODO log a warning if arrays start getting removed, that means we may need to re-think how the caching here works */ })
|
||||
.build().asMap();
|
||||
private static final ConcurrentMap<Integer, int[]> INT_ARRAY_BY_KEY = CacheBuilder.newBuilder()
|
||||
.maximumSize(512)
|
||||
.removalListener((RemovalNotification<Integer, int[]> notification) -> {})
|
||||
.build().asMap();
|
||||
|
||||
|
||||
|
||||
//============//
|
||||
// get arrays //
|
||||
//============//
|
||||
|
||||
/**
|
||||
* The ID parameter is to prevent returning the same array
|
||||
* multiple times when the same length is requested.
|
||||
*/
|
||||
public static float[] getCachedFloatArray(int length, int id)
|
||||
{
|
||||
int key = encodeKey(length, id);
|
||||
return FLOAT_ARRAY_BY_KEY.computeIfAbsent(key, (newKey) ->
|
||||
{
|
||||
int newLength = getLengthFromKey(newKey);
|
||||
return new float[newLength];
|
||||
});
|
||||
}
|
||||
public static int[] getCachedIntArray(int length, int id)
|
||||
{
|
||||
int key = encodeKey(length, id);
|
||||
return INT_ARRAY_BY_KEY.computeIfAbsent(key, (newKey) ->
|
||||
{
|
||||
int newLength = getLengthFromKey(newKey);
|
||||
return new int[newLength];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// key encoding //
|
||||
//==============//
|
||||
|
||||
private static int encodeKey(int arrayLength, int id)
|
||||
{
|
||||
if (id > Byte.MAX_VALUE)
|
||||
{
|
||||
throw new IndexOutOfBoundsException("The array's ID can only be 8 bytes long.");
|
||||
}
|
||||
|
||||
int data = 0;
|
||||
data |= (arrayLength & ARRAY_LENGTH_MASK);
|
||||
data |= (id & ARRAY_ID_MASK) << ARRAY_ID_OFFSET;
|
||||
return data;
|
||||
}
|
||||
|
||||
private static int getLengthFromKey(int key) { return (key & ARRAY_LENGTH_MASK); }
|
||||
private static int getIdFromKey(int key) { return ((key >> ARRAY_ID_OFFSET) & ARRAY_ID_MASK); }
|
||||
|
||||
}
|
||||
+6
-6
@@ -24,7 +24,7 @@ public class RenderableBoxGroup
|
||||
extends AbstractList<DhApiRenderableBox>
|
||||
implements IDhApiRenderableBoxGroup, Closeable
|
||||
{
|
||||
public final static AtomicInteger NEXT_ID_ATOMIC_INT = new AtomicInteger(0);
|
||||
public static final AtomicInteger NEXT_ID_ATOMIC_INT = new AtomicInteger(0);
|
||||
|
||||
|
||||
|
||||
@@ -247,9 +247,9 @@ public class RenderableBoxGroup
|
||||
|
||||
|
||||
// transformation / scaling //
|
||||
int[] chunkPosData = new int[boxCount * 3];
|
||||
float[] subChunkPosData = new float[boxCount * 3];
|
||||
float[] scalingData = new float[boxCount * 3];
|
||||
int[] chunkPosData = RenderBoxArrayCache.getCachedIntArray(boxCount * 3, 0);
|
||||
float[] subChunkPosData = RenderBoxArrayCache.getCachedFloatArray(boxCount * 3, 1);
|
||||
float[] scalingData = RenderBoxArrayCache.getCachedFloatArray(boxCount * 3, 2);
|
||||
for (int i = 0; i < boxCount; i++)
|
||||
{
|
||||
DhApiRenderableBox box = this.get(i);
|
||||
@@ -272,8 +272,8 @@ public class RenderableBoxGroup
|
||||
|
||||
|
||||
// colors/materials //
|
||||
float[] colorData = new float[boxCount * 4];
|
||||
int[] materialData = new int[boxCount];
|
||||
float[] colorData = RenderBoxArrayCache.getCachedFloatArray(boxCount * 4, 3);
|
||||
int[] materialData = RenderBoxArrayCache.getCachedIntArray(boxCount, 4);
|
||||
for (int i = 0; i < boxCount; i++)
|
||||
{
|
||||
DhApiRenderableBox box = this.get(i);
|
||||
|
||||
Reference in New Issue
Block a user