Some optimizations for 1.13

This commit is contained in:
Jesse Boyd
2019-04-13 16:44:23 +10:00
parent 99c4c2f35d
commit f9f6aead0f
21 changed files with 1395 additions and 1308 deletions

View File

@ -1,62 +1,43 @@
package com.boydti.fawe;
import com.boydti.fawe.object.collection.IterableThreadLocal;
import com.sk89q.jnbt.*;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.lang.reflect.Field;
import java.util.*;
public class FaweCache {
/**
* [ y | z | x ] => index
*/
public final static short[][][] CACHE_I = new short[256][16][16];
/**
* [ y | z | x ] => index
*/
public final static short[][][] CACHE_J = new short[256][16][16];
public static final IterableThreadLocal<int[]> BLOCK_TO_PALETTE = new IterableThreadLocal<int[]>() {
@Override
public int[] init() {
int[] result = new int[BlockTypes.states.length];
Arrays.fill(result, Integer.MAX_VALUE);
return result;
}
};
/**
* [ i | j ] => x
*/
public final static byte[][] CACHE_X = new byte[16][];
/**
* [ i | j ] => y
*/
public final static short[][] CACHE_Y = new short[16][4096];
/**
* [ i | j ] => z
*/
public final static byte[][] CACHE_Z = new byte[16][];
public static final IterableThreadLocal<int[]> PALETTE_TO_BLOCK = new IterableThreadLocal<int[]>() {
@Override
public int[] init() {
return new int[Character.MAX_VALUE];
}
};
static {
CACHE_X[0] = new byte[4096];
CACHE_Z[0] = new byte[4096];
for (int y = 0; y < 16; y++) {
CACHE_X[y] = CACHE_X[0];
CACHE_Z[y] = CACHE_Z[0];
public static final IterableThreadLocal<long[]> BLOCK_STATES = new IterableThreadLocal<long[]>() {
@Override
public long[] init() {
return new long[2048];
}
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < 16; y++) {
final short j = (short) (((y & 0xF) << 8) | (z << 4) | x);
CACHE_X[0][j] = (byte) x;
CACHE_Z[0][j] = (byte) z;
}
}
};
public static final IterableThreadLocal<int[]> SECTION_BLOCKS = new IterableThreadLocal<int[]>() {
@Override
public int[] init() {
return new int[4096];
}
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = 0; y < 256; y++) {
final short i = (short) (y >> 4);
final short j = (short) (((y & 0xF) << 8) | (z << 4) | x);
CACHE_I[y][z][x] = i;
CACHE_J[y][z][x] = j;
CACHE_Y[i][j] = (short) y;
}
}
}
}
};
public static Map<String, Object> asMap(Object... pairs) {
HashMap<String, Object> map = new HashMap<>(pairs.length >> 1);

View File

@ -6,6 +6,7 @@ import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MathMan;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockID;
import com.sk89q.worldedit.world.block.BlockTypes;
import java.util.*;
@ -15,7 +16,6 @@ public abstract class IntFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
public final int[][] ids;
public final short[] count;
public final short[] air;
public final byte[] heightMap;
public BiomeType[] biomes;
public HashMap<Short, CompoundTag> tiles;
@ -24,12 +24,11 @@ public abstract class IntFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
public T chunk;
public IntFaweChunk(FaweQueue parent, int x, int z, int[][] ids, short[] count, short[] air, byte[] heightMap) {
public IntFaweChunk(FaweQueue parent, int x, int z, int[][] ids, short[] count, short[] air) {
super(parent, x, z);
this.ids = ids;
this.count = count;
this.air = air;
this.heightMap = heightMap;
}
/**
@ -44,7 +43,6 @@ public abstract class IntFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
this.ids = new int[HEIGHT >> 4][];
this.count = new short[HEIGHT >> 4];
this.air = new short[HEIGHT >> 4];
this.heightMap = new byte[256];
}
@Override
@ -136,12 +134,11 @@ public abstract class IntFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
@Override
public int getBlockCombinedId(int x, int y, int z) {
short i = FaweCache.CACHE_I[y][z][x];
int[] array = getIdArray(i);
int[] array = getIdArray(y >> 4);
if (array == null) {
return 0;
}
return array[FaweCache.CACHE_J[y][z][x]];
return array[(((y & 0xF) << 8) | (z << 4) | x)];
}
@Override
@ -195,19 +192,20 @@ public abstract class IntFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
@Override
public void setBlock(int x, int y, int z, int combinedId) {
final int i = FaweCache.CACHE_I[y][z][x];
final int j = FaweCache.CACHE_J[y][z][x];
final int i = y >> 4;
int[] vs = this.ids[i];
if (vs == null) {
vs = this.ids[i] = new int[4096];
}
vs[j] = combinedId;
vs[(((y & 15) << 8) | (z << 4) | x)] = combinedId;
this.count[i]++;
if (BlockTypes.getFromStateId(combinedId).getMaterial().isAir()) {
this.air[i]++;
return;
switch (combinedId) {
case 0:
case BlockID.AIR:
case BlockID.CAVE_AIR:
case BlockID.VOID_AIR:
this.air[i]++;
}
heightMap[z << 4 | x] = (byte) y;
return;
}

View File

@ -76,7 +76,8 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
byte[] fix = new byte[(maxY + 1) >> 4];
boolean sky = hasSky();
if (sky) {
for (int i = cfc.ids.length - 1; i >= 0; i--) {
int layers = FaweChunk.HEIGHT >> 4;
for (int i = layers - 1; i >= 0; i--) {
int air = cfc.getAir(i);
int solid = cfc.getCount(i);
if (air == 4096) {
@ -107,8 +108,6 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
}
}
public abstract void setHeightMap(FaweChunk chunk, byte[] heightMap);
public abstract void setFullbright(CHUNKSECTION sections);
public boolean removeLighting(CHUNKSECTION sections, RelightMode mode, boolean hasSky) {
@ -143,13 +142,12 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
if ((y < 0) || (y > maxY)) {
return BlockTypes.AIR.getInternalId();
}
final int i = FaweCache.CACHE_I[y][z][x];
final int i = y >> 4;
final char[] section = sections[i];
if (section == null) {
return 0;
}
final int j = FaweCache.CACHE_J[y][z][x];
return section[j] >> 4;
return section[(((y & 0xF) << 8) | (z << 4) | x)] >> 4;
}
public void saveChunk(CHUNK chunk) {

View File

@ -409,8 +409,8 @@ public class NMSRelighter implements Relighter {
}
}
byte[] cacheX = FaweCache.CACHE_X[0];
byte[] cacheZ = FaweCache.CACHE_Z[0];
// byte[] cacheX = FaweCache.CACHE_X[0];
// byte[] cacheZ = FaweCache.CACHE_Z[0];
for (int y = FaweChunk.HEIGHT - 1; y > 0; y--) {
for (RelightSkyEntry chunk : chunks) { // Propogate skylight
int layer = y >> 4;
@ -434,58 +434,58 @@ public class NMSRelighter implements Relighter {
queue.removeSectionLighting(section, y >> 4, true);
}
for (int j = 0; j <= maxY; j++) {
int x = cacheX[j];
int z = cacheZ[j];
byte value = mask[j];
byte pair = (byte) queue.getOpacityBrightnessPair(section, x, y, z);
int opacity = MathMan.unpair16x(pair);
int brightness = MathMan.unpair16y(pair);
if (brightness > 1 && (brightness != 15 || opacity != 15)) {
addLightUpdate(bx + x, y, bz + z);
}
switch (value) {
case 0:
if (opacity > 1) {
queue.setSkyLight(section, x, y, z, 0);
for (int z = 0, j = 0; z < 16; z++) {
for (int x = 0; x < 16; x++, j++) {
byte value = mask[j];
byte pair = (byte) queue.getOpacityBrightnessPair(section, x, y, z);
int opacity = MathMan.unpair16x(pair);
int brightness = MathMan.unpair16y(pair);
if (brightness > 1 && (brightness != 15 || opacity != 15)) {
addLightUpdate(bx + x, y, bz + z);
}
switch (value) {
case 0:
if (opacity > 1) {
queue.setSkyLight(section, x, y, z, 0);
continue;
}
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
if (opacity >= value) {
mask[j] = 0;
queue.setSkyLight(section, x, y, z, 0);
continue;
}
if (opacity <= 1) {
mask[j] = --value;
} else {
mask[j] = value = (byte) Math.max(0, value - opacity);
}
break;
case 15:
if (opacity > 1) {
value -= opacity;
mask[j] = value;
}
queue.setSkyLight(section, x, y, z, value);
continue;
}
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
if (opacity >= value) {
mask[j] = 0;
queue.setSkyLight(section, x, y, z, 0);
continue;
}
if (opacity <= 1) {
mask[j] = --value;
} else {
mask[j] = value = (byte) Math.max(0, value - opacity);
}
break;
case 15:
if (opacity > 1) {
value -= opacity;
mask[j] = value;
}
queue.setSkyLight(section, x, y, z, value);
continue;
}
chunk.smooth = true;
queue.setSkyLight(section, x, y, z, value);
}
chunk.smooth = true;
queue.setSkyLight(section, x, y, z, value);
}
queue.saveChunk(chunkObj);
}

View File

@ -9,8 +9,8 @@ public class NullQueueIntFaweChunk extends IntFaweChunk {
super(null, cx, cz);
}
public NullQueueIntFaweChunk(int x, int z, int[][] ids, short[] count, short[] air, byte[] heightMap) {
super(null, x, z, ids, count, air, heightMap);
public NullQueueIntFaweChunk(int x, int z, int[][] ids, short[] count, short[] air) {
super(null, x, z, ids, count, air);
}
@Override
@ -21,9 +21,9 @@ public class NullQueueIntFaweChunk extends IntFaweChunk {
@Override
public IntFaweChunk copy(boolean shallow) {
if (shallow) {
return new NullQueueIntFaweChunk(getX(), getZ(), ids, count, air, heightMap);
return new NullQueueIntFaweChunk(getX(), getZ(), ids, count, air);
} else {
return new NullQueueIntFaweChunk(getX(), getZ(), (int[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
return new NullQueueIntFaweChunk(getX(), getZ(), (int[][]) MainUtil.copyNd(ids), count.clone(), air.clone());
}
}

View File

@ -10,8 +10,8 @@ public class SimpleIntFaweChunk extends IntFaweChunk {
super(parent, x, z);
}
public SimpleIntFaweChunk(FaweQueue parent, int x, int z, int[][] ids, short[] count, short[] air, byte[] heightMap) {
super(parent, x, z, ids, count, air, heightMap);
public SimpleIntFaweChunk(FaweQueue parent, int x, int z, int[][] ids, short[] count, short[] air) {
super(parent, x, z, ids, count, air);
}
@Override
@ -23,10 +23,10 @@ public class SimpleIntFaweChunk extends IntFaweChunk {
public IntFaweChunk copy(boolean shallow) {
SimpleIntFaweChunk copy;
if (shallow) {
copy = new SimpleIntFaweChunk(getParent(), getX(), getZ(), ids, count, air, heightMap);
copy = new SimpleIntFaweChunk(getParent(), getX(), getZ(), ids, count, air);
copy.biomes = biomes;
} else {
copy = new SimpleIntFaweChunk(getParent(), getX(), getZ(), (int[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
copy = new SimpleIntFaweChunk(getParent(), getX(), getZ(), (int[][]) MainUtil.copyNd(ids), count.clone(), air.clone());
copy.biomes = biomes != null ? biomes.clone() : null;
}
return copy;
@ -37,4 +37,4 @@ public class SimpleIntFaweChunk extends IntFaweChunk {
getParent().setChunk(this);
return this;
}
}
}

View File

@ -69,15 +69,14 @@ public final class BitArray4096 {
}
}
public final void fromRaw(int[] arr, int offset) {
public final void fromRaw(int[] arr) {
final long[] data = this.data;
final int bitsPerEntry = this.bitsPerEntry;
final int maxEntryValue = this.maxEntryValue;
final int maxSeqLocIndex = this.maxSeqLocIndex;
int localStart = 0;
int lastVal;
int arrI = offset;
int arrI = 0;
long l = 0;
long nextVal;
for (int i = 0; i < longLen; i++) {
@ -123,11 +122,11 @@ public final class BitArray4096 {
return arr;
}
public final char[] toRaw() {
return toRaw(new char[4096]);
public final int[] toRaw() {
return toRaw(new int[4096]);
}
protected final char[] toRaw(char[] buffer) {
public final int[] toRaw(int[] buffer) {
final long[] data = this.data;
final int dataLength = longLen;
final int bitsPerEntry = this.bitsPerEntry;

View File

@ -597,8 +597,7 @@ public class MCAChunk extends FaweChunk<Void> {
if (idLayer == null) {
return 0;
}
int j = FaweCache.CACHE_J[y][z & 15][x & 15];
return idLayer[j];
return idLayer[(((y & 15) << 8) | ((z & 15) << 4) | (x & 15))];
}
@Override
@ -627,8 +626,7 @@ public class MCAChunk extends FaweChunk<Void> {
if (skyLayer == null) {
return;
}
int index = FaweCache.CACHE_J[y][z & 15][x & 15];
setNibble(index, skyLayer, value);
setNibble((((y & 15) << 8) | ((z & 15) << 4) | (x & 15)), skyLayer, value);
}
public void setBlockLight(int x, int y, int z, int value) {
@ -638,8 +636,7 @@ public class MCAChunk extends FaweChunk<Void> {
if (blockLayer == null) {
return;
}
int index = FaweCache.CACHE_J[y][z & 15][x & 15];
setNibble(index, blockLayer, value);
setNibble((((y & 15) << 8) | ((z & 15) << 4) | (x & 15)), blockLayer, value);
}
public int getSkyLight(int x, int y, int z) {
@ -648,8 +645,7 @@ public class MCAChunk extends FaweChunk<Void> {
if (skyLayer == null) {
return 0;
}
int index = FaweCache.CACHE_J[y][z & 15][x & 15];
return getNibble(index, skyLayer);
return getNibble((((y & 15) << 8) | ((z & 15) << 4) | (x & 15)), skyLayer);
}
public int getBlockLight(int x, int y, int z) {
@ -658,8 +654,7 @@ public class MCAChunk extends FaweChunk<Void> {
if (blockLayer == null) {
return 0;
}
int index = FaweCache.CACHE_J[y][z & 15][x & 15];
return getNibble(index, blockLayer);
return getNibble((((y & 15) << 8) | ((z & 15) << 4) | (x & 15)), blockLayer);
}
public void setFullbright() {
@ -729,8 +724,7 @@ public class MCAChunk extends FaweChunk<Void> {
this.skyLight[layer] = new byte[2048];
this.blockLight[layer] = new byte[2048];
}
int j = FaweCache.CACHE_J[y][z & 15][x & 15];
idsLayer[j] = combinedId;
idsLayer[(((y & 15) << 8) | ((z & 15) << 4) | (x & 15))] = combinedId;
}
@Override

View File

@ -652,21 +652,6 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
return parent;
}
@Override
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
MCAChunk mca = (MCAChunk) chunk;
if (mca != null) {
int[] otherMap = mca.getHeightMapArray();
for (int i = 0; i < heightMap.length; i++) {
int newHeight = heightMap[i] & 0xFF;
int currentHeight = otherMap[i];
if (newHeight > currentHeight) {
otherMap[i] = newHeight;
}
}
}
}
@Override
public void setFullbright(FaweChunk sections) {
if (sections.getClass() == MCAChunk.class) {

View File

@ -1,5 +1,6 @@
package com.boydti.fawe.jnbt.anvil;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.io.FastByteArrayOutputStream;
import com.boydti.fawe.util.MathMan;
@ -81,14 +82,12 @@ public class WritableMCAChunk extends FaweChunk<Void> {
Arrays.fill(hasSections, false);
}
private transient final int[] blockToPalette = new int[BlockTypes.states.length];
{
Arrays.fill(blockToPalette, Integer.MAX_VALUE);
}
private transient final int[] paletteToBlock = new int[Character.MAX_VALUE];
private transient final long[] blockstates = new long[2048];
public void write(NBTOutputStream nbtOut) throws IOException {
int[] blockToPalette = FaweCache.BLOCK_TO_PALETTE.get();
int[] paletteToBlock = FaweCache.PALETTE_TO_BLOCK.get();
long[] blockstates = FaweCache.BLOCK_STATES.get();
int[] blocksCopy = FaweCache.SECTION_BLOCKS.get();
nbtOut.writeNamedTagName("", NBTConstants.TYPE_COMPOUND);
nbtOut.writeNamedTag("DataVersion", 1631);
nbtOut.writeLazyCompoundTag("Level", out -> {
@ -128,7 +127,7 @@ public class WritableMCAChunk extends FaweChunk<Void> {
int blockIndexEnd = blockIndexStart + 4096;
int num_palette = 0;
try {
for (int i = blockIndexStart; i < blockIndexEnd; i++) {
for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) {
int stateId = blocks[i];
int ordinal = BlockState.getFromInternalId(stateId).getOrdinal(); // TODO fixme Remove all use of BlockTypes.BIT_OFFSET so that this conversion isn't necessary
int palette = blockToPalette[ordinal];
@ -138,7 +137,7 @@ public class WritableMCAChunk extends FaweChunk<Void> {
paletteToBlock[num_palette] = ordinal;
num_palette++;
}
blocks[i] = palette;
blocksCopy[j] = palette;
}
for (int i = 0; i < num_palette; i++) {
@ -184,7 +183,7 @@ public class WritableMCAChunk extends FaweChunk<Void> {
blockBitArrayEnd = 1;
} else {
BitArray4096 bitArray = new BitArray4096(blockstates, bitsPerEntry);
bitArray.fromRaw(blocks, blockIndexStart);
bitArray.fromRaw(blocksCopy);
}
out.writeNamedTagName("BlockStates", NBTConstants.TYPE_LONG_ARRAY);

View File

@ -68,4 +68,4 @@ public class MutableChunkChange implements Change {
queue.setChunk(to);
}
}
}
}