Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
From 9cf6515af10a67c0778bbd697d12254907ad766a Mon Sep 17 00:00:00 2001
|
2016-03-25 06:38:38 +00:00
|
|
|
From: Byteflux <byte@byteflux.net>
|
|
|
|
Date: Wed, 2 Mar 2016 00:52:31 -0600
|
|
|
|
Subject: [PATCH] Lighting Queue
|
|
|
|
|
2016-07-15 22:36:53 +00:00
|
|
|
This provides option to queue lighting updates to ensure they do not cause the server lag
|
2016-03-25 06:38:38 +00:00
|
|
|
|
2016-05-15 22:48:39 +00:00
|
|
|
diff --git a/src/main/java/co/aikar/timings/WorldTimingsHandler.java b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
|
2018-09-08 03:49:37 +00:00
|
|
|
index 145cb274b0..eff9dcf54f 100644
|
2016-05-15 22:48:39 +00:00
|
|
|
--- a/src/main/java/co/aikar/timings/WorldTimingsHandler.java
|
|
|
|
+++ b/src/main/java/co/aikar/timings/WorldTimingsHandler.java
|
2018-07-15 01:53:17 +00:00
|
|
|
@@ -50,6 +50,8 @@ public class WorldTimingsHandler {
|
2017-08-12 21:32:01 +00:00
|
|
|
public final Timing worldSaveLevel;
|
2016-10-21 20:42:49 +00:00
|
|
|
public final Timing chunkSaveData;
|
2016-03-25 06:38:38 +00:00
|
|
|
|
2016-05-15 22:48:39 +00:00
|
|
|
+ public final Timing lightingQueueTimer;
|
|
|
|
+
|
|
|
|
public WorldTimingsHandler(World server) {
|
|
|
|
String name = server.worldData.getName() +" - ";
|
|
|
|
|
2018-07-15 01:53:17 +00:00
|
|
|
@@ -96,6 +98,8 @@ public class WorldTimingsHandler {
|
2016-05-15 22:48:39 +00:00
|
|
|
tracker2 = Timings.ofSafe(name + "tracker stage 2");
|
|
|
|
doTick = Timings.ofSafe(name + "doTick");
|
|
|
|
tickEntities = Timings.ofSafe(name + "tickEntities");
|
|
|
|
+
|
|
|
|
+ lightingQueueTimer = Timings.ofSafe(name + "Lighting Queue");
|
|
|
|
}
|
2018-07-15 01:53:17 +00:00
|
|
|
|
|
|
|
public static Timing getTickList(WorldServer worldserver, String timingsType) {
|
2016-03-25 06:38:38 +00:00
|
|
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
index 39d565db1f..9fd1bde0ef 100644
|
2016-03-25 06:38:38 +00:00
|
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
|
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
2018-07-24 00:24:44 +00:00
|
|
|
@@ -130,4 +130,10 @@ public class PaperWorldConfig {
|
2016-03-31 00:50:23 +00:00
|
|
|
netherVoidTopDamage = getBoolean( "nether-ceiling-void-damage", false );
|
|
|
|
log("Top of the nether void damage: " + netherVoidTopDamage);
|
2016-03-25 06:38:38 +00:00
|
|
|
}
|
2016-03-31 00:50:23 +00:00
|
|
|
+
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
+ public boolean queueLightUpdates = true; // This doesn't need to be configurable, it's not buggy.
|
2016-03-25 06:38:38 +00:00
|
|
|
+ private void queueLightUpdates() {
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
+ //queueLightUpdates = getBoolean("queue-light-updates", false);
|
|
|
|
+ //log("Lighting Queue enabled: " + queueLightUpdates);
|
2016-03-25 06:38:38 +00:00
|
|
|
+ }
|
|
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
index 4622e92b05..703c377f93 100644
|
2016-03-25 06:38:38 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/Chunk.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/Chunk.java
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
@@ -38,7 +38,7 @@ public class Chunk implements IChunkAccess {
|
|
|
|
public final Map<HeightMap.Type, HeightMap> heightMap;
|
|
|
|
public final int locX;
|
|
|
|
public final int locZ;
|
|
|
|
- private boolean l;
|
|
|
|
+ private boolean l; public boolean needsGapCheck() { return l; } // Paper - OBFHELPER
|
|
|
|
private final ChunkConverter m;
|
|
|
|
public final Map<BlockPosition, TileEntity> tileEntities;
|
|
|
|
public final List<Entity>[] entitySlices; // Spigot
|
2018-08-26 18:11:49 +00:00
|
|
|
@@ -90,6 +90,7 @@ public class Chunk implements IChunkAccess {
|
2018-07-04 07:55:24 +00:00
|
|
|
return removed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
+ final PaperLightingQueue.LightingQueue lightingQueue = new PaperLightingQueue.LightingQueue(this);
|
|
|
|
// Paper end
|
2018-07-15 01:53:17 +00:00
|
|
|
public boolean areNeighborsLoaded(final int radius) {
|
|
|
|
switch (radius) {
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
@@ -277,6 +278,7 @@ public class Chunk implements IChunkAccess {
|
|
|
|
this.l = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ private void recheckGaps(boolean flag) { g(flag); } // Paper - OBFHELPER
|
2018-07-15 01:53:17 +00:00
|
|
|
private void g(boolean flag) {
|
2016-03-25 06:38:38 +00:00
|
|
|
this.world.methodProfiler.a("recheckGaps");
|
|
|
|
if (this.world.areChunksLoaded(new BlockPosition(this.locX * 16 + 8, 0, this.locZ * 16 + 8), 16)) {
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
@@ -530,6 +532,7 @@ public class Chunk implements IChunkAccess {
|
2018-07-15 01:53:17 +00:00
|
|
|
if (flag1) {
|
2016-03-25 06:38:38 +00:00
|
|
|
this.initLighting();
|
2017-12-22 21:25:01 +00:00
|
|
|
} else {
|
|
|
|
+ this.runOrQueueLightUpdate(() -> { // Paper - Queue light update
|
2018-07-15 01:53:17 +00:00
|
|
|
int i1 = iblockdata.b(this.world, blockposition);
|
|
|
|
int j1 = iblockdata1.b(this.world, blockposition);
|
2016-03-25 06:38:38 +00:00
|
|
|
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
@@ -537,6 +540,7 @@ public class Chunk implements IChunkAccess {
|
2018-07-15 01:53:17 +00:00
|
|
|
if (i1 != j1 && (i1 < j1 || this.getBrightness(EnumSkyBlock.SKY, blockposition) > 0 || this.getBrightness(EnumSkyBlock.BLOCK, blockposition) > 0)) {
|
|
|
|
this.c(i, k);
|
2016-03-25 06:38:38 +00:00
|
|
|
}
|
2016-05-15 22:48:39 +00:00
|
|
|
+ }); // Paper
|
2016-03-25 06:38:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TileEntity tileentity;
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
@@ -974,10 +978,16 @@ public class Chunk implements IChunkAccess {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
- public void d(boolean flag) {
|
|
|
|
- if (this.l && this.world.worldProvider.g() && !flag) {
|
|
|
|
- this.g(this.world.isClientSide);
|
|
|
|
+ // Paper start
|
|
|
|
+ private boolean shouldRecheckGaps = false;
|
|
|
|
+ public void doGapCheck() {
|
|
|
|
+ if (shouldRecheckGaps) {
|
|
|
|
+ this.recheckGaps(false);
|
|
|
|
+ shouldRecheckGaps = false;
|
|
|
|
}
|
|
|
|
+ }
|
|
|
|
+ public void d(boolean flag) {
|
|
|
|
+ shouldRecheckGaps = this.needsGapCheck() && this.world.worldProvider.hasNaturalLight() && !flag; // Paper
|
|
|
|
|
|
|
|
this.u = true;
|
|
|
|
|
2018-08-27 15:07:22 +00:00
|
|
|
@@ -1307,6 +1317,16 @@ public class Chunk implements IChunkAccess {
|
2018-08-26 18:11:49 +00:00
|
|
|
return this.D == 8;
|
2017-12-22 21:25:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
+ // Paper start
|
|
|
|
+ public void runOrQueueLightUpdate(Runnable runnable) {
|
|
|
|
+ if (this.world.paperConfig.queueLightUpdates) {
|
|
|
|
+ lightingQueue.add(runnable);
|
|
|
|
+ } else {
|
|
|
|
+ runnable.run();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // Paper end
|
|
|
|
+
|
|
|
|
public static enum EnumTileEntityState {
|
|
|
|
|
|
|
|
IMMEDIATE, QUEUED, CHECK;
|
2016-03-25 06:38:38 +00:00
|
|
|
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
2018-09-18 02:32:37 +00:00
|
|
|
index 68212aa26e..046973a4ed 100644
|
2016-03-25 06:38:38 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
|
2018-08-26 18:11:49 +00:00
|
|
|
@@ -314,6 +314,7 @@ public class ChunkProviderServer implements IChunkProvider {
|
2016-06-23 02:18:41 +00:00
|
|
|
return false;
|
|
|
|
}
|
2016-07-13 04:22:58 +00:00
|
|
|
save = event.isSaveChunk();
|
2016-06-23 02:18:41 +00:00
|
|
|
+ chunk.lightingQueue.processUnload(); // Paper
|
2016-03-25 06:38:38 +00:00
|
|
|
|
2016-06-23 02:18:41 +00:00
|
|
|
// Update neighbor counts
|
|
|
|
for (int x = -2; x < 3; x++) {
|
2016-03-25 06:38:38 +00:00
|
|
|
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
2018-09-18 02:32:37 +00:00
|
|
|
index d6ea4ae532..5086fe4027 100644
|
2016-03-25 06:38:38 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
2018-09-18 02:32:37 +00:00
|
|
|
@@ -894,7 +894,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
2018-08-26 18:11:49 +00:00
|
|
|
protected void a(BooleanSupplier booleansupplier) {
|
2016-05-15 22:48:39 +00:00
|
|
|
co.aikar.timings.TimingsManager.FULL_SERVER_TICK.startTiming(); // Paper
|
2017-01-31 04:33:54 +00:00
|
|
|
this.slackActivityAccountant.tickStarted(); // Spigot
|
2018-07-15 01:53:17 +00:00
|
|
|
- long i = SystemUtils.c();
|
|
|
|
+ long i = SystemUtils.c(); long startTime = i; // Paper
|
2016-03-25 06:38:38 +00:00
|
|
|
|
2016-05-15 22:48:39 +00:00
|
|
|
++this.ticks;
|
2018-07-15 01:53:17 +00:00
|
|
|
if (this.S) {
|
2018-09-18 02:32:37 +00:00
|
|
|
@@ -952,6 +952,7 @@ public abstract class MinecraftServer implements IAsyncTaskHandler, IMojangStati
|
2018-07-15 01:53:17 +00:00
|
|
|
this.methodProfiler.e();
|
|
|
|
this.methodProfiler.e();
|
2016-05-15 22:48:39 +00:00
|
|
|
org.spigotmc.WatchdogThread.tick(); // Spigot
|
|
|
|
+ PaperLightingQueue.processQueue(startTime); // Paper
|
2018-07-15 01:53:17 +00:00
|
|
|
this.slackActivityAccountant.tickEnded(l); // Spigot
|
2016-05-15 22:48:39 +00:00
|
|
|
co.aikar.timings.TimingsManager.FULL_SERVER_TICK.stopTiming(); // Paper
|
|
|
|
}
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/PaperLightingQueue.java b/src/main/java/net/minecraft/server/PaperLightingQueue.java
|
|
|
|
new file mode 100644
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
index 0000000000..f3d6eb7694
|
2016-05-15 22:48:39 +00:00
|
|
|
--- /dev/null
|
|
|
|
+++ b/src/main/java/net/minecraft/server/PaperLightingQueue.java
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
@@ -0,0 +1,91 @@
|
2016-05-15 22:48:39 +00:00
|
|
|
+package net.minecraft.server;
|
|
|
|
+
|
|
|
|
+import co.aikar.timings.Timing;
|
2017-01-02 19:08:55 +00:00
|
|
|
+import it.unimi.dsi.fastutil.objects.ObjectCollection;
|
|
|
|
+
|
2016-05-15 22:48:39 +00:00
|
|
|
+import java.util.ArrayDeque;
|
2016-03-25 06:38:38 +00:00
|
|
|
+
|
2016-05-15 22:48:39 +00:00
|
|
|
+class PaperLightingQueue {
|
|
|
|
+ private static final long MAX_TIME = (long) (1000000000 / 20 * .95);
|
|
|
|
+
|
|
|
|
+ static void processQueue(long curTime) {
|
|
|
|
+ final long startTime = System.nanoTime();
|
|
|
|
+ final long maxTickTime = MAX_TIME - (startTime - curTime);
|
|
|
|
+
|
|
|
|
+ START:
|
2018-08-26 18:11:49 +00:00
|
|
|
+ for (World world : MinecraftServer.getServer().getWorlds()) {
|
2016-05-15 22:48:39 +00:00
|
|
|
+ if (!world.paperConfig.queueLightUpdates) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
2017-01-02 19:08:55 +00:00
|
|
|
+ ObjectCollection<Chunk> loadedChunks = ((WorldServer) world).getChunkProviderServer().chunks.values();
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
+ for (Chunk chunk : loadedChunks.toArray(new Chunk[0])) {
|
2016-05-15 22:48:39 +00:00
|
|
|
+ if (chunk.lightingQueue.processQueue(startTime, maxTickTime)) {
|
|
|
|
+ break START;
|
2016-03-25 06:38:38 +00:00
|
|
|
+ }
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
+ chunk.doGapCheck();
|
2016-03-25 06:38:38 +00:00
|
|
|
+ }
|
2016-05-15 22:48:39 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
2016-03-25 06:38:38 +00:00
|
|
|
+
|
2016-05-15 22:48:39 +00:00
|
|
|
+ static class LightingQueue extends ArrayDeque<Runnable> {
|
|
|
|
+ final private Chunk chunk;
|
|
|
|
+
|
|
|
|
+ LightingQueue(Chunk chunk) {
|
|
|
|
+ super();
|
|
|
|
+ this.chunk = chunk;
|
2016-03-25 06:38:38 +00:00
|
|
|
+ }
|
|
|
|
+
|
2016-05-15 22:48:39 +00:00
|
|
|
+ /**
|
|
|
|
+ * Processes the lighting queue for this chunk
|
|
|
|
+ *
|
|
|
|
+ * @param startTime If start Time is 0, we will not limit execution time
|
|
|
|
+ * @param maxTickTime Maximum time to spend processing lighting updates
|
|
|
|
+ * @return true to abort processing furthur lighting updates
|
|
|
|
+ */
|
|
|
|
+ private boolean processQueue(long startTime, long maxTickTime) {
|
|
|
|
+ if (this.isEmpty()) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ try (Timing ignored = chunk.world.timings.lightingQueueTimer.startTiming()) {
|
|
|
|
+ Runnable lightUpdate;
|
|
|
|
+ while ((lightUpdate = this.poll()) != null) {
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
+ if (startTime > 0 && isOutOfTime(maxTickTime, System.nanoTime() - startTime)) {
|
|
|
|
+ return true;
|
2016-05-15 22:48:39 +00:00
|
|
|
+ }
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
+ lightUpdate.run();
|
2016-05-15 22:48:39 +00:00
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Flushes lighting updates to unload the chunk
|
|
|
|
+ */
|
|
|
|
+ void processUnload() {
|
|
|
|
+ if (!chunk.world.paperConfig.queueLightUpdates) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ processQueue(0, 0); // No timeout
|
|
|
|
+
|
|
|
|
+ final int radius = 1; // TODO: bitflip, why should this ever be 2?
|
|
|
|
+ for (int x = chunk.locX - radius; x <= chunk.locX + radius; ++x) {
|
|
|
|
+ for (int z = chunk.locZ - radius; z <= chunk.locZ + radius; ++z) {
|
|
|
|
+ if (x == chunk.locX && z == chunk.locZ) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ Chunk neighbor = MCUtil.getLoadedChunkWithoutMarkingActive(chunk.world, x, z);
|
|
|
|
+ if (neighbor != null) {
|
|
|
|
+ neighbor.lightingQueue.processQueue(0, 0); // No timeout
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
+
|
|
|
|
+ private static boolean isOutOfTime(long maxTickTime, long l) {
|
|
|
|
+ return l > maxTickTime;
|
|
|
|
+ }
|
2016-05-15 22:48:39 +00:00
|
|
|
+}
|
2016-03-25 06:38:38 +00:00
|
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
2018-09-18 02:32:37 +00:00
|
|
|
index 499d64ea2c..e06da6bef9 100644
|
2016-03-25 06:38:38 +00:00
|
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
2018-08-26 18:11:49 +00:00
|
|
|
@@ -335,7 +335,7 @@ public abstract class World implements IEntityAccess, GeneratorAccess, IIBlockAc
|
2018-07-15 01:53:17 +00:00
|
|
|
|
|
|
|
if (iblockdata2.b(this, blockposition) != iblockdata1.b(this, blockposition) || iblockdata2.e() != iblockdata1.e()) {
|
2016-03-25 06:38:38 +00:00
|
|
|
this.methodProfiler.a("checkLight");
|
2018-07-15 01:53:17 +00:00
|
|
|
- this.r(blockposition);
|
|
|
|
+ chunk.runOrQueueLightUpdate(() -> this.r(blockposition)); // Paper - Queue light update
|
|
|
|
this.methodProfiler.e();
|
2016-03-25 06:38:38 +00:00
|
|
|
}
|
|
|
|
|
Improve Light Queue and force enable it for all
There is no reason for the light queue to even be an option. This
enables the light queue for everyone.
This also improves the "can we still tick" time logic to always
check before running a light operation.
previously, we always executed at least 10 on the first world
(but not other worlds...), but we are seeing light take up some
heavy time, so improving that for now.
I've now also improved recheck gaps logic to happen at the end of all single block updates
This also prevents multiple gap checks, as previously if a tick skipped
the gaps check, the next tick would end up re-adding the entry again,
resulting in multiple gap checks.
This now just sets a marker "We need to recheck gaps" and will only occur
once.
This also should reduce chunk loads, as previously, we checked if
the neighbor chunks were loaded for the gap check, however those
neighbor chunks might of unloaded before the light queue operation
actually ran. Now, the neighbor chunk is done when the gap check
is being done, so it should avoid loading chunks.
Fixes #1466
Fixes #1431
2018-09-22 15:46:31 +00:00
|
|
|
diff --git a/src/main/java/net/minecraft/server/WorldProvider.java b/src/main/java/net/minecraft/server/WorldProvider.java
|
|
|
|
index 517b1e7124..53ce7d5e11 100644
|
|
|
|
--- a/src/main/java/net/minecraft/server/WorldProvider.java
|
|
|
|
+++ b/src/main/java/net/minecraft/server/WorldProvider.java
|
|
|
|
@@ -7,7 +7,7 @@ public abstract class WorldProvider {
|
|
|
|
protected World b;
|
|
|
|
protected boolean c;
|
|
|
|
protected boolean d;
|
|
|
|
- protected boolean e;
|
|
|
|
+ protected boolean e; public boolean hasNaturalLight() { return e; } // Paper - OBFHELPER
|
|
|
|
protected final float[] f = new float[16];
|
|
|
|
private final float[] g = new float[4];
|
|
|
|
|
2016-03-25 06:38:38 +00:00
|
|
|
--
|
2018-09-18 02:32:37 +00:00
|
|
|
2.19.0
|
2016-03-25 06:38:38 +00:00
|
|
|
|