Lighting / MCA changes / Queue

Optimize queue dispatch parallelization
Fix lighting issues
Add MCAFile/Chunk listing to API
This commit is contained in:
Jesse Boyd 2016-08-23 16:25:31 +10:00
parent 39158816cf
commit 3e0852d589
12 changed files with 108 additions and 84 deletions

View File

@ -120,22 +120,6 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
private DataBits lastBits;
private DataPaletteBlock lastBlocks;
@Override
public boolean hasBlock(ChunkSection section, int x, int y, int z) {
DataPaletteBlock dataPaletteBlock = section.getBlocks();
try {
if (lastBlocks != dataPaletteBlock) {
lastBits = (DataBits) fieldBits.get(dataPaletteBlock);
lastBlocks = dataPaletteBlock;
}
int i = FaweCache.CACHE_J[y][z & 15][x & 15];
return lastBits.a(i) != 0;
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
}
@Override
public World createWorld(final WorldCreator creator) {
final String name = creator.name();

View File

@ -754,22 +754,6 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
private DataBits lastBits;
private DataPaletteBlock lastBlocks;
@Override
public boolean hasBlock(ChunkSection section, int x, int y, int z) {
DataPaletteBlock dataPaletteBlock = section.getBlocks();
try {
if (lastBlocks != dataPaletteBlock) {
lastBits = (DataBits) fieldBits.get(dataPaletteBlock);
lastBlocks = dataPaletteBlock;
}
int i = FaweCache.CACHE_J[y][z & 15][x & 15];
return lastBits.a(i) != 0;
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
}
@Override
public void relightBlock(int x, int y, int z) {
pos.c(x, y, z);

View File

@ -144,7 +144,8 @@ public abstract class CharFaweChunk<T> extends FaweChunk<T> {
return this.biomes;
}
public int getCombinedId(int x, int y, int z) {
@Override
public int getBlockCombinedId(int x, int y, int z) {
short i = FaweCache.CACHE_I[y][z][x];
char[] array = getIdArray(i);
if (array == null) {

View File

@ -4,6 +4,7 @@ import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag;
import java.util.Collection;
import java.util.Map;
@ -27,7 +28,12 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
@Override
public void run() {
if (relighter != null) {
relighter.fixLightingSafe(hasSky());
TaskManager.IMP.taskNowAsync(new Runnable() {
@Override
public void run() {
relighter.fixLightingSafe(hasSky());
}
});
}
}
});

View File

@ -2,6 +2,7 @@ package com.boydti.fawe.example;
import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import java.util.ArrayDeque;
import java.util.ArrayList;
@ -59,11 +60,12 @@ public class NMSRelighter {
}
public void smoothBlockLight(int emit, int x, int y, int z, int rx, int ry, int rz) {
if (queue.hasBlock(rx, ry, rz)) {
int opacity = queue.getOpacity(rx, ry, rz);
if (opacity >= emit) {
return;
}
int emitAdjacent = queue.getEmmittedLight(rx, ry, rz);
if (emit - emitAdjacent > 2) {
if (emit - emitAdjacent > 1) {
queue.setBlockLight(rx, ry, rz, emit - 1);
addBlock(rx, ry, rz);
}
@ -100,7 +102,7 @@ public class NMSRelighter {
int xx = bx + x;
int zz = bz + z;
int emit = queue.getEmmittedLight(xx, y, zz);
if (emit < 2) {
if (emit < 1) {
continue;
}
smoothBlockLight(emit, xx, y, zz, xx - 1, y, zz);
@ -119,6 +121,7 @@ public class NMSRelighter {
}
public void sendChunks() {
MainUtil.stacktrace();
for (Map.Entry<Long, RelightSkyEntry> entry : skyToRelight.entrySet()) {
RelightSkyEntry chunk = entry.getValue();
CharFaweChunk fc = (CharFaweChunk) queue.getFaweChunk(chunk.x, chunk.z);
@ -134,14 +137,18 @@ public class NMSRelighter {
}
private boolean isTransparent(int x, int y, int z) {
return FaweCache.isTransparent(FaweCache.getId(queue.getCombinedId4Data(x, y, z)));
}
public void lightBlock(int x, int y, int z, int brightness) {
queue.setBlockLight(x, y, z, Math.max(15, brightness + 1));
if (!queue.hasBlock(x - 1, y, z)) { queue.setBlockLight(x - 1, y, z, brightness); addBlock(x - 1, y, z); }
if (!queue.hasBlock(x + 1, y, z)) { queue.setBlockLight(x + 1, y, z, brightness); addBlock(x + 1, y, z); }
if (!queue.hasBlock(x, y, z - 1)) { queue.setBlockLight(x, y, z - 1, brightness); addBlock(x, y, z - 1); }
if (!queue.hasBlock(x, y, z + 1)) { queue.setBlockLight(x, y, z + 1, brightness); addBlock(x, y, z + 1); }
if (y > 0 && !queue.hasBlock(x, y - 1, z)) { queue.setBlockLight(x, y - 1, z, brightness); addBlock(x, y - 1, z); }
if (y < 255 && !queue.hasBlock(x, y + 1, z)) { queue.setBlockLight(x, y + 1, z, brightness); addBlock(x, y + 1, z); }
if (isTransparent(x - 1, y, z)) { queue.setBlockLight(x - 1, y, z, brightness); addBlock(x - 1, y, z); }
if (isTransparent(x + 1, y, z)) { queue.setBlockLight(x + 1, y, z, brightness); addBlock(x + 1, y, z); }
if (isTransparent(x, y, z - 1)) { queue.setBlockLight(x, y, z - 1, brightness); addBlock(x, y, z - 1); }
if (isTransparent(x, y, z + 1)) { queue.setBlockLight(x, y, z + 1, brightness); addBlock(x, y, z + 1); }
if (y > 0 && isTransparent(x, y - 1, z)) { queue.setBlockLight(x, y - 1, z, brightness); addBlock(x, y - 1, z); }
if (y < 255 && isTransparent(x, y + 1, z)) { queue.setBlockLight(x, y + 1, z, brightness); addBlock(x, y + 1, z); }
}
public void fixSkyLighting() {
@ -210,13 +217,13 @@ public class NMSRelighter {
case 10:
case 12:
case 14:
if (opacity == 0) {
mask[j] = --value;
} else {
mask[j] = (byte) Math.max(0, value - opacity);
}
queue.setSkyLight(section, x, y, z, value);
continue;
// if (opacity == 0) {
// mask[j] = --value;
// } else {
// mask[j] = (byte) Math.max(0, value - opacity);
// }
// queue.setSkyLight(section, x, y, z, value);
// continue;
case 1:
case 3:
case 5:

View File

@ -33,6 +33,11 @@ public class NullFaweChunk extends FaweChunk<Void> {
return 0;
}
@Override
public int getBlockCombinedId(int x, int y, int z) {
return 0;
}
@Override
public Void getChunk() {
return null;

View File

@ -191,6 +191,8 @@ public class MCAChunk extends FaweChunk<Void> {
streamer.readFully();
}
public boolean isModified() {
return modified;
}
@ -390,9 +392,4 @@ public class MCAChunk extends FaweChunk<Void> {
public Void getChunk() {
throw new UnsupportedOperationException("Not applicable for this");
}
@Override
public char[][] getCombinedIdArrays() {
throw new UnsupportedOperationException("Not applicable for this");
}
}

View File

@ -121,6 +121,21 @@ public class MCAFile {
}
}
public void forEachChunk(RunnableVal<MCAChunk> onEach) {
int i = 0;
for (int z = 0; z < 32; z++) {
for (int x = 0; x < 32; x++, i += 4) {
int offset = (((locations[i] & 0xFF) << 16) + ((locations[i + 1] & 0xFF) << 8) + ((locations[i+ 2] & 0xFF)));
int size = locations[i + 3] & 0xFF;
if (size != 0) {
try {
onEach.run(getChunk(x, z));
} catch (Throwable ignore) {}
}
}
}
}
public int getOffset(int cx, int cz) {
int i = ((cx & 31) << 2) + ((cz & 31) << 7);
int offset = (((locations[i] & 0xFF) << 16) + ((locations[i + 1] & 0xFF) << 8) + ((locations[i+ 2] & 0xFF)));

View File

@ -8,6 +8,7 @@ import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.MathMan;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
@ -34,6 +35,15 @@ public class MCAQueueMap implements IFaweQueueMap {
private int lastFileX = Integer.MIN_VALUE;
private int lastFileZ = Integer.MIN_VALUE;
public void forEachMCAFile(RunnableVal<MCAFile> onEach) {
File folder = queue.getSaveFolder();
for (File file : folder.listFiles()) {
try {
onEach.run(new MCAFile(queue, file));
} catch (Throwable ignore) {}
}
}
public MCAFile getMCAFile(int cx, int cz) {
int mcaX = cx >> 5;
int mcaZ = cz >> 5;

View File

@ -77,21 +77,6 @@ public abstract class FaweChunk<T> {
parent.setChunk(this);
}
/**
* This may return the raw value or constructed depending on the implementation<br>
* - The first index (i) is the layer (layer = y >> 4) (16 layers)<br>
* - The second array is length 4096 and contains the combined ids (cast to an int if you want)
*
* @see com.boydti.fawe.FaweCache#CACHE_I
* @see com.boydti.fawe.FaweCache#CACHE_J
* @see com.boydti.fawe.FaweCache#CACHE_X
* @see com.boydti.fawe.FaweCache#CACHE_Y
* @see com.boydti.fawe.FaweCache#CACHE_Z
*
* @return Combined id arrays
*/
public abstract char[][] getCombinedIdArrays();
/**
* The modified sections
* @return
@ -106,10 +91,30 @@ public abstract class FaweChunk<T> {
* @param z
* @return The combined id
*/
public int getBlockCombinedId(int x, int y, int z) {
char[][] arrays = getCombinedIdArrays();
char[] array = arrays[y >> 4];
return array != null ? (array[FaweCache.CACHE_J[y][z][x]]) : 0;
public abstract int getBlockCombinedId(int x, int y, int z);
public char[][] getCombinedIdArrays() {
char[][] ids = new char[16][];
for (int y = 0; y < 16; y++) {
int y4 = y >> 4;
short[][] i1 = FaweCache.CACHE_J[y];
for (int z = 0; z < 16; z++) {
short[] i2 = i1[z];
for (int x = 0; x < 16; x++) {
int combined = getBlockCombinedId(x, y, z);
if (combined == 0) {
continue;
}
char[] array = ids[y4];
if (array == null) {
array = ids[y4] = new char[4096];
}
int index = i2[x];
array[index] = (char) combined;
}
}
}
return ids;
}
/**

View File

@ -100,9 +100,9 @@ public class SetQueue {
if (Settings.QUEUE.PARALLEL_THREADS <= 1) {
SET_TASK.run();
} else {
ArrayList<Thread> threads = new ArrayList<Thread>();
Thread[] threads = new Thread[Settings.QUEUE.PARALLEL_THREADS];
for (int i = 0; i < Settings.QUEUE.PARALLEL_THREADS; i++) {
threads.add(new Thread(SET_TASK));
threads[i] = (new Thread(SET_TASK));
}
for (Thread thread : threads) {
thread.start();
@ -198,9 +198,9 @@ public class SetQueue {
if (!parallel) {
SET_TASK.run();
} else {
ArrayList<Thread> threads = new ArrayList<Thread>();
Thread[] threads = new Thread[Settings.QUEUE.PARALLEL_THREADS];
for (int i = 0; i < Settings.QUEUE.PARALLEL_THREADS; i++) {
threads.add(new Thread(SET_TASK));
threads[i] = (new Thread(SET_TASK));
}
for (Thread thread : threads) {
thread.start();

View File

@ -129,20 +129,30 @@ public abstract class TaskManager {
}
/**
* Run a task as soon as possible on the main thread, or now async
* Run a task as soon as possible on the main thread
* - Non blocking if not calling from the main thread
* @param r
* @param async
*/
public void taskNowMain(final Runnable r, boolean async) {
if (async) {
async(r);
} else if (r != null && Thread.currentThread() == Fawe.get().getMainThread()){
public void taskNowMain(final Runnable r) {
if (r == null) {
return;
}
if (Thread.currentThread() == Fawe.get().getMainThread()){
r.run();
} else {
task(r);
}
}
/**
* Run a task as soon as possible not on the main thread
* @see com.boydti.fawe.Fawe#isMainThread()
* @param r
*/
public void taskNowAsync(final Runnable r) {
taskNow(r, Fawe.get().isMainThread());
}
/**
* Run a task on the main thread at the next tick or now async
* @param r