Improve light optimizations and fix bugs
Rewrites the Threaded task logic to no longer use 2 queues and instead keep a single prioritized queue and do all of a chunks light tasks in a single batch Fix a math issue in one place (Thankfully didn't seem to really be a common place since didn't notice anything)
This commit is contained in:
parent
9ffaa44ae1
commit
92d1247ee3
2 changed files with 371 additions and 193 deletions
|
@ -57,7 +57,7 @@ index 3bf17ccdaef21322b787db538d569e0bc614ef22..4c64798fbc50f4d8b08502ba865c5fde
|
|||
|
||||
public static long f(long i) {
|
||||
diff --git a/src/main/java/net/minecraft/server/SectionPosition.java b/src/main/java/net/minecraft/server/SectionPosition.java
|
||||
index ca3f63f5e5e4e926de562b4bfbbf72ad8a6b943f..c415736282de6d4d0f87135c24999c4bbf993901 100644
|
||||
index ca3f63f5e5e4e926de562b4bfbbf72ad8a6b943f..22bc96f97d22e0748110982e4b1ff85002f924b5 100644
|
||||
--- a/src/main/java/net/minecraft/server/SectionPosition.java
|
||||
+++ b/src/main/java/net/minecraft/server/SectionPosition.java
|
||||
@@ -16,7 +16,7 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
|
@ -69,7 +69,7 @@ index ca3f63f5e5e4e926de562b4bfbbf72ad8a6b943f..c415736282de6d4d0f87135c24999c4b
|
|||
}
|
||||
|
||||
public static SectionPosition a(ChunkCoordIntPair chunkcoordintpair, int i) {
|
||||
@@ -28,7 +28,7 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
@@ -28,15 +28,23 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public static SectionPosition a(long i) {
|
||||
|
@ -78,16 +78,24 @@ index ca3f63f5e5e4e926de562b4bfbbf72ad8a6b943f..c415736282de6d4d0f87135c24999c4b
|
|||
}
|
||||
|
||||
public static long a(long i, EnumDirection enumdirection) {
|
||||
@@ -36,7 +36,7 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
return a(i, enumdirection.getAdjacentX(), enumdirection.getAdjacentY(), enumdirection.getAdjacentZ());
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static long getAdjacentFromBlockPos(int x, int y, int z, EnumDirection enumdirection) {
|
||||
+ return (((long) ((x >> 4) + enumdirection.getAdjacentX()) & 4194303L) << 42) | (((long) ((y >> 4) + enumdirection.getAdjacentY()) & 1048575L)) | (((long) ((z >> 4) + enumdirection.getAdjacentZ()) & 4194303L) << 20);
|
||||
+ }
|
||||
+ public static long getAdjacentFromSectionPos(int x, int y, int z, EnumDirection enumdirection) {
|
||||
+ return (((long) (x + enumdirection.getAdjacentX()) & 4194303L) << 42) | (((long) ((y) + enumdirection.getAdjacentY()) & 1048575L)) | (((long) (z + enumdirection.getAdjacentZ()) & 4194303L) << 20);
|
||||
+ }
|
||||
+ // Paper end
|
||||
public static long a(long i, int j, int k, int l) {
|
||||
- return b(b(i) + j, c(i) + k, d(i) + l);
|
||||
+ return (((long) ((int) (i >> 42) + j) & 4194303L) << 42) | (((long) ((int) (i << 44 >> 44) + k) & 1048575L)) | (((long) ((int) (i << 22 >> 42) + l) & 4194303L) << 20); // Simplify to reduce instruction count
|
||||
}
|
||||
|
||||
public static int a(int i) {
|
||||
@@ -48,11 +48,7 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
@@ -48,11 +56,7 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public static short b(BlockPosition blockposition) {
|
||||
|
@ -100,7 +108,7 @@ index ca3f63f5e5e4e926de562b4bfbbf72ad8a6b943f..c415736282de6d4d0f87135c24999c4b
|
|||
}
|
||||
|
||||
public static int c(int i) {
|
||||
@@ -60,7 +56,7 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
@@ -60,7 +64,7 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public static int b(long i) {
|
||||
|
@ -109,7 +117,7 @@ index ca3f63f5e5e4e926de562b4bfbbf72ad8a6b943f..c415736282de6d4d0f87135c24999c4b
|
|||
}
|
||||
|
||||
public static int c(long i) {
|
||||
@@ -71,44 +67,46 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
@@ -71,44 +75,46 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
return (int) (i << 22 >> 42);
|
||||
}
|
||||
|
||||
|
@ -175,7 +183,7 @@ index ca3f63f5e5e4e926de562b4bfbbf72ad8a6b943f..c415736282de6d4d0f87135c24999c4b
|
|||
}
|
||||
|
||||
public static long f(long i) {
|
||||
@@ -116,7 +114,7 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
@@ -116,7 +122,7 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
}
|
||||
|
||||
public BlockPosition s() {
|
||||
|
@ -184,7 +192,7 @@ index ca3f63f5e5e4e926de562b4bfbbf72ad8a6b943f..c415736282de6d4d0f87135c24999c4b
|
|||
}
|
||||
|
||||
public BlockPosition t() {
|
||||
@@ -129,36 +127,30 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
@@ -129,36 +135,30 @@ public class SectionPosition extends BaseBlockPosition {
|
||||
return new ChunkCoordIntPair(this.a(), this.c());
|
||||
}
|
||||
|
||||
|
|
|
@ -38,24 +38,18 @@ index d051a54aa04326f84e211cd68ddd2bb209230770..bd7a92599b4182739aafef9eeaaf8665
|
|||
return this.j;
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
index 340d6e992786e8877243ccb472b462e88ec1e6fb..d07fcc0c51679104506d81acfdee6f391f30c0a0 100644
|
||||
index 340d6e992786e8877243ccb472b462e88ec1e6fb..451803d3f575b7fcd7ce0891bc1e2c86c2aa2832 100644
|
||||
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
||||
@@ -1089,12 +1089,13 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
@@ -1089,7 +1089,7 @@ public class ChunkProviderServer extends IChunkProvider {
|
||||
if (ChunkProviderServer.this.tickDistanceManager()) {
|
||||
return true;
|
||||
} else {
|
||||
- ChunkProviderServer.this.lightEngine.queueUpdate();
|
||||
+ //ChunkProviderServer.this.lightEngine.queueUpdate(); // Paper - move down
|
||||
+ //ChunkProviderServer.this.lightEngine.queueUpdate(); // Paper - not needed
|
||||
return super.executeNext() || execChunkTask; // Paper
|
||||
}
|
||||
} finally {
|
||||
playerChunkMap.chunkLoadConversionCallbackExecutor.run(); // Paper - Add chunk load conversion callback executor to prevent deadlock due to recursion in the chunk task queue sorter
|
||||
playerChunkMap.callbackExecutor.run();
|
||||
+ ChunkProviderServer.this.lightEngine.queueUpdate(); // Paper - always run, this is rate limited now
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/IBlockData.java b/src/main/java/net/minecraft/server/IBlockData.java
|
||||
index 296b41bf36ee1ace5bd9db2b810bf926b5f5278f..b39554faf235b6f81c86542673dfb4508d4c3e5a 100644
|
||||
--- a/src/main/java/net/minecraft/server/IBlockData.java
|
||||
|
@ -97,7 +91,7 @@ index 296b41bf36ee1ace5bd9db2b810bf926b5f5278f..b39554faf235b6f81c86542673dfb450
|
|||
|
||||
public VoxelShape getShape(IBlockAccess iblockaccess, BlockPosition blockposition) {
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineBlock.java b/src/main/java/net/minecraft/server/LightEngineBlock.java
|
||||
index 07fadc21ee12138b52cc77c50da536fec5b032f5..86868bedc65948b00edc8a7b6f219b85cc8c6374 100644
|
||||
index 07fadc21ee12138b52cc77c50da536fec5b032f5..a61d0a27e9525505eedaec8cde44216e807eb9a8 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineBlock.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineBlock.java
|
||||
@@ -13,9 +13,11 @@ public final class LightEngineBlock extends LightEngineLayer<LightEngineStorageB
|
||||
|
@ -166,7 +160,7 @@ index 07fadc21ee12138b52cc77c50da536fec5b032f5..86868bedc65948b00edc8a7b6f219b85
|
|||
+ int x = (int) (i >> 38);
|
||||
+ int y = (int) ((i << 52) >> 52);
|
||||
+ int z = (int) ((i << 26) >> 38);
|
||||
+ long k = SectionPosition.asLong(x >> 4, y >> 4, z >> 4);
|
||||
+ long k = SectionPosition.blockPosAsSectionLong(x, y, z);
|
||||
+ // Paper end
|
||||
EnumDirection[] aenumdirection = LightEngineBlock.e;
|
||||
int l = aenumdirection.length;
|
||||
|
@ -175,12 +169,12 @@ index 07fadc21ee12138b52cc77c50da536fec5b032f5..86868bedc65948b00edc8a7b6f219b85
|
|||
EnumDirection enumdirection = aenumdirection[i1];
|
||||
- long j1 = BlockPosition.a(i, enumdirection);
|
||||
- long k1 = SectionPosition.e(j1);
|
||||
+ long j1 = BlockPosition.asLong(x + enumdirection.getAdjacentX(), y + enumdirection.getAdjacentY(), z + enumdirection.getAdjacentZ()); // Paper
|
||||
+ long k1 = SectionPosition.asLong((x + enumdirection.getAdjacentX()) >> 4, (y + enumdirection.getAdjacentY()) >> 4, (z + enumdirection.getAdjacentZ()) >> 4); // Paper
|
||||
+ long j1 = BlockPosition.getAdjacent(x, y, z, enumdirection); // Paper
|
||||
+ long k1 = SectionPosition.getAdjacentFromBlockPos(x, y, z, enumdirection); // Paper
|
||||
|
||||
if (k == k1 || ((LightEngineStorageBlock) this.c).g(k1)) {
|
||||
this.b(i, j1, j, flag);
|
||||
@@ -88,27 +103,36 @@ public final class LightEngineBlock extends LightEngineLayer<LightEngineStorageB
|
||||
@@ -88,27 +103,37 @@ public final class LightEngineBlock extends LightEngineLayer<LightEngineStorageB
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,7 +184,7 @@ index 07fadc21ee12138b52cc77c50da536fec5b032f5..86868bedc65948b00edc8a7b6f219b85
|
|||
+ int baseX = (int) (i >> 38);
|
||||
+ int baseY = (int) ((i << 52) >> 52);
|
||||
+ int baseZ = (int) ((i << 26) >> 38);
|
||||
+ long j1 = (((long) (baseX >> 4) & 4194303L) << 42) | (((long) (baseY >> 4) & 1048575L)) | (((long) (baseZ >> 4) & 4194303L) << 20);
|
||||
+ long j1 = SectionPosition.blockPosAsSectionLong(baseX, baseY, baseZ);
|
||||
+ NibbleArray nibblearray = this.c.updating.getUpdatingOptimized(j1);
|
||||
+ // Paper end
|
||||
EnumDirection[] aenumdirection = LightEngineBlock.e;
|
||||
|
@ -199,15 +193,14 @@ index 07fadc21ee12138b52cc77c50da536fec5b032f5..86868bedc65948b00edc8a7b6f219b85
|
|||
for (int l1 = 0; l1 < k1; ++l1) {
|
||||
EnumDirection enumdirection = aenumdirection[l1];
|
||||
- long i2 = BlockPosition.a(i, enumdirection);
|
||||
-
|
||||
- if (i2 != j) {
|
||||
- long j2 = SectionPosition.e(i2);
|
||||
+ // Paper start
|
||||
+ int newX = baseX + enumdirection.getAdjacentX();
|
||||
+ int newY = baseY + enumdirection.getAdjacentY();
|
||||
+ int newZ = baseZ + enumdirection.getAdjacentZ();
|
||||
+ if (newX != baseX || newY != baseY || newZ != baseZ) {
|
||||
+ long i2 = BlockPosition.asLong(newX, newY, newZ);
|
||||
+ long i2 = BlockPosition.asLong(newX, newY, newZ);
|
||||
|
||||
if (i2 != j) {
|
||||
- long j2 = SectionPosition.e(i2);
|
||||
+ long j2 = SectionPosition.blockPosAsSectionLong(newX, newY, newZ);
|
||||
+ // Paper end
|
||||
NibbleArray nibblearray1;
|
||||
|
@ -408,7 +401,7 @@ index f72ff8495bcf704c15040676b95c51fecb72b73a..faa432779ec70c2c6b5fe7fe3523f171
|
|||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineSky.java b/src/main/java/net/minecraft/server/LightEngineSky.java
|
||||
index f0b57784006752e031800a12a1a3c1a5945c636b..3d508fdb0ea86fbe78891113776a1cb312df8dce 100644
|
||||
index f0b57784006752e031800a12a1a3c1a5945c636b..32b52ca2462fa206b1184025cb3837d6c326db2d 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineSky.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineSky.java
|
||||
@@ -29,21 +29,25 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
|
@ -471,42 +464,32 @@ index f0b57784006752e031800a12a1a3c1a5945c636b..3d508fdb0ea86fbe78891113776a1cb3
|
|||
}
|
||||
}
|
||||
}
|
||||
@@ -92,8 +96,13 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
@@ -92,10 +96,14 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
|
||||
@Override
|
||||
protected void a(long i, int j, boolean flag) {
|
||||
- long k = SectionPosition.e(i);
|
||||
- int l = BlockPosition.c(i);
|
||||
- int i1 = SectionPosition.b(l);
|
||||
- int j1 = SectionPosition.a(l);
|
||||
+ // Paper start
|
||||
+ int baseX = (int) (i >> 38);
|
||||
+ int baseY = (int) ((i << 52) >> 52);
|
||||
+ int baseZ = (int) ((i << 26) >> 38);
|
||||
+ long k = SectionPosition.blockPosAsSectionLong(baseX, baseY, baseZ);
|
||||
+ int l = baseY;
|
||||
+ int i1 = baseY & 15;
|
||||
+ int j1 = baseY >> 4;
|
||||
+ // Paper end
|
||||
int i1 = SectionPosition.b(l);
|
||||
int j1 = SectionPosition.a(l);
|
||||
int k1;
|
||||
@@ -103,22 +112,28 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
} else {
|
||||
int l1;
|
||||
|
||||
- for (l1 = 0; !((LightEngineStorageSky) this.c).g(SectionPosition.a(k, 0, -l1 - 1, 0)) && ((LightEngineStorageSky) this.c).a(j1 - l1 - 1); ++l1) {
|
||||
+ // Paper start - cache and optimize base values
|
||||
+ int secX = baseX >> 4;
|
||||
+ int secY = baseY >> 4;
|
||||
+ int secZ = baseZ >> 4;
|
||||
+ for (l1 = 0; !((LightEngineStorageSky) this.c).g(SectionPosition.asLong(secX, secY + -l1 - 1, secZ)) && ((LightEngineStorageSky) this.c).a(j1 - l1 - 1); ++l1) {
|
||||
+ // Paper end
|
||||
;
|
||||
}
|
||||
|
||||
if (i1 != 0) {
|
||||
@@ -110,15 +118,16 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
k1 = l1;
|
||||
}
|
||||
|
||||
- long i2 = BlockPosition.a(i, 0, -1 - k1 * 16, 0);
|
||||
- long j2 = SectionPosition.e(i2);
|
||||
+ int newBaseY = baseY + -1 - k1 * 16; // Paper
|
||||
+ int newBaseY = baseY + (-1 - k1 * 16); // Paper
|
||||
+ long i2 = BlockPosition.asLong(baseX, newBaseY, baseZ); // Paper
|
||||
+ long j2 = SectionPosition.blockPosAsSectionLong(baseX, newBaseY, baseZ); // Paper
|
||||
|
||||
|
@ -521,7 +504,7 @@ index f0b57784006752e031800a12a1a3c1a5945c636b..3d508fdb0ea86fbe78891113776a1cb3
|
|||
|
||||
if (k == l2 || ((LightEngineStorageSky) this.c).g(l2)) {
|
||||
this.b(i, k2, j, flag);
|
||||
@@ -133,8 +148,8 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
@@ -133,8 +142,8 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
int k3 = 0;
|
||||
|
||||
while (true) {
|
||||
|
@ -532,7 +515,7 @@ index f0b57784006752e031800a12a1a3c1a5945c636b..3d508fdb0ea86fbe78891113776a1cb3
|
|||
|
||||
if (k == i4) {
|
||||
this.b(i, l3, j, flag);
|
||||
@@ -172,26 +187,36 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
@@ -172,26 +181,36 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -542,7 +525,7 @@ index f0b57784006752e031800a12a1a3c1a5945c636b..3d508fdb0ea86fbe78891113776a1cb3
|
|||
+ int baseX = (int) (i >> 38);
|
||||
+ int baseY = (int) ((i << 52) >> 52);
|
||||
+ int baseZ = (int) ((i << 26) >> 38);
|
||||
+ long j1 = (((long) (baseX >> 4) & 4194303L) << 42) | (((long) (baseY >> 4) & 1048575L)) | (((long) (baseZ >> 4) & 4194303L) << 20);
|
||||
+ long j1 = SectionPosition.blockPosAsSectionLong(baseX, baseY, baseZ);
|
||||
+ NibbleArray nibblearray = this.c.updating.getUpdatingOptimized(j1);
|
||||
+ // Paper end
|
||||
EnumDirection[] aenumdirection = LightEngineSky.e;
|
||||
|
@ -575,7 +558,7 @@ index f0b57784006752e031800a12a1a3c1a5945c636b..3d508fdb0ea86fbe78891113776a1cb3
|
|||
|
||||
if (l > k2) {
|
||||
l = k2;
|
||||
@@ -206,7 +231,7 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
@@ -206,7 +225,7 @@ public final class LightEngineSky extends LightEngineLayer<LightEngineStorageSky
|
||||
j2 = SectionPosition.a(j2, EnumDirection.UP);
|
||||
}
|
||||
|
||||
|
@ -585,7 +568,7 @@ index f0b57784006752e031800a12a1a3c1a5945c636b..3d508fdb0ea86fbe78891113776a1cb3
|
|||
if (i2 != j) {
|
||||
int l2;
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineStorage.java b/src/main/java/net/minecraft/server/LightEngineStorage.java
|
||||
index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a2323447f 100644
|
||||
index b0b7544592981bcff22c8acee7230a211918ef28..f2575fb69714397bb8e1f9d402689c7816d73b6c 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineStorage.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineStorage.java
|
||||
@@ -20,42 +20,42 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
|
@ -640,7 +623,7 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
return m0.c(i);
|
||||
}
|
||||
|
||||
@@ -69,27 +69,56 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
@@ -69,27 +69,57 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
protected abstract int d(long i);
|
||||
|
||||
protected int i(long i) {
|
||||
|
@ -650,10 +633,11 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
+ final int x = (int) (i >> 38);
|
||||
+ final int y = (int) ((i << 52) >> 52);
|
||||
+ final int z = (int) ((i << 26) >> 38);
|
||||
+ NibbleArray nibblearray = this.updating.getUpdatingOptimized((((long) (x >> 4) & 4194303L) << 42) | (((long) (y >> 4) & 1048575L)) | (((long) (z >> 4) & 4194303L) << 20));
|
||||
+ long j = SectionPosition.blockPosAsSectionLong(x, y, z);
|
||||
+ NibbleArray nibblearray = this.updating.getUpdatingOptimized(j);
|
||||
+ // BUG: Sometimes returns null and crashes, try to recover, but to prevent crash just return no light.
|
||||
+ if (nibblearray == null) {
|
||||
+ nibblearray = this.e_visible.lookup.apply((((long) (x >> 4) & 4194303L) << 42) | (((long) (y >> 4) & 1048575L)) | (((long) (z >> 4) & 4194303L) << 20));
|
||||
+ nibblearray = this.e_visible.lookup.apply(j);
|
||||
+ }
|
||||
+ if (nibblearray == null) {
|
||||
+ System.err.println("Null nibble, preventing crash " + BlockPosition.fromLong(i));
|
||||
|
@ -671,7 +655,7 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
+ int x = (int) (i >> 38);
|
||||
+ int y = (int) ((i << 52) >> 52);
|
||||
+ int z = (int) ((i << 26) >> 38);
|
||||
+ long k = SectionPosition.asLong(x >> 4, y >> 4, z >> 4);
|
||||
+ long k = SectionPosition.blockPosAsSectionLong(x, y, z);
|
||||
+ // Paper end
|
||||
|
||||
if (this.g.add(k)) {
|
||||
|
@ -708,7 +692,7 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
}
|
||||
}
|
||||
}
|
||||
@@ -121,17 +150,23 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
@@ -121,17 +151,23 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
}
|
||||
|
||||
if (k >= 2 && j != 2) {
|
||||
|
@ -739,7 +723,7 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
}
|
||||
}
|
||||
}
|
||||
@@ -157,9 +192,9 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
@@ -157,9 +193,9 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
return SectionPosition.e(j) == i;
|
||||
});
|
||||
} else {
|
||||
|
@ -752,7 +736,7 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
|
||||
for (int i1 = 0; i1 < 16; ++i1) {
|
||||
for (int j1 = 0; j1 < 16; ++j1) {
|
||||
@@ -186,7 +221,7 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
@@ -186,7 +222,7 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
NibbleArray nibblearray;
|
||||
|
||||
while (longiterator.hasNext()) {
|
||||
|
@ -761,7 +745,7 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
this.a(lightenginelayer, i);
|
||||
NibbleArray nibblearray1 = (NibbleArray) this.i.remove(i);
|
||||
|
||||
@@ -204,48 +239,56 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
@@ -204,48 +240,56 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
longiterator = this.o.iterator();
|
||||
|
||||
while (longiterator.hasNext()) {
|
||||
|
@ -812,12 +796,12 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
+ // Paper start
|
||||
+ i = longiterator.nextLong();
|
||||
+ if (true) { // don't check hasLight, this iterator is filtered already
|
||||
+ int baseX = (int) (i >> 42);
|
||||
+ int baseY = (int) (i << 44 >> 44);
|
||||
+ int baseZ = (int) (i << 22 >> 42);
|
||||
+ int k = baseX << 4;
|
||||
+ int l = baseY << 4;
|
||||
+ int i1 = baseZ << 4;
|
||||
+ int secX = (int) (i >> 42);
|
||||
+ int secY = (int) (i << 44 >> 44);
|
||||
+ int secZ = (int) (i << 22 >> 42);
|
||||
+ int k = secX << 4; // baseX
|
||||
+ int l = secY << 4; // baseY
|
||||
+ int i1 = secZ << 4; // baseZ
|
||||
+ // Paper end
|
||||
EnumDirection[] aenumdirection = LightEngineStorage.k;
|
||||
int j1 = aenumdirection.length;
|
||||
|
@ -827,12 +811,12 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
- long l1 = SectionPosition.a(i, enumdirection);
|
||||
-
|
||||
- if (!this.i.containsKey(l1) && this.g(l1)) {
|
||||
+ long l1 = SectionPosition.asLong(baseX + enumdirection.getAdjacentX(), baseY + enumdirection.getAdjacentY(), baseZ + enumdirection.getAdjacentZ()); // Paper - avoid unpacking
|
||||
+ long l1 = SectionPosition.getAdjacentFromSectionPos(secX, secY, secZ, enumdirection); // Paper - avoid extra unpacking
|
||||
+ if (!propagating.contains(l1) && this.g(l1)) { // Paper - use propagating
|
||||
for (int i2 = 0; i2 < 16; ++i2) {
|
||||
for (int j2 = 0; j2 < 16; ++j2) {
|
||||
long k2;
|
||||
@@ -287,6 +330,8 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
@@ -287,6 +331,8 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -841,7 +825,7 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
objectiterator = this.i.long2ObjectEntrySet().iterator();
|
||||
|
||||
while (objectiterator.hasNext()) {
|
||||
@@ -295,7 +340,8 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
@@ -295,7 +341,8 @@ public abstract class LightEngineStorage<M extends LightEngineStorageArray<M>> e
|
||||
if (this.g(j)) {
|
||||
objectiterator.remove();
|
||||
}
|
||||
|
@ -852,59 +836,157 @@ index b0b7544592981bcff22c8acee7230a211918ef28..84a2589ef0bbb2c5d8b5d4808277916a
|
|||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageArray.java b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
|
||||
index 37c44a89f28c44915fcae5a7e2c4797b1c123723..53c204455c3800b4fe399ce6261b0495eea4d003 100644
|
||||
index 37c44a89f28c44915fcae5a7e2c4797b1c123723..549c2551c2b59730bf53a80f8706d388d96ad932 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineStorageArray.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineStorageArray.java
|
||||
@@ -43,6 +43,25 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
||||
@@ -5,13 +5,18 @@ import javax.annotation.Nullable;
|
||||
|
||||
public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<M>> {
|
||||
|
||||
- private final long[] b = new long[2];
|
||||
- private final NibbleArray[] c = new NibbleArray[2];
|
||||
+ // private final long[] b = new long[2]; // Paper - unused
|
||||
+ private final NibbleArray[] c = new NibbleArray[]{NibbleArray.EMPTY_NIBBLE_ARRAY, NibbleArray.EMPTY_NIBBLE_ARRAY}; private final NibbleArray[] cache = c; // Paper - OBFHELPER
|
||||
private boolean d;
|
||||
protected final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<NibbleArray> data; // Paper - avoid copying light data
|
||||
protected final boolean isVisible; // Paper - avoid copying light data
|
||||
- java.util.function.Function<Long, NibbleArray> lookup; // Paper - faster branchless lookup
|
||||
|
||||
+ // Paper start - faster lookups with less branching, use interface to avoid boxing instead of Function
|
||||
+ public final NibbleArrayAccess lookup;
|
||||
+ public interface NibbleArrayAccess {
|
||||
+ NibbleArray apply(long id);
|
||||
+ }
|
||||
+ // Paper end
|
||||
// Paper start - avoid copying light data
|
||||
protected LightEngineStorageArray(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<NibbleArray> data, boolean isVisible) {
|
||||
if (isVisible) {
|
||||
@@ -19,12 +24,14 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
||||
}
|
||||
this.data = data;
|
||||
this.isVisible = isVisible;
|
||||
+ // Paper end - avoid copying light data
|
||||
+ // Paper start - faster lookups with less branching
|
||||
if (isVisible) {
|
||||
lookup = data::getVisibleAsync;
|
||||
} else {
|
||||
- lookup = data::getUpdating;
|
||||
+ lookup = data.getUpdatingMap()::get; // jump straight the sub map
|
||||
}
|
||||
- // Paper end - avoid copying light data
|
||||
+ // Paper end
|
||||
this.c();
|
||||
this.d = true;
|
||||
}
|
||||
@@ -34,7 +41,9 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
||||
public void a(long i) {
|
||||
if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
|
||||
NibbleArray updating = this.data.getUpdating(i); // Paper - pool nibbles
|
||||
- this.data.queueUpdate(i, new NibbleArray().markPoolSafe(updating.getCloneIfSet())); // Paper - avoid copying light data - pool safe clone
|
||||
+ NibbleArray nibblearray = new NibbleArray().markPoolSafe(updating.getCloneIfSet()); // Paper
|
||||
+ nibblearray.lightCacheKey = i; // Paper
|
||||
+ this.data.queueUpdate(i, nibblearray); // Paper - avoid copying light data - pool safe clone
|
||||
if (updating.cleaner != null) MCUtil.scheduleTask(2, updating.cleaner, "Light Engine Release"); // Paper - delay clean incase anything holding ref was still using it
|
||||
this.c();
|
||||
}
|
||||
@@ -43,34 +52,34 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
||||
return lookup.apply(i) != null; // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
- @Nullable
|
||||
- public final NibbleArray c(long i) { // Paper - final
|
||||
- if (this.d) {
|
||||
- for (int j = 0; j < 2; ++j) {
|
||||
- if (i == this.b[j]) {
|
||||
- return this.c[j];
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- NibbleArray nibblearray = lookup.apply(i); // Paper - avoid copying light data
|
||||
+ // Paper start - less branching as we know we are using cache and updating
|
||||
+ public final NibbleArray getUpdatingOptimized(long i) { // Paper - final
|
||||
+ if (this.b[0] == i) return this.c[0];
|
||||
+ if (this.b[1] == i) return this.c[1];
|
||||
+
|
||||
+ NibbleArray nibblearray = this.data.getUpdating(i); // Paper - avoid copying light data
|
||||
+ if (nibblearray == null) {
|
||||
+ return null;
|
||||
+ } else {
|
||||
+ this.b[1] = this.b[0];
|
||||
+ this.c[1] = this.c[0];
|
||||
+
|
||||
+ this.b[0] = i;
|
||||
+ this.c[0] = nibblearray;
|
||||
+ return nibblearray;
|
||||
+ }
|
||||
+ }
|
||||
+ public final NibbleArray getUpdatingOptimized(final long i) { // Paper - final
|
||||
+ final NibbleArray[] cache = this.cache;
|
||||
+ if (cache[0].lightCacheKey == i) return cache[0];
|
||||
+ if (cache[1].lightCacheKey == i) return cache[1];
|
||||
|
||||
+ final NibbleArray nibblearray = this.lookup.apply(i); // Paper - avoid copying light data
|
||||
if (nibblearray == null) {
|
||||
return null;
|
||||
} else {
|
||||
- if (this.d) {
|
||||
- for (int k = 1; k > 0; --k) {
|
||||
- this.b[k] = this.b[k - 1];
|
||||
- this.c[k] = this.c[k - 1];
|
||||
- }
|
||||
-
|
||||
- this.b[0] = i;
|
||||
- this.c[0] = nibblearray;
|
||||
- }
|
||||
-
|
||||
+ cache[1] = cache[0];
|
||||
+ cache[0] = nibblearray;
|
||||
return nibblearray;
|
||||
}
|
||||
}
|
||||
+ // Paper end
|
||||
+
|
||||
+ @Nullable
|
||||
+ public final NibbleArray c(final long i) { // Paper - final
|
||||
+ // Paper start - optimize visible case or missed updating cases
|
||||
+ if (this.d) {
|
||||
+ // short circuit to optimized
|
||||
+ return getUpdatingOptimized(i);
|
||||
+ }
|
||||
+
|
||||
+ return this.lookup.apply(i);
|
||||
+ // Paper end
|
||||
+ }
|
||||
|
||||
@Nullable
|
||||
public final NibbleArray c(long i) { // Paper - final
|
||||
if (this.d) {
|
||||
public NibbleArray d(long i) {
|
||||
@@ -80,13 +89,14 @@ public abstract class LightEngineStorageArray<M extends LightEngineStorageArray<
|
||||
|
||||
public void a(long i, NibbleArray nibblearray) {
|
||||
if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
|
||||
+ nibblearray.lightCacheKey = i; // Paper
|
||||
this.data.queueUpdate(i, nibblearray); // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
public void c() {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
- this.b[i] = Long.MAX_VALUE;
|
||||
- this.c[i] = null;
|
||||
+ // this.b[i] = Long.MAX_VALUE; // Paper - Unused
|
||||
+ this.c[i] = NibbleArray.EMPTY_NIBBLE_ARRAY; // Paper
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageBlock.java b/src/main/java/net/minecraft/server/LightEngineStorageBlock.java
|
||||
index 292d8c742d3be41ba8ad7fb7f1251dc7f790b62b..ae6a5d2f660a53885b5b0c61ce39cf75a7dd99be 100644
|
||||
index 292d8c742d3be41ba8ad7fb7f1251dc7f790b62b..5b7b7506f5d1a7578fb54a578891324dfcec3f03 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineStorageBlock.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineStorageBlock.java
|
||||
@@ -10,10 +10,15 @@ public class LightEngineStorageBlock extends LightEngineStorage<LightEngineStora
|
||||
@@ -10,10 +10,14 @@ public class LightEngineStorageBlock extends LightEngineStorage<LightEngineStora
|
||||
|
||||
@Override
|
||||
protected int d(long i) {
|
||||
- long j = SectionPosition.e(i);
|
||||
- NibbleArray nibblearray = this.a(j, false);
|
||||
-
|
||||
- return nibblearray == null ? 0 : nibblearray.a(SectionPosition.b(BlockPosition.b(i)), SectionPosition.b(BlockPosition.c(i)), SectionPosition.b(BlockPosition.d(i)));
|
||||
+ // Paper start
|
||||
+ int baseX = (int) (i >> 38);
|
||||
+ int baseY = (int) ((i << 52) >> 52);
|
||||
+ int baseZ = (int) ((i << 26) >> 38);
|
||||
+ long j = (((long) (baseX >> 4) & 4194303L) << 42) | (((long) (baseY >> 4) & 1048575L)) | (((long) (baseZ >> 4) & 4194303L) << 20);
|
||||
+ NibbleArray nibblearray = this.e_visible.lookup.apply(j);
|
||||
+ return nibblearray == null ? 0 : nibblearray.a(baseX & 15, baseY & 15, baseZ & 15);
|
||||
+ // Paper end
|
||||
NibbleArray nibblearray = this.a(j, false);
|
||||
|
||||
- return nibblearray == null ? 0 : nibblearray.a(SectionPosition.b(BlockPosition.b(i)), SectionPosition.b(BlockPosition.c(i)), SectionPosition.b(BlockPosition.d(i)));
|
||||
+ return nibblearray == null ? 0 : nibblearray.a(baseX & 15, baseY & 15, baseZ & 15); // Paper
|
||||
}
|
||||
|
||||
public static final class a extends LightEngineStorageArray<LightEngineStorageBlock.a> {
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineStorageSky.java b/src/main/java/net/minecraft/server/LightEngineStorageSky.java
|
||||
index 097f58e9ac3f4096d3b9dad75b6ebe76021fa92c..5ccd81bd0d49052fe84d4f34e29774f0cc2dd732 100644
|
||||
index 097f58e9ac3f4096d3b9dad75b6ebe76021fa92c..f744f62c93370d096c113f92ee81a8232c35501d 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineStorageSky.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineStorageSky.java
|
||||
@@ -22,7 +22,12 @@ public class LightEngineStorageSky extends LightEngineStorage<LightEngineStorage
|
||||
|
@ -916,7 +998,7 @@ index 097f58e9ac3f4096d3b9dad75b6ebe76021fa92c..5ccd81bd0d49052fe84d4f34e29774f0
|
|||
+ int baseX = (int) (i >> 38);
|
||||
+ int baseY = (int) ((i << 52) >> 52);
|
||||
+ int baseZ = (int) ((i << 26) >> 38);
|
||||
+ long j = (((long) (baseX >> 4) & 4194303L) << 42) | (((long) (baseY >> 4) & 1048575L)) | (((long) (baseZ >> 4) & 4194303L) << 20);
|
||||
+ long j = SectionPosition.blockPosAsSectionLong(baseX, baseY, baseZ);
|
||||
+ // Paper end
|
||||
int k = SectionPosition.c(j);
|
||||
synchronized (this.visibleUpdateLock) { // Paper - avoid copying light data
|
||||
|
@ -971,7 +1053,7 @@ index 097f58e9ac3f4096d3b9dad75b6ebe76021fa92c..5ccd81bd0d49052fe84d4f34e29774f0
|
|||
EnumDirection enumdirection = aenumdirection[l1];
|
||||
|
||||
- k1 = SectionPosition.a(i, enumdirection);
|
||||
+ k1 = SectionPosition.asLong(baseX + enumdirection.getAdjacentX(), baseY + enumdirection.getAdjacentY(), baseZ + enumdirection.getAdjacentZ()); // Paper
|
||||
+ k1 = SectionPosition.getAdjacentFromBlockPos(baseX, baseY, baseZ, enumdirection); // Paper
|
||||
if ((this.n.contains(k1) || !this.l.contains(k1) && !this.m.contains(k1)) && this.g(k1)) {
|
||||
for (int i2 = 0; i2 < 16; ++i2) {
|
||||
for (int j2 = 0; j2 < 16; ++j2) {
|
||||
|
@ -1013,53 +1095,71 @@ index 097f58e9ac3f4096d3b9dad75b6ebe76021fa92c..5ccd81bd0d49052fe84d4f34e29774f0
|
|||
lightenginelayer.a(Long.MAX_VALUE, l3, 15, false);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/LightEngineThreaded.java b/src/main/java/net/minecraft/server/LightEngineThreaded.java
|
||||
index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..72cc711d6c2645aed44f208ee44f8702d64c5af8 100644
|
||||
index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..604fe85313969bf1ad5b5ef75b46f9a23f79764a 100644
|
||||
--- a/src/main/java/net/minecraft/server/LightEngineThreaded.java
|
||||
+++ b/src/main/java/net/minecraft/server/LightEngineThreaded.java
|
||||
@@ -15,8 +15,70 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
@@ -14,8 +14,98 @@ import org.apache.logging.log4j.Logger;
|
||||
public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private final ThreadedMailbox<Runnable> b;
|
||||
- private final ThreadedMailbox<Runnable> b;
|
||||
- private final ObjectList<Pair<LightEngineThreaded.Update, Runnable>> c = new ObjectArrayList();
|
||||
- private final PlayerChunkMap d;
|
||||
+ // Paper start - add urgent queue, switch to ArrayDeque
|
||||
+ private long nextNonUrgent = 0;
|
||||
+ private boolean shouldPollNonUrgent() {
|
||||
+ return urgent.isEmpty() && !c.isEmpty() && (this.c.size() >= this.f || System.nanoTime() > nextNonUrgent);
|
||||
+ }
|
||||
+
|
||||
+ private boolean shouldPollUrgent() {
|
||||
+ return (super.a() || !urgent.isEmpty());
|
||||
+ }
|
||||
+
|
||||
+ private IntSupplier getChunkPrioritySupplier(ChunkCoordIntPair coords) {
|
||||
+ return getChunkMap().getPrioritySupplier(coords.pair());
|
||||
+ }
|
||||
+ private final ThreadedMailbox<Runnable> b; ThreadedMailbox<Runnable> mailbox; // Paper
|
||||
+ // Paper start
|
||||
+ private static final int MAX_PRIORITIES = PlayerChunkMap.GOLDEN_TICKET + 2;
|
||||
+ private static class LightQueueBucket extends java.util.ArrayDeque<Pair<LightEngineThreaded.Update, Runnable>> {
|
||||
+ public LightQueueBucket() {
|
||||
+ super(64);
|
||||
+ }
|
||||
+
|
||||
+ public void changePriority(long pair, int currentPriority, int priority) {
|
||||
+ this.mailbox.queue(() -> {
|
||||
+ ChunkLightQueue remove = this.queue.buckets[currentPriority].remove(pair);
|
||||
+ if (remove != null) {
|
||||
+ ChunkLightQueue existing = this.queue.buckets[priority].put(pair, remove);
|
||||
+ if (existing != null) {
|
||||
+ remove.pre.addAll(existing.pre);
|
||||
+ remove.post.addAll(existing.post);
|
||||
+ }
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ static class ChunkLightQueue {
|
||||
+ public boolean shouldFastUpdate;
|
||||
+ java.util.ArrayDeque<Runnable> pre = new java.util.ArrayDeque<Runnable>();
|
||||
+ java.util.ArrayDeque<Runnable> post = new java.util.ArrayDeque<Runnable>();
|
||||
+
|
||||
+ ChunkLightQueue(long chunk) {}
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ // Retain the chunks priority level for queued light tasks
|
||||
+ private static class LightQueue {
|
||||
+
|
||||
+ private int size = 0;
|
||||
+ private int lowestPriority = MAX_PRIORITIES;
|
||||
+ private final LightQueueBucket[] buckets = new LightQueueBucket[MAX_PRIORITIES];
|
||||
+ private final it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<ChunkLightQueue>[] buckets = new it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap[MAX_PRIORITIES];
|
||||
+
|
||||
+ private LightQueue() {
|
||||
+ for (int i = 0; i < buckets.length; i++) {
|
||||
+ buckets[i] = new LightQueueBucket();
|
||||
+ buckets[i] = new it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<>();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ public final void add(int priority, LightEngineThreaded.Update type, Runnable run) {
|
||||
+ public final void add(long chunkId, int priority, LightEngineThreaded.Update type, Runnable run) {
|
||||
+ add(chunkId, priority, type, run, false);
|
||||
+ }
|
||||
+ public final void add(long chunkId, int priority, LightEngineThreaded.Update type, Runnable run, boolean shouldFastUpdate) {
|
||||
+ ChunkLightQueue lightQueue = this.buckets[priority].computeIfAbsent(chunkId, ChunkLightQueue::new);
|
||||
+ this.size++;
|
||||
+ if (lowestPriority > priority) {
|
||||
+ lowestPriority = priority;
|
||||
+ if (type == Update.PRE_UPDATE) {
|
||||
+ lightQueue.pre.add(run);
|
||||
+ } else {
|
||||
+ lightQueue.post.add(run);
|
||||
+ }
|
||||
+ if (shouldFastUpdate) {
|
||||
+ lightQueue.shouldFastUpdate = true;
|
||||
+ }
|
||||
+
|
||||
+ if (this.lowestPriority > priority) {
|
||||
+ this.lowestPriority = priority;
|
||||
+ }
|
||||
+ this.buckets[priority].add(new Pair<>(type, run));
|
||||
+ }
|
||||
+
|
||||
+ public final boolean isEmpty() {
|
||||
|
@ -1070,82 +1170,102 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..72cc711d6c2645aed44f208ee44f8702
|
|||
+ return this.size;
|
||||
+ }
|
||||
+
|
||||
+ public Pair<Update, Runnable> poll() {
|
||||
+ for (; lowestPriority < MAX_PRIORITIES; lowestPriority++) {
|
||||
+ Pair<Update, Runnable> entry = buckets[lowestPriority].pollFirst();
|
||||
+ if (entry != null) {
|
||||
+ this.size--;
|
||||
+ return entry;
|
||||
+ public boolean poll(java.util.List<Runnable> pre, java.util.List<Runnable> post) {
|
||||
+ boolean hasWork = false;
|
||||
+ it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<ChunkLightQueue>[] buckets = this.buckets;
|
||||
+ while (lowestPriority < MAX_PRIORITIES && !isEmpty()) {
|
||||
+ it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap<ChunkLightQueue> bucket = buckets[lowestPriority];
|
||||
+ if (bucket.isEmpty()) {
|
||||
+ lowestPriority++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ ChunkLightQueue queue = bucket.removeFirst();
|
||||
+ this.size -= queue.pre.size() + queue.post.size();
|
||||
+ pre.addAll(queue.pre);
|
||||
+ post.addAll(queue.post);
|
||||
+ queue.pre.clear();
|
||||
+ queue.post.clear();
|
||||
+ hasWork = true;
|
||||
+ if (queue.shouldFastUpdate) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return null;
|
||||
+ return hasWork;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private final LightQueue urgent = new LightQueue();
|
||||
+ private final LightQueue c = new LightQueue();
|
||||
+ private final LightQueue queue = new LightQueue();
|
||||
+ // Paper end
|
||||
+ private final PlayerChunkMap d; private PlayerChunkMap getChunkMap() { return d; } // Paper - OBFHELPER
|
||||
private final PlayerChunkMap d;
|
||||
private final Mailbox<ChunkTaskQueueSorter.a<Runnable>> e;
|
||||
private volatile int f = 5;
|
||||
private final AtomicBoolean g = new AtomicBoolean();
|
||||
@@ -110,11 +172,14 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
@@ -25,7 +115,7 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
super(ilightaccess, true, flag);
|
||||
this.d = playerchunkmap;
|
||||
this.e = mailbox;
|
||||
- this.b = threadedmailbox;
|
||||
+ this.mailbox = this.b = threadedmailbox; // Paper
|
||||
}
|
||||
|
||||
public void close() {}
|
||||
@@ -111,8 +201,11 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
|
||||
private void a(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable) {
|
||||
+ // Paper start
|
||||
+ scheduleLightTask(i, j, intsupplier, lightenginethreaded_update, runnable, false);
|
||||
+ }
|
||||
+ private void scheduleLightTask(int i, int j, IntSupplier intsupplier, LightEngineThreaded.Update lightenginethreaded_update, Runnable runnable, boolean urgent) {
|
||||
this.e.a(ChunkTaskQueueSorter.a(() -> { // Paper - decompile error
|
||||
- this.c.add(Pair.of(lightenginethreaded_update, runnable));
|
||||
- if (this.c.size() >= this.f) {
|
||||
- this.b();
|
||||
- }
|
||||
+ (urgent ? this.urgent : this.c).add(intsupplier.getAsInt(), lightenginethreaded_update, runnable);
|
||||
+ if (shouldPollUrgent() || shouldPollNonUrgent()) queueUpdate();
|
||||
+ // Paper end
|
||||
+ // Paper start
|
||||
+ int priority = intsupplier.getAsInt();
|
||||
+ this.queue.add(ChunkCoordIntPair.pair(i, j), priority, lightenginethreaded_update, runnable); // Paper
|
||||
+ if (priority <= 25) { // don't auto kick off unless priority
|
||||
+ // Paper end
|
||||
this.b();
|
||||
}
|
||||
|
||||
}, ChunkCoordIntPair.pair(i, j), intsupplier));
|
||||
}
|
||||
@@ -134,7 +199,7 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
@@ -134,7 +227,14 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
ChunkCoordIntPair chunkcoordintpair = ichunkaccess.getPos();
|
||||
|
||||
ichunkaccess.b(false);
|
||||
- this.a(chunkcoordintpair.x, chunkcoordintpair.z, LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> {
|
||||
+ this.scheduleLightTask(chunkcoordintpair.x, chunkcoordintpair.z, getChunkPrioritySupplier(chunkcoordintpair), LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> { // Paper
|
||||
+ // Paper start
|
||||
+ long pair = chunkcoordintpair.pair();
|
||||
+ CompletableFuture<IChunkAccess> future = new CompletableFuture<>();
|
||||
+ IntSupplier prioritySupplier1 = d.getPrioritySupplier(pair);
|
||||
+ IntSupplier prioritySupplier = flag ? () -> Math.max(1, prioritySupplier1.getAsInt() - 10) : prioritySupplier1;
|
||||
+ this.e.a(ChunkTaskQueueSorter.a(() -> {
|
||||
+ this.queue.add(pair, prioritySupplier.getAsInt(), LightEngineThreaded.Update.PRE_UPDATE, SystemUtils.a(() -> {
|
||||
+ // Paper end
|
||||
ChunkSection[] achunksection = ichunkaccess.getSections();
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
@@ -155,51 +220,58 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
@@ -155,52 +255,45 @@ public class LightEngineThreaded extends LightEngine implements AutoCloseable {
|
||||
this.d.c(chunkcoordintpair);
|
||||
}, () -> {
|
||||
return "lightChunk " + chunkcoordintpair + " " + flag;
|
||||
- }));
|
||||
+ }), true); // Paper - urgent flag
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
+ // Paper start - merge the 2 together
|
||||
}));
|
||||
- return CompletableFuture.supplyAsync(() -> {
|
||||
+
|
||||
+ this.queue.add(pair, prioritySupplier.getAsInt(), LightEngineThreaded.Update.POST_UPDATE, () -> {
|
||||
ichunkaccess.b(true);
|
||||
super.b(chunkcoordintpair, false);
|
||||
return ichunkaccess;
|
||||
}, (runnable) -> {
|
||||
- return ichunkaccess;
|
||||
- }, (runnable) -> {
|
||||
- this.a(chunkcoordintpair.x, chunkcoordintpair.z, LightEngineThreaded.Update.POST_UPDATE, runnable);
|
||||
+ this.scheduleLightTask(chunkcoordintpair.x, chunkcoordintpair.z, getChunkPrioritySupplier(chunkcoordintpair), LightEngineThreaded.Update.POST_UPDATE, runnable, true); // Paper
|
||||
+ queueUpdate(); // Paper
|
||||
+ // Paper start
|
||||
+ future.complete(ichunkaccess);
|
||||
});
|
||||
+ queueUpdate(); // run queue now
|
||||
+ }, pair, prioritySupplier));
|
||||
+ return future;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public void queueUpdate() {
|
||||
- if ((!this.c.isEmpty() || super.a()) && this.g.compareAndSet(false, true)) {
|
||||
+ if ((shouldPollUrgent() || shouldPollNonUrgent()) && this.g.compareAndSet(false, true)) { // Paper - level check is now in shouldPollUrgent
|
||||
+ if ((!this.queue.isEmpty() || super.a()) && this.g.compareAndSet(false, true)) { // Paper
|
||||
this.b.a((() -> { // Paper - decompile error
|
||||
- this.b();
|
||||
+ // Paper start
|
||||
+ if (shouldPollUrgent()) {
|
||||
+ do {
|
||||
+ this.runQueue(true);
|
||||
+ } while (shouldPollUrgent());
|
||||
+ } else if (shouldPollNonUrgent()) this.runQueue(false); // don't loop non urgent as urgent might come in
|
||||
+ // Paper end
|
||||
this.b();
|
||||
this.g.set(false);
|
||||
+ queueUpdate(); // Paper - if we still have work to do, do it!
|
||||
}));
|
||||
|
@ -1153,6 +1273,7 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..72cc711d6c2645aed44f208ee44f8702
|
|||
|
||||
}
|
||||
|
||||
+ // Paper start - replace impl
|
||||
private void b() {
|
||||
- int i = Math.min(this.c.size(), this.f);
|
||||
- ObjectListIterator<Pair<LightEngineThreaded.Update, Runnable>> objectlistiterator = this.c.iterator();
|
||||
|
@ -1164,28 +1285,12 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..72cc711d6c2645aed44f208ee44f8702
|
|||
- pair = (Pair) objectlistiterator.next();
|
||||
- if (pair.getFirst() == LightEngineThreaded.Update.PRE_UPDATE) {
|
||||
- ((Runnable) pair.getSecond()).run();
|
||||
+ // Paper start - replace impl, use more effecient deque, avoid single removes (iterator.remove() which does a lot of copying)
|
||||
+ runQueue(!this.urgent.isEmpty());
|
||||
+ }
|
||||
+ private void runQueue(boolean urgent) {
|
||||
+ LightQueue col = urgent ? this.urgent : c;
|
||||
+ java.util.List<Pair<LightEngineThreaded.Update, Runnable>> pre = new java.util.ArrayList<>();
|
||||
+ java.util.List<Pair<LightEngineThreaded.Update, Runnable>> post = new java.util.ArrayList<>();
|
||||
+ int i = Math.min(col.size(), 8); // process small batches so chunks can progress without waiting for everything
|
||||
+ Pair<LightEngineThreaded.Update, Runnable> pair;
|
||||
+ while (i-- > 0 && (pair = col.poll()) != null) {
|
||||
+ if (pair.getFirst() == Update.PRE_UPDATE) {
|
||||
+ pre.add(pair);
|
||||
+ } else {
|
||||
+ post.add(pair);
|
||||
}
|
||||
}
|
||||
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- objectlistiterator.back(j);
|
||||
+ pre.forEach(entry -> entry.getSecond().run());
|
||||
super.a(Integer.MAX_VALUE, true, true);
|
||||
+ post.forEach(entry -> entry.getSecond().run());
|
||||
|
||||
- super.a(Integer.MAX_VALUE, true, true);
|
||||
-
|
||||
- for (j = 0; objectlistiterator.hasNext() && j < i; ++j) {
|
||||
- pair = (Pair) objectlistiterator.next();
|
||||
- if (pair.getFirst() == LightEngineThreaded.Update.POST_UPDATE) {
|
||||
|
@ -1193,14 +1298,53 @@ index 8776799de033f02b0f87e9ea7e4a4ce912e94dd4..72cc711d6c2645aed44f208ee44f8702
|
|||
- }
|
||||
-
|
||||
- objectlistiterator.remove();
|
||||
- }
|
||||
+ if (!urgent && this.c.isEmpty()) nextNonUrgent = System.nanoTime() + (50 * 1000000);
|
||||
+ java.util.List<Runnable> pre = new java.util.ArrayList<>();
|
||||
+ java.util.List<Runnable> post = new java.util.ArrayList<>();
|
||||
+ int i = Math.min(queue.size(), 4);
|
||||
+ while (i-- > 0 && queue.poll(pre, post)) {
|
||||
+ pre.forEach(Runnable::run);
|
||||
+ pre.clear();
|
||||
+ super.a(Integer.MAX_VALUE, true, true);
|
||||
+ post.forEach(Runnable::run);
|
||||
+ post.clear();
|
||||
}
|
||||
-
|
||||
+ // Paper end
|
||||
|
||||
}
|
||||
|
||||
public void a(int i) {
|
||||
diff --git a/src/main/java/net/minecraft/server/NibbleArray.java b/src/main/java/net/minecraft/server/NibbleArray.java
|
||||
index 8cedfdd820cc02a76607b53e0b054fc74654f907..a9795394c9b17f9f0ce4c4f9c8f51a48e950418e 100644
|
||||
--- a/src/main/java/net/minecraft/server/NibbleArray.java
|
||||
+++ b/src/main/java/net/minecraft/server/NibbleArray.java
|
||||
@@ -8,6 +8,13 @@ import javax.annotation.Nullable;
|
||||
public class NibbleArray {
|
||||
|
||||
// Paper start
|
||||
+ static final NibbleArray EMPTY_NIBBLE_ARRAY = new NibbleArray() {
|
||||
+ @Override
|
||||
+ public byte[] asBytes() {
|
||||
+ throw new IllegalStateException();
|
||||
+ }
|
||||
+ };
|
||||
+ long lightCacheKey = Long.MIN_VALUE;
|
||||
public static byte[] EMPTY_NIBBLE = new byte[2048];
|
||||
private static final int nibbleBucketSizeMultiplier = Integer.getInteger("Paper.nibbleBucketSize", 3072);
|
||||
private static final int maxPoolSize = Integer.getInteger("Paper.maxNibblePoolSize", (int) Math.min(6, Math.max(1, Runtime.getRuntime().maxMemory() / 1024 / 1024 / 1024)) * (nibbleBucketSizeMultiplier * 8));
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunk.java b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
index f8820f24075e7f42f67426fc9ecf5238f4499b72..0ef55c49235f8e024268b5411eeaf4ddc76c921d 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunk.java
|
||||
@@ -729,6 +729,7 @@ public class PlayerChunk {
|
||||
ioPriority = com.destroystokyo.paper.io.PrioritizedTaskQueue.HIGH_PRIORITY;
|
||||
}
|
||||
chunkMap.world.asyncChunkTaskManager.raisePriority(location.x, location.z, ioPriority);
|
||||
+ chunkMap.world.getChunkProvider().getLightEngine().changePriority(location.pair(), getCurrentPriority(), priority);
|
||||
}
|
||||
if (getCurrentPriority() != priority) {
|
||||
this.w.a(this.location, this::getCurrentPriority, priority, this::setPriority); // use preferred priority
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
index babac7a8513a1f7698ef2fb7263f13f8f3c9717c..e00692f0e19798798b1bc38c8c4c53be71447b21 100644
|
||||
index 394cea57b3871c2e11d1f7e0e9546df64ff3bafe..8abf276a325cbc3a863fb89276526790c4de2692 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java
|
||||
@@ -629,6 +629,7 @@ public class PlayerChunkMap extends IChunkLoader implements PlayerChunk.d {
|
||||
|
@ -1211,3 +1355,29 @@ index babac7a8513a1f7698ef2fb7263f13f8f3c9717c..e00692f0e19798798b1bc38c8c4c53be
|
|||
protected IntSupplier c(long i) {
|
||||
return () -> {
|
||||
PlayerChunk playerchunk = this.getVisibleChunk(i);
|
||||
diff --git a/src/main/java/net/minecraft/server/ThreadedMailbox.java b/src/main/java/net/minecraft/server/ThreadedMailbox.java
|
||||
index 8082569022384a3ba03fb4a6f1ae12b443598dcb..3db8073f5182fe4dd4c710b202afc323dfb9b2d2 100644
|
||||
--- a/src/main/java/net/minecraft/server/ThreadedMailbox.java
|
||||
+++ b/src/main/java/net/minecraft/server/ThreadedMailbox.java
|
||||
@@ -93,7 +93,8 @@ public class ThreadedMailbox<T> implements Mailbox<T>, AutoCloseable, Runnable {
|
||||
|
||||
}
|
||||
|
||||
- @Override
|
||||
+
|
||||
+ public void queue(T t0) { a(t0); } @Override // Paper - OBFHELPER
|
||||
public void a(T t0) {
|
||||
this.a.a(t0);
|
||||
this.f();
|
||||
diff --git a/src/main/java/net/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
index 49da7352dcee6c352904cabe8b5db0152c427029..46e261b6513b52f5562387b661de4a409ea515a3 100644
|
||||
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
||||
@@ -685,6 +685,7 @@ public class WorldServer extends World {
|
||||
}
|
||||
gameprofilerfiller.exit();
|
||||
timings.chunkTicksBlocks.stopTiming(); // Paper
|
||||
+ getChunkProvider().getLightEngine().queueUpdate(); // Paper
|
||||
// Paper end
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue