mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-28 07:20:24 +01:00
Finish updating chunk system patch
Add in locking changes from folia, plus fix some diffs. I'm sure it'll be error-free.
This commit is contained in:
parent
dc11e08746
commit
e031042af5
6 changed files with 3796 additions and 20229 deletions
|
@ -127,6 +127,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
- if (!this.player.noPhysics && !this.player.isSleeping() && (flag2 && worldserver.noCollision(this.player, axisalignedbb) || this.isPlayerCollidingWithAnythingNew(worldserver, axisalignedbb, d0, d1, d2))) {
|
||||
+ // Paper start - optimise out extra getCubes
|
||||
+ this.player.absMoveTo(d0, d1, d2, f, f1); // prevent desync by tping to the set position, dropped for unknown reasons by mojang
|
||||
+ // Original for reference:
|
||||
+ // boolean teleportBack = flag2 && worldserver.getCubes(this.player, axisalignedbb) || (didCollide && this.a((IWorldReader) worldserver, axisalignedbb));
|
||||
+ boolean teleportBack = flag2; // violating this is always a fail
|
||||
|
|
|
@ -49,7 +49,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|||
|
||||
// Paper start - distance maps
|
||||
private final com.destroystokyo.paper.util.misc.PooledLinkedHashSets<ServerPlayer> pooledLinkedPlayerHashSets = new com.destroystokyo.paper.util.misc.PooledLinkedHashSets<>();
|
||||
+ public final io.papermc.paper.chunk.PlayerChunkLoader playerChunkManager = new io.papermc.paper.chunk.PlayerChunkLoader(this, this.pooledLinkedPlayerHashSets); // Paper - replace chunk loader
|
||||
+ // Paper start - optimise ChunkMap#anyPlayerCloseEnoughForSpawning
|
||||
+ // A note about the naming used here:
|
||||
+ // Previously, mojang used a "spawn range" of 8 for controlling both ticking and
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,28 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 8 Apr 2020 21:24:05 -0400
|
||||
Subject: [PATCH] Increase Light Queue Size
|
||||
|
||||
Wiz mentioned that large WorldEdit operations cause light to run on
|
||||
main thread. The queue was small, set to 5.. this bumps it to 20
|
||||
but makes it configurable per-world.
|
||||
|
||||
The main risk of increasing this higher is during shutdown, some
|
||||
queued light updates may be lost because mojang did not flush the
|
||||
light engine on shutdown...
|
||||
|
||||
The queue size only puts a cap on max loss, doesn't solve that problem.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.executeModerately();
|
||||
// CraftBukkit end
|
||||
if (worldserver.getWorld().getKeepSpawnInMemory()) worldloadlistener.stop(); // Paper
|
||||
- chunkproviderserver.getLightEngine().setTaskPerBatch(5);
|
||||
+ chunkproviderserver.getLightEngine().setTaskPerBatch(worldserver.paperConfig().misc.lightQueueSize); // Paper - increase light queue size
|
||||
// CraftBukkit start
|
||||
// this.updateMobSpawningFlags();
|
||||
worldserver.setSpawnSettings(this.isSpawningMonsters(), this.isSpawningAnimals());
|
File diff suppressed because it is too large
Load diff
|
@ -1,297 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Mon, 27 Apr 2020 04:05:38 -0700
|
||||
Subject: [PATCH] Stop copy-on-write operations for updating light data
|
||||
|
||||
Causes huge memory allocations + gc issues
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/lighting/BlockLightSectionStorage.java b/src/main/java/net/minecraft/world/level/lighting/BlockLightSectionStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/lighting/BlockLightSectionStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/lighting/BlockLightSectionStorage.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.level.chunk.LightChunkGetter;
|
||||
|
||||
public class BlockLightSectionStorage extends LayerLightSectionStorage<BlockLightSectionStorage.BlockDataLayerStorageMap> {
|
||||
protected BlockLightSectionStorage(LightChunkGetter chunkProvider) {
|
||||
- super(LightLayer.BLOCK, chunkProvider, new BlockLightSectionStorage.BlockDataLayerStorageMap(new Long2ObjectOpenHashMap<>()));
|
||||
+ super(LightLayer.BLOCK, chunkProvider, new BlockLightSectionStorage.BlockDataLayerStorageMap(new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>(), false)); // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class BlockLightSectionStorage extends LayerLightSectionStorage<BlockLigh
|
||||
}
|
||||
|
||||
protected static final class BlockDataLayerStorageMap extends DataLayerStorageMap<BlockLightSectionStorage.BlockDataLayerStorageMap> {
|
||||
- public BlockDataLayerStorageMap(Long2ObjectOpenHashMap<DataLayer> arrays) {
|
||||
- super(arrays);
|
||||
+ public BlockDataLayerStorageMap(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> long2objectopenhashmap, boolean isVisible) { // Paper - avoid copying light data
|
||||
+ super(long2objectopenhashmap, isVisible); // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockLightSectionStorage.BlockDataLayerStorageMap copy() {
|
||||
- return new BlockLightSectionStorage.BlockDataLayerStorageMap(this.map.clone());
|
||||
+ return new BlockDataLayerStorageMap(this.data, true); // Paper - avoid copying light data
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java b/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/lighting/DataLayerStorageMap.java
|
||||
@@ -0,0 +0,0 @@ public abstract class DataLayerStorageMap<M extends DataLayerStorageMap<M>> {
|
||||
private final long[] lastSectionKeys = new long[2];
|
||||
private final DataLayer[] lastSections = new DataLayer[2];
|
||||
private boolean cacheEnabled;
|
||||
- protected final Long2ObjectOpenHashMap<DataLayer> map;
|
||||
+ protected final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> data; // Paper - avoid copying light data
|
||||
+ protected final boolean isVisible; // Paper - avoid copying light data
|
||||
+ java.util.function.Function<Long, DataLayer> lookup; // Paper - faster branchless lookup
|
||||
|
||||
- protected DataLayerStorageMap(Long2ObjectOpenHashMap<DataLayer> arrays) {
|
||||
- this.map = arrays;
|
||||
+ // Paper start - avoid copying light data
|
||||
+ protected DataLayerStorageMap(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> data, boolean isVisible) {
|
||||
+ if (isVisible) {
|
||||
+ data.performUpdatesLockMap();
|
||||
+ }
|
||||
+ this.data = data;
|
||||
+ this.isVisible = isVisible;
|
||||
+ if (isVisible) {
|
||||
+ lookup = data::getVisibleAsync;
|
||||
+ } else {
|
||||
+ lookup = data::getUpdating;
|
||||
+ }
|
||||
+ // Paper end - avoid copying light data
|
||||
this.clearCache();
|
||||
this.cacheEnabled = true;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class DataLayerStorageMap<M extends DataLayerStorageMap<M>> {
|
||||
public abstract M copy();
|
||||
|
||||
public void copyDataLayer(long pos) {
|
||||
- this.map.put(pos, this.map.get(pos).copy());
|
||||
+ if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
|
||||
+ this.data.queueUpdate(pos, ((DataLayer) this.data.getUpdating(pos)).copy()); // Paper - avoid copying light data
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
public boolean hasLayer(long chunkPos) {
|
||||
- return this.map.containsKey(chunkPos);
|
||||
+ return lookup.apply(chunkPos) != null; // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
@Nullable
|
||||
- public DataLayer getLayer(long chunkPos) {
|
||||
+ public final DataLayer getLayer(long chunkPos) { // Paper - final
|
||||
if (this.cacheEnabled) {
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
if (chunkPos == this.lastSectionKeys[i]) {
|
||||
@@ -0,0 +0,0 @@ public abstract class DataLayerStorageMap<M extends DataLayerStorageMap<M>> {
|
||||
}
|
||||
}
|
||||
|
||||
- DataLayer dataLayer = this.map.get(chunkPos);
|
||||
+ DataLayer dataLayer = lookup.apply(chunkPos); // Paper - avoid copying light data
|
||||
if (dataLayer == null) {
|
||||
return null;
|
||||
} else {
|
||||
@@ -0,0 +0,0 @@ public abstract class DataLayerStorageMap<M extends DataLayerStorageMap<M>> {
|
||||
|
||||
@Nullable
|
||||
public DataLayer removeLayer(long chunkPos) {
|
||||
- return this.map.remove(chunkPos);
|
||||
+ if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
|
||||
+ return (DataLayer) this.data.queueRemove(chunkPos); // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
public void setLayer(long pos, DataLayer data) {
|
||||
- this.map.put(pos, data);
|
||||
+ if (this.isVisible) { throw new IllegalStateException("writing to visible data"); } // Paper - avoid copying light data
|
||||
+ this.data.queueUpdate(pos, data); // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
public void clearCache() {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java b/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/lighting/LayerLightSectionStorage.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
|
||||
protected final LongSet dataSectionSet = new LongOpenHashSet();
|
||||
protected final LongSet toMarkNoData = new LongOpenHashSet();
|
||||
protected final LongSet toMarkData = new LongOpenHashSet();
|
||||
- protected volatile M visibleSectionData;
|
||||
+ protected volatile M e_visible; protected final Object visibleUpdateLock = new Object(); // Paper - diff on change, should be "visible" - force compile fail on usage change
|
||||
protected final M updatingSectionData;
|
||||
protected final LongSet changedSections = new LongOpenHashSet();
|
||||
protected final LongSet sectionsAffectedByLightUpdates = new LongOpenHashSet();
|
||||
@@ -0,0 +0,0 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
|
||||
this.layer = lightType;
|
||||
this.chunkSource = chunkProvider;
|
||||
this.updatingSectionData = lightData;
|
||||
- this.visibleSectionData = lightData.copy();
|
||||
- this.visibleSectionData.disableCache();
|
||||
+ this.e_visible = lightData.copy(); // Paper - avoid copying light dat
|
||||
+ this.e_visible.disableCache(); // Paper - avoid copying light dat
|
||||
}
|
||||
|
||||
protected boolean storingLightForSection(long sectionPos) {
|
||||
@@ -0,0 +0,0 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
|
||||
|
||||
@Nullable
|
||||
protected DataLayer getDataLayer(long sectionPos, boolean cached) {
|
||||
- return this.getDataLayer((M)(cached ? this.updatingSectionData : this.visibleSectionData), sectionPos);
|
||||
+ // Paper start - avoid copying light data
|
||||
+ if (cached) {
|
||||
+ return this.getDataLayer(this.updatingSectionData, sectionPos);
|
||||
+ } else {
|
||||
+ synchronized (this.visibleUpdateLock) {
|
||||
+ return this.getDataLayer(this.e_visible, sectionPos);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - avoid copying light data
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -0,0 +0,0 @@ public abstract class LayerLightSectionStorage<M extends DataLayerStorageMap<M>>
|
||||
|
||||
protected void swapSectionMap() {
|
||||
if (!this.changedSections.isEmpty()) {
|
||||
+ synchronized (this.visibleUpdateLock) { // Paper - avoid copying light data
|
||||
M dataLayerStorageMap = this.updatingSectionData.copy();
|
||||
dataLayerStorageMap.disableCache();
|
||||
- this.visibleSectionData = dataLayerStorageMap;
|
||||
+ this.e_visible = dataLayerStorageMap; // Paper - avoid copying light data
|
||||
+ } // Paper - avoid copying light data
|
||||
this.changedSections.clear();
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java b/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
|
||||
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
|
||||
private volatile boolean hasSourceInconsistencies;
|
||||
|
||||
protected SkyLightSectionStorage(LightChunkGetter chunkProvider) {
|
||||
- super(LightLayer.SKY, chunkProvider, new SkyLightSectionStorage.SkyDataLayerStorageMap(new Long2ObjectOpenHashMap<>(), new Long2IntOpenHashMap(), Integer.MAX_VALUE));
|
||||
+ super(LightLayer.SKY, chunkProvider, new SkyLightSectionStorage.SkyDataLayerStorageMap(new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<>(), new com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int(), Integer.MAX_VALUE, false)); // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
|
||||
protected int getLightValue(long blockPos, boolean cached) {
|
||||
long l = SectionPos.blockToSection(blockPos);
|
||||
int i = SectionPos.y(l);
|
||||
- SkyLightSectionStorage.SkyDataLayerStorageMap skyDataLayerStorageMap = cached ? this.updatingSectionData : this.visibleSectionData;
|
||||
- int j = skyDataLayerStorageMap.topSections.get(SectionPos.getZeroNode(l));
|
||||
+ synchronized (this.visibleUpdateLock) { // Paper - avoid copying light data
|
||||
+ SkyLightSectionStorage.SkyDataLayerStorageMap skyDataLayerStorageMap = (SkyLightSectionStorage.SkyDataLayerStorageMap) this.e_visible; // Paper - avoid copying light data - must be after lock acquire
|
||||
+ int j = skyDataLayerStorageMap.otherData.getVisibleAsync(SectionPos.getZeroNode(l)); // Paper - avoid copying light data
|
||||
if (j != skyDataLayerStorageMap.currentLowestY && i < j) {
|
||||
DataLayer dataLayer = this.getDataLayer(skyDataLayerStorageMap, l);
|
||||
if (dataLayer == null) {
|
||||
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
|
||||
} else {
|
||||
return cached && !this.lightOnInSection(l) ? 0 : 15;
|
||||
}
|
||||
+ } // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
|
||||
int i = SectionPos.y(sectionPos);
|
||||
if ((this.updatingSectionData).currentLowestY > i) {
|
||||
(this.updatingSectionData).currentLowestY = i;
|
||||
- (this.updatingSectionData).topSections.defaultReturnValue((this.updatingSectionData).currentLowestY);
|
||||
+ (this.updatingSectionData).otherData.queueDefaultReturnValue((this.updatingSectionData).currentLowestY); // Paper - avoid copying light data
|
||||
}
|
||||
|
||||
long l = SectionPos.getZeroNode(sectionPos);
|
||||
- int j = (this.updatingSectionData).topSections.get(l);
|
||||
+ int j = (this.updatingSectionData).otherData.getUpdating(l); // Paper - avoid copying light data
|
||||
if (j < i + 1) {
|
||||
- (this.updatingSectionData).topSections.put(l, i + 1);
|
||||
+ (this.updatingSectionData).otherData.queueUpdate(l, i + 1); // Paper - avoid copying light data
|
||||
if (this.columnsWithSkySources.contains(l)) {
|
||||
this.queueAddSource(sectionPos);
|
||||
if (j > (this.updatingSectionData).currentLowestY) {
|
||||
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
|
||||
}
|
||||
|
||||
int i = SectionPos.y(sectionPos);
|
||||
- if ((this.updatingSectionData).topSections.get(l) == i + 1) {
|
||||
+ if ((this.updatingSectionData).otherData.getUpdating(l) == i + 1) { // Paper - avoid copying light data
|
||||
long m;
|
||||
for(m = sectionPos; !this.storingLightForSection(m) && this.hasSectionsBelow(i); m = SectionPos.offset(m, Direction.DOWN)) {
|
||||
--i;
|
||||
}
|
||||
|
||||
if (this.storingLightForSection(m)) {
|
||||
- (this.updatingSectionData).topSections.put(l, i + 1);
|
||||
+ (this.updatingSectionData).otherData.queueUpdate(l, i + 1); // Paper - avoid copying light data
|
||||
if (bl) {
|
||||
this.queueAddSource(m);
|
||||
}
|
||||
} else {
|
||||
- (this.updatingSectionData).topSections.remove(l);
|
||||
+ (this.updatingSectionData).otherData.queueRemove(l); // Paper - avoid copying light data
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
|
||||
protected void enableLightSources(long columnPos, boolean enabled) {
|
||||
this.runAllUpdates();
|
||||
if (enabled && this.columnsWithSkySources.add(columnPos)) {
|
||||
- int i = (this.updatingSectionData).topSections.get(columnPos);
|
||||
+ int i = (this.updatingSectionData).otherData.getUpdating(columnPos); // Paper - avoid copying light data
|
||||
if (i != (this.updatingSectionData).currentLowestY) {
|
||||
long l = SectionPos.asLong(SectionPos.x(columnPos), i - 1, SectionPos.z(columnPos));
|
||||
this.queueAddSource(l);
|
||||
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
|
||||
return dataLayer;
|
||||
} else {
|
||||
long l = SectionPos.offset(sectionPos, Direction.UP);
|
||||
- int i = (this.updatingSectionData).topSections.get(SectionPos.getZeroNode(sectionPos));
|
||||
+ int i = (this.updatingSectionData).otherData.getUpdating(SectionPos.getZeroNode(sectionPos)); // Paper - avoid copying light data
|
||||
if (i != (this.updatingSectionData).currentLowestY && SectionPos.y(l) < i) {
|
||||
DataLayer dataLayer2;
|
||||
while((dataLayer2 = this.getDataLayer(l, true)) == null) {
|
||||
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
|
||||
|
||||
protected boolean isAboveData(long sectionPos) {
|
||||
long l = SectionPos.getZeroNode(sectionPos);
|
||||
- int i = (this.updatingSectionData).topSections.get(l);
|
||||
+ int i = (this.updatingSectionData).otherData.getUpdating(l); // Paper - avoid copying light data
|
||||
return i == (this.updatingSectionData).currentLowestY || SectionPos.y(sectionPos) >= i;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSec
|
||||
|
||||
protected static final class SkyDataLayerStorageMap extends DataLayerStorageMap<SkyLightSectionStorage.SkyDataLayerStorageMap> {
|
||||
int currentLowestY;
|
||||
- final Long2IntOpenHashMap topSections;
|
||||
-
|
||||
- public SkyDataLayerStorageMap(Long2ObjectOpenHashMap<DataLayer> arrays, Long2IntOpenHashMap columnToTopSection, int minSectionY) {
|
||||
- super(arrays);
|
||||
- this.topSections = columnToTopSection;
|
||||
- columnToTopSection.defaultReturnValue(minSectionY);
|
||||
+ private final com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int otherData; // Paper - avoid copying light data
|
||||
+
|
||||
+ // Paper start - avoid copying light data
|
||||
+ public SkyDataLayerStorageMap(com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object<DataLayer> arrays, com.destroystokyo.paper.util.map.QueuedChangesMapLong2Int columnToTopSection, int minSectionY, boolean isVisible) {
|
||||
+ super(arrays, isVisible);
|
||||
+ this.otherData = columnToTopSection;
|
||||
+ otherData.queueDefaultReturnValue(minSectionY);
|
||||
+ // Paper end
|
||||
this.currentLowestY = minSectionY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SkyLightSectionStorage.SkyDataLayerStorageMap copy() {
|
||||
- return new SkyLightSectionStorage.SkyDataLayerStorageMap(this.map.clone(), this.topSections.clone(), this.currentLowestY);
|
||||
+ this.otherData.performUpdatesLockMap(); // Paper - avoid copying light data
|
||||
+ return new SkyLightSectionStorage.SkyDataLayerStorageMap(this.data, this.otherData, this.currentLowestY, true); // Paper - avoid copying light data
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue