Combined stages optimizations for bukkit 1.11

This commit is contained in:
Jesse Boyd 2016-12-29 10:19:48 +11:00
parent 5ffacaaf12
commit 8dba2a5620
No known key found for this signature in database
GPG Key ID: 59F1DE6293AF6E1F
3 changed files with 126 additions and 37 deletions

View File

@ -81,32 +81,26 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
if (sectionPalettes != null) {
copy.sectionPalettes = new DataPaletteBlock[16];
try {
Field fieldBits = DataPaletteBlock.class.getDeclaredField("b");
fieldBits.setAccessible(true);
Field fieldPalette = DataPaletteBlock.class.getDeclaredField("c");
fieldPalette.setAccessible(true);
Field fieldSize = DataPaletteBlock.class.getDeclaredField("e");
fieldSize.setAccessible(true);
for (int i = 0; i < sectionPalettes.length; i++) {
DataPaletteBlock current = sectionPalettes[i];
if (current == null) {
continue;
}
// Clone palette
DataPalette currentPalette = (DataPalette) fieldPalette.get(current);
DataPalette currentPalette = (DataPalette) BukkitQueue_1_11.fieldPalette.get(current);
if (!(currentPalette instanceof DataPaletteGlobal)) {
current.a(128, null);
}
DataPaletteBlock paletteBlock = newDataPaletteBlock();
currentPalette = (DataPalette) fieldPalette.get(current);
currentPalette = (DataPalette) BukkitQueue_1_11.fieldPalette.get(current);
if (!(currentPalette instanceof DataPaletteGlobal)) {
throw new RuntimeException("Palette must be global!");
}
fieldPalette.set(paletteBlock, currentPalette);
BukkitQueue_1_11.fieldPalette.set(paletteBlock, currentPalette);
// Clone size
fieldSize.set(paletteBlock, fieldSize.get(current));
BukkitQueue_1_11.fieldSize.set(paletteBlock, BukkitQueue_1_11.fieldSize.get(current));
// Clone palette
DataBits currentBits = (DataBits) fieldBits.get(current);
DataBits currentBits = (DataBits) BukkitQueue_1_11.fieldBits.get(current);
DataBits newBits = new DataBits(1, 0);
for (Field field : DataBits.class.getDeclaredFields()) {
field.setAccessible(true);
@ -116,7 +110,7 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
}
field.set(newBits, currentValue);
}
fieldBits.set(paletteBlock, newBits);
BukkitQueue_1_11.fieldBits.set(paletteBlock, newBits);
copy.sectionPalettes[i] = paletteBlock;
}
} catch (Throwable e) {

View File

@ -0,0 +1,62 @@
package com.boydti.fawe.bukkit.v1_11;
import com.boydti.fawe.object.FaweQueue;
public class BukkitChunk_1_11_Copy extends BukkitChunk_1_11 {
public final byte[][] idsBytes;
public final byte[][] datasBytes;
public BukkitChunk_1_11_Copy(FaweQueue parent, int x, int z) {
super(parent, x, z);
idsBytes = new byte[16][];
datasBytes = new byte[16][];
}
public void set(int i, byte[] ids, byte[] data) {
this.idsBytes[i] = ids;
this.datasBytes[i] = data;
}
@Override
public char[][] getCombinedIdArrays() {
for (int i = 0; i < ids.length; i++) {
getIdArray(i);
}
return super.getCombinedIdArrays();
}
@Override
public char[] getIdArray(int i) {
char[] combined = this.ids[i];
if (combined != null) {
return combined;
}
byte[] idsBytesArray = idsBytes[i];
if (idsBytesArray == null) {
return null;
}
byte[] datasBytesArray = datasBytes[i];
idsBytes[i] = null;
datasBytes[i] = null;
this.ids[i] = combined = new char[4096];
for (int j = 0, k = 0; j < 2048; j++, k += 2) {
combined[k] = (char) ((idsBytesArray[j] << 4) + (datasBytesArray[j] & 15));
}
for (int j = 0, k = 1; j < 2048; j++, k += 2) {
combined[k] = (char) ((idsBytesArray[j] << 4) + (datasBytesArray[j] >> 4));
}
return combined;
}
@Override
public void setBlock(int x, int y, int z, int id) {
throw new UnsupportedOperationException("This chunk is an immutable copy");
}
@Override
public void setBlock(int x, int y, int z, int id, int data) {
throw new UnsupportedOperationException("This chunk is an immutable copy");
}
}

View File

@ -25,7 +25,37 @@ import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ExecutorCompletionService;
import net.minecraft.server.v1_11_R1.*;
import net.minecraft.server.v1_11_R1.BiomeBase;
import net.minecraft.server.v1_11_R1.BiomeCache;
import net.minecraft.server.v1_11_R1.Block;
import net.minecraft.server.v1_11_R1.BlockPosition;
import net.minecraft.server.v1_11_R1.ChunkProviderGenerate;
import net.minecraft.server.v1_11_R1.ChunkProviderServer;
import net.minecraft.server.v1_11_R1.ChunkSection;
import net.minecraft.server.v1_11_R1.DataPaletteBlock;
import net.minecraft.server.v1_11_R1.Entity;
import net.minecraft.server.v1_11_R1.EntityPlayer;
import net.minecraft.server.v1_11_R1.EntityTracker;
import net.minecraft.server.v1_11_R1.EntityTypes;
import net.minecraft.server.v1_11_R1.EnumDifficulty;
import net.minecraft.server.v1_11_R1.EnumGamemode;
import net.minecraft.server.v1_11_R1.EnumSkyBlock;
import net.minecraft.server.v1_11_R1.IBlockData;
import net.minecraft.server.v1_11_R1.IDataManager;
import net.minecraft.server.v1_11_R1.MinecraftServer;
import net.minecraft.server.v1_11_R1.NBTTagCompound;
import net.minecraft.server.v1_11_R1.NibbleArray;
import net.minecraft.server.v1_11_R1.PacketPlayOutMapChunk;
import net.minecraft.server.v1_11_R1.PlayerChunk;
import net.minecraft.server.v1_11_R1.PlayerChunkMap;
import net.minecraft.server.v1_11_R1.ServerNBTManager;
import net.minecraft.server.v1_11_R1.TileEntity;
import net.minecraft.server.v1_11_R1.WorldChunkManager;
import net.minecraft.server.v1_11_R1.WorldData;
import net.minecraft.server.v1_11_R1.WorldManager;
import net.minecraft.server.v1_11_R1.WorldServer;
import net.minecraft.server.v1_11_R1.WorldSettings;
import net.minecraft.server.v1_11_R1.WorldType;
import org.bukkit.Bukkit;
import org.bukkit.Chunk;
import org.bukkit.World;
@ -42,6 +72,8 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
protected static IBlockData air;
protected static Field fieldBits;
protected static Field fieldPalette;
protected static Field fieldSize;
protected static Method getEntitySlices;
protected static Field fieldTickingBlockCount;
protected static Field fieldNonEmptyBlockCount;
@ -82,6 +114,11 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
fieldGenLayer1.setAccessible(true);
fieldGenLayer2.setAccessible(true);
fieldPalette = DataPaletteBlock.class.getDeclaredField("c");
fieldPalette.setAccessible(true);
fieldSize = DataPaletteBlock.class.getDeclaredField("e");
fieldSize.setAccessible(true);
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
fieldAir.setAccessible(true);
air = (IBlockData) fieldAir.get(null);
@ -189,9 +226,6 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
section.getEmittedLightArray().a(x & 15, y & 15, z & 15, value);
}
protected DataBits lastBits;
protected DataPaletteBlock lastBlocks;
@Override
public World createWorld(final WorldCreator creator) {
final String name = creator.name();
@ -470,37 +504,36 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
}
}
private static ThreadLocal<byte[]> ID_CACHE = new ThreadLocal<byte[]>() {
@Override
protected byte[] initialValue() {
return new byte[4096];
}
};
private static ThreadLocal<NibbleArray> DATA_CACHE = new ThreadLocal<NibbleArray>() {
@Override
protected NibbleArray initialValue() {
return new NibbleArray();
}
};
@Override
public BukkitChunk_1_11 getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
Map<BlockPosition, TileEntity> tiles = (Map<BlockPosition, TileEntity>) tilesGeneric;
Collection<Entity>[] entities = (Collection<Entity>[]) entitiesGeneric;
BukkitChunk_1_11 previous = getFaweChunk(fs.getX(), fs.getZ());
// Copy blocks
char[][] idPrevious = previous.getCombinedIdArrays();
BukkitChunk_1_11_Copy previous = new BukkitChunk_1_11_Copy(this, fs.getX(), fs.getZ());
for (int layer = 0; layer < sections.length; layer++) {
if (fs.getCount(layer) != 0 || all) {
ChunkSection section = sections[layer];
if (section != null) {
short solid = 0;
char[] previousLayer = idPrevious[layer] = new char[4096];
DataPaletteBlock blocks = section.getBlocks();
for (int j = 0; j < 4096; j++) {
int x = FaweCache.CACHE_X[0][j];
int y = FaweCache.CACHE_Y[0][j];
int z = FaweCache.CACHE_Z[0][j];
IBlockData ibd = blocks.a(x, y, z);
Block block = ibd.getBlock();
int combined = Block.getId(block);
if (FaweCache.hasData(combined)) {
combined = (combined << 4) + block.toLegacyData(ibd);
} else {
combined = combined << 4;
}
if (combined > 1) {
solid++;
}
previousLayer[j] = (char) combined;
}
byte[] ids = ID_CACHE.get();
NibbleArray data = DATA_CACHE.get();
blocks.exportData(ids, data);
previous.set(layer, ids, data.asBytes());
short solid = (short) fieldNonEmptyBlockCount.getInt(section);
previous.count[layer] = solid;
previous.air[layer] = (short) (4096 - solid);
}