Paper/Spigot-Server-Patches/0030-Configurable-async-light-updates.patch

243 lines
9.4 KiB
Diff
Raw Normal View History

2016-03-03 10:46:26 +01:00
From 229a02dbfcc982bb407cd6044c935c71a9dcd913 Mon Sep 17 00:00:00 2001
2015-07-01 09:27:58 +02:00
From: Byteflux <byte@byteflux.net>
2016-03-01 00:09:49 +01:00
Date: Wed, 2 Mar 2016 00:52:31 -0600
2015-04-18 10:30:12 +02:00
Subject: [PATCH] Configurable async light updates
2016-03-01 00:09:49 +01:00
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
2016-03-03 10:46:26 +01:00
index 28e3e3c..402ed0a 100644
2016-03-01 00:09:49 +01:00
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -158,4 +158,9 @@ public class PaperWorldConfig {
}
+ public boolean useAsyncLighting;
+ private void useAsyncLighting() {
+ useAsyncLighting = getBoolean( "use-async-lighting", false );
+ log("World async lighting: " + useAsyncLighting);
+ }
}
2015-07-01 09:27:58 +02:00
diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java
2016-03-01 00:09:49 +01:00
index 2f37957..3e9b26f 100644
2015-07-01 09:27:58 +02:00
--- a/src/main/java/net/minecraft/server/Chunk.java
+++ b/src/main/java/net/minecraft/server/Chunk.java
@@ -11,6 +11,8 @@ import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedQueue;
2016-03-01 00:09:49 +01:00
+import java.util.concurrent.atomic.AtomicInteger; // Paper
2015-07-01 09:27:58 +02:00
+
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
2016-03-01 00:09:49 +01:00
@@ -44,6 +46,10 @@ public class Chunk {
private int w;
private ConcurrentLinkedQueue<BlockPosition> x;
2015-07-01 09:27:58 +02:00
protected gnu.trove.map.hash.TObjectIntHashMap<Class> entityCount = new gnu.trove.map.hash.TObjectIntHashMap<Class>(); // Spigot
2016-03-01 00:09:49 +01:00
+ // Paper start - Asynchronous light updates
2015-07-01 09:27:58 +02:00
+ public AtomicInteger pendingLightUpdates = new AtomicInteger();
+ public long lightUpdateTime;
2016-03-01 00:09:49 +01:00
+ // Paper end
2015-07-01 09:27:58 +02:00
// CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking
private int neighbors = 0x1 << 12;
2016-03-01 00:09:49 +01:00
@@ -278,7 +284,7 @@ public class Chunk {
2015-07-01 09:27:58 +02:00
private void a(int i, int j, int k, int l) {
if (l > k && this.world.areChunksLoaded(new BlockPosition(i, 0, j), 16)) {
for (int i1 = k; i1 < l; ++i1) {
- this.world.c(EnumSkyBlock.SKY, new BlockPosition(i, i1, j));
2016-03-01 00:09:49 +01:00
+ this.world.updateLight(EnumSkyBlock.SKY, new BlockPosition(i, i1, j));
2015-07-01 09:27:58 +02:00
}
2016-03-01 00:09:49 +01:00
this.r = true;
@@ -991,7 +997,7 @@ public class Chunk {
public void b(boolean flag) {
2016-03-01 00:09:49 +01:00
if (this.l && !this.world.worldProvider.m() && !flag) {
- this.h(this.world.isClientSide);
2016-03-01 00:09:49 +01:00
+ this.recheckGaps(this.world.isClientSide); // Paper - Asynchronous lighting updates
}
2016-03-01 00:09:49 +01:00
this.q = true;
@@ -1012,6 +1018,23 @@ public class Chunk {
}
+ /**
2016-03-01 00:09:49 +01:00
+ * Paper- Recheck gaps asynchronously
+ */
+ public void recheckGaps(final boolean isClientSide) {
2016-03-01 00:09:49 +01:00
+ if (!world.paperConfig.useAsyncLighting) {
+ this.h(this.world.isClientSide);
+ return;
+ }
+
+ world.lightingExecutor.submit(new Runnable() {
+ @Override
+ public void run() {
+ Chunk.this.h(isClientSide);
+ }
+ });
+ }
+
public boolean isReady() {
// Spigot Start
/*
2015-07-01 09:27:58 +02:00
diff --git a/src/main/java/net/minecraft/server/ChunkProviderServer.java b/src/main/java/net/minecraft/server/ChunkProviderServer.java
2016-03-03 10:46:26 +01:00
index 21e7709..1f99e85 100644
2015-07-01 09:27:58 +02:00
--- a/src/main/java/net/minecraft/server/ChunkProviderServer.java
+++ b/src/main/java/net/minecraft/server/ChunkProviderServer.java
2016-03-01 00:09:49 +01:00
@@ -46,6 +46,12 @@ public class ChunkProviderServer implements IChunkProvider {
2015-07-01 09:27:58 +02:00
}
public void queueUnload(int i, int j) {
2016-03-01 00:09:49 +01:00
+ // Paper start - Asynchronous lighting updates
2015-07-01 09:27:58 +02:00
+ Chunk chunk = chunks.get(LongHash.toLong(i, j));
2016-03-01 00:09:49 +01:00
+ if (chunk != null && chunk.world.paperConfig.useAsyncLighting && (chunk.pendingLightUpdates.get() > 0 || chunk.world.getTime() - chunk.lightUpdateTime < 20)) {
2015-07-01 09:27:58 +02:00
+ return;
+ }
2016-03-01 00:09:49 +01:00
+ // Paper end
if (this.world.worldProvider.c(i, j)) {
// CraftBukkit start
this.unloadQueue.add(i, j);
2015-04-18 10:30:12 +02:00
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
2016-03-03 10:46:26 +01:00
index 58abd10..bbdfb3b 100644
2015-04-18 10:30:12 +02:00
--- a/src/main/java/net/minecraft/server/World.java
+++ b/src/main/java/net/minecraft/server/World.java
2016-03-01 00:09:49 +01:00
@@ -29,6 +29,12 @@ import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.generator.ChunkGenerator;
// CraftBukkit end
2015-04-18 10:30:12 +02:00
2016-03-01 00:09:49 +01:00
+// Paper start
2015-04-18 10:30:12 +02:00
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
2016-03-01 00:09:49 +01:00
+// Paper end
2015-04-18 10:30:12 +02:00
+
2016-03-01 00:09:49 +01:00
public abstract class World implements IBlockAccess {
2015-05-19 01:41:57 +02:00
2016-03-01 00:09:49 +01:00
private int a = 63;
@@ -134,6 +140,7 @@ public abstract class World implements IBlockAccess {
private org.spigotmc.TickLimiter entityLimiter;
private org.spigotmc.TickLimiter tileLimiter;
2015-07-01 09:27:58 +02:00
private int tileTickPosition;
2016-03-01 00:09:49 +01:00
+ public ExecutorService lightingExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat("Paper - Lighting Thread").build()); // Paper - Asynchronous lighting updates
2015-07-01 09:27:58 +02:00
2016-03-01 00:09:49 +01:00
public CraftWorld getWorld() {
return this.world;
2016-03-03 10:46:26 +01:00
@@ -450,7 +457,7 @@ public abstract class World implements IBlockAccess {
2015-07-01 09:27:58 +02:00
2016-03-01 00:09:49 +01:00
if (!this.worldProvider.m()) {
2015-07-01 09:27:58 +02:00
for (i1 = k; i1 <= l; ++i1) {
- this.c(EnumSkyBlock.SKY, new BlockPosition(i, i1, j));
2016-03-01 00:09:49 +01:00
+ this.updateLight(EnumSkyBlock.SKY, new BlockPosition(i, i1, j)); // Paper - Asynchronous lighting updates
2015-07-01 09:27:58 +02:00
}
2015-04-18 10:30:12 +02:00
}
2016-03-03 10:46:26 +01:00
@@ -2218,10 +2225,10 @@ public abstract class World implements IBlockAccess {
2015-07-01 09:27:58 +02:00
boolean flag = false;
2016-03-01 00:09:49 +01:00
if (!this.worldProvider.m()) {
2015-07-01 09:27:58 +02:00
- flag |= this.c(EnumSkyBlock.SKY, blockposition);
2016-03-01 00:09:49 +01:00
+ flag |= this.updateLight(EnumSkyBlock.SKY, blockposition); // Paper - Asynchronous lighting updates
2015-04-18 10:30:12 +02:00
}
2015-07-01 09:27:58 +02:00
- flag |= this.c(EnumSkyBlock.BLOCK, blockposition);
2016-03-01 00:09:49 +01:00
+ flag |= this.updateLight(EnumSkyBlock.BLOCK, blockposition); // Paper - Asynchronous lighting updates
2015-07-01 09:27:58 +02:00
return flag;
2015-04-18 10:30:12 +02:00
}
2016-03-03 10:46:26 +01:00
@@ -2271,10 +2278,15 @@ public abstract class World implements IBlockAccess {
2015-04-18 10:30:12 +02:00
}
}
2016-03-01 00:09:49 +01:00
+ // Paper start - Asynchronous lighting updates
public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition) {
+ return this.c(enumskyblock, blockposition, null, null);
+ }
+
+ public boolean c(EnumSkyBlock enumskyblock, BlockPosition blockposition, Chunk chunk, List<Chunk> neighbors) { // Paper
2015-07-01 09:27:58 +02:00
// CraftBukkit start - Use neighbor cache instead of looking up
2015-04-18 10:30:12 +02:00
- Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4);
- if (chunk == null || !chunk.areNeighborsLoaded(1) /*!this.areChunksLoaded(blockposition, 17, false)*/) {
2015-07-01 09:27:58 +02:00
+ //Chunk chunk = this.getChunkIfLoaded(blockposition.getX() >> 4, blockposition.getZ() >> 4);
+ if (chunk == null /*|| !chunk.areNeighborsLoaded(1)*/ /*!this.areChunksLoaded(blockposition, 17, false)*/) {
// CraftBukkit end
return false;
} else {
2016-03-03 10:46:26 +01:00
@@ -2345,6 +2357,17 @@ public abstract class World implements IBlockAccess {
2016-03-01 00:09:49 +01:00
i = 0;
2015-07-01 09:27:58 +02:00
}
2015-04-18 10:30:12 +02:00
2016-03-01 00:09:49 +01:00
+ // Paper start - Asynchronous light updates
+ if (chunk.world.paperConfig.useAsyncLighting) {
2015-07-01 09:27:58 +02:00
+ chunk.pendingLightUpdates.decrementAndGet();
+ if (neighbors != null) {
+ for (Chunk neighbor : neighbors) {
+ neighbor.pendingLightUpdates.decrementAndGet();
2015-04-18 10:30:12 +02:00
+ }
2015-07-01 09:27:58 +02:00
+ }
+ }
2016-03-01 00:09:49 +01:00
+ // Paper end
+
2015-07-01 09:27:58 +02:00
this.methodProfiler.b();
2016-03-01 00:09:49 +01:00
this.methodProfiler.a("checkedPosition < toCheckCount");
2016-03-03 10:46:26 +01:00
@@ -2399,6 +2422,52 @@ public abstract class World implements IBlockAccess {
2015-07-01 09:27:58 +02:00
}
}
2015-04-18 10:30:12 +02:00
2015-07-01 09:27:58 +02:00
+ /**
2016-03-01 00:09:49 +01:00
+ * Paper - Asynchronous lighting updates
2015-07-01 09:27:58 +02:00
+ */
+ public boolean updateLight(final EnumSkyBlock enumskyblock, final BlockPosition position) {
+ int x = position.getX();
+ int z = position.getZ();
+ final Chunk chunk = this.getChunkIfLoaded(x >> 4, z >> 4);
+ if (chunk == null || !chunk.areNeighborsLoaded(1)) {
2015-07-01 09:27:58 +02:00
+ return false;
+ }
2015-04-18 10:30:12 +02:00
+
2016-03-01 00:09:49 +01:00
+ if (!chunk.world.paperConfig.useAsyncLighting) {
2015-07-01 09:27:58 +02:00
+ return this.c(enumskyblock, position, chunk, null);
+ }
2015-04-18 10:30:12 +02:00
+
2015-07-01 09:27:58 +02:00
+ chunk.pendingLightUpdates.incrementAndGet();
+ chunk.lightUpdateTime = chunk.world.getTime();
2015-04-18 10:30:12 +02:00
+
2015-07-01 09:27:58 +02:00
+ final List<Chunk> neighbors = new ArrayList<Chunk>();
2016-03-01 00:09:49 +01:00
+
+ for (int cx = (x >> 4) - 1; cx <= (x >> 4) + 1; ++cx) {
+ for (int cz = (z >> 4) - 1; cz <= (z >> 4) + 1; ++cz) {
+ if (cx != x >> 4 && cz != z >> 4) {
+ Chunk neighbor = this.getChunkIfLoaded(cx, cz);
+ if (neighbor != null) {
2015-07-01 09:27:58 +02:00
+ neighbor.pendingLightUpdates.incrementAndGet();
+ neighbor.lightUpdateTime = chunk.world.getTime();
+ neighbors.add(neighbor);
+ }
+ }
2015-04-18 10:30:12 +02:00
+ }
2015-07-01 09:27:58 +02:00
+ }
+
+ if (!Bukkit.isPrimaryThread()) {
+ return this.c(enumskyblock, position, chunk, neighbors);
+ }
+
2015-07-01 09:27:58 +02:00
+ lightingExecutor.submit(new Runnable() {
+ @Override
+ public void run() {
+ World.this.c(enumskyblock, position, chunk, neighbors);
+ }
+ });
2015-04-18 10:30:12 +02:00
+ return true;
2015-07-01 09:27:58 +02:00
+ }
+
2015-04-18 10:30:12 +02:00
public boolean a(boolean flag) {
return false;
2015-07-01 09:27:58 +02:00
}
2015-04-18 10:30:12 +02:00
--
2016-03-01 00:09:49 +01:00
2.7.2
2015-04-18 10:30:12 +02:00