mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-19 15:09:25 +00:00
Update changes from ver/1.21.4 branch
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Taiyou06 <kaandindar21@gmail.com>
|
||||
Date: Mon, 24 Feb 2025 21:33:24 +0100
|
||||
Subject: [PATCH] Rewrite ClientboundLightUpdatePacketData
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
On writing operations:
|
||||
At 256 sections with 0.75 fill ratio: 18x faster (333.489 μs → 18.606 μs)
|
||||
At 256 sections with 0.5 fill ratio: 13.5x faster (147.804 μs → 10.962 μs)
|
||||
|
||||
diff --git a/net/minecraft/network/protocol/game/ClientboundLightUpdatePacketData.java b/net/minecraft/network/protocol/game/ClientboundLightUpdatePacketData.java
|
||||
index a0b54f3a3d11e0f0f1cb806406a870ba36da8f07..234280499fe1bc495bcdd4c3e144d1f99b7e6975 100644
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundLightUpdatePacketData.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundLightUpdatePacketData.java
|
||||
@@ -16,30 +16,113 @@ import net.minecraft.world.level.lighting.LevelLightEngine;
|
||||
|
||||
public class ClientboundLightUpdatePacketData {
|
||||
private static final StreamCodec<ByteBuf, byte[]> DATA_LAYER_STREAM_CODEC = ByteBufCodecs.byteArray(2048);
|
||||
+
|
||||
+ // Leaf start - Rewrite ClientboundLightUpdatePacketData
|
||||
+ // Static constants to avoid allocations
|
||||
+ private static final byte[][] EMPTY_ARRAY = new byte[0][];
|
||||
+
|
||||
+ // Pre-sized arrays to avoid dynamic resizing
|
||||
+ private static final ThreadLocal<byte[][]> SKY_BUFFER = ThreadLocal.withInitial(() -> new byte[256][]);
|
||||
+ private static final ThreadLocal<byte[][]> BLOCK_BUFFER = ThreadLocal.withInitial(() -> new byte[256][]);
|
||||
+
|
||||
+ // Pre-cached BitSets with fixed size
|
||||
private final BitSet skyYMask;
|
||||
private final BitSet blockYMask;
|
||||
private final BitSet emptySkyYMask;
|
||||
private final BitSet emptyBlockYMask;
|
||||
- private final List<byte[]> skyUpdates;
|
||||
- private final List<byte[]> blockUpdates;
|
||||
+
|
||||
+ // Fixed arrays with exact counts
|
||||
+ private final byte[][] skyUpdates;
|
||||
+ private final byte[][] blockUpdates;
|
||||
+ private final int skyUpdateCount;
|
||||
+ private final int blockUpdateCount;
|
||||
+ // Leaf end - Rewrite ClientboundLightUpdatePacketData
|
||||
|
||||
public ClientboundLightUpdatePacketData(ChunkPos chunkPos, LevelLightEngine lightEngine, @Nullable BitSet skyLight, @Nullable BitSet blockLight) {
|
||||
- this.skyYMask = new BitSet();
|
||||
- this.blockYMask = new BitSet();
|
||||
- this.emptySkyYMask = new BitSet();
|
||||
- this.emptyBlockYMask = new BitSet();
|
||||
- this.skyUpdates = Lists.newArrayList();
|
||||
- this.blockUpdates = Lists.newArrayList();
|
||||
-
|
||||
- for (int i = 0; i < lightEngine.getLightSectionCount(); i++) {
|
||||
+ // Leaf start - Rewrite ClientboundLightUpdatePacketData
|
||||
+ int sectionCount = lightEngine.getLightSectionCount();
|
||||
+
|
||||
+ // Round up to nearest long boundary (64 bits) to prevent BitSet expansion
|
||||
+ int longWords = (sectionCount + 63) >>> 6;
|
||||
+ int bitSetSize = longWords << 6;
|
||||
+
|
||||
+ // Pre-size all BitSets to exact size needed
|
||||
+ this.skyYMask = new BitSet(bitSetSize);
|
||||
+ this.blockYMask = new BitSet(bitSetSize);
|
||||
+ this.emptySkyYMask = new BitSet(bitSetSize);
|
||||
+ this.emptyBlockYMask = new BitSet(bitSetSize);
|
||||
+
|
||||
+ // Get buffer arrays from thread local storage to avoid allocations
|
||||
+ byte[][] skyBuffer = SKY_BUFFER.get();
|
||||
+ byte[][] blockBuffer = BLOCK_BUFFER.get();
|
||||
+
|
||||
+ // Process all sections in a single pass
|
||||
+ int skyCount = 0;
|
||||
+ int blockCount = 0;
|
||||
+ int minLightSection = lightEngine.getMinLightSection();
|
||||
+
|
||||
+ // Cache layer listeners to avoid repeated method calls
|
||||
+ var skyLayerListener = lightEngine.getLayerListener(LightLayer.SKY);
|
||||
+ var blockLayerListener = lightEngine.getLayerListener(LightLayer.BLOCK);
|
||||
+
|
||||
+ // Single pass through all sections
|
||||
+ for (int i = 0; i < sectionCount; i++) {
|
||||
+ int sectionY = minLightSection + i;
|
||||
+ SectionPos sectionPos = SectionPos.of(chunkPos.x, sectionY, chunkPos.z);
|
||||
+
|
||||
+ // Process sky light
|
||||
if (skyLight == null || skyLight.get(i)) {
|
||||
- this.prepareSectionData(chunkPos, lightEngine, LightLayer.SKY, i, this.skyYMask, this.emptySkyYMask, this.skyUpdates);
|
||||
+ DataLayer skyData = skyLayerListener.getDataLayerData(sectionPos);
|
||||
+ if (skyData != null) {
|
||||
+ if (skyData.isEmpty()) {
|
||||
+ emptySkyYMask.set(i);
|
||||
+ } else {
|
||||
+ skyYMask.set(i);
|
||||
+ // Store in buffer temporarily - only clone at the end
|
||||
+ skyBuffer[skyCount++] = skyData.getData();
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
+ // Process block light
|
||||
if (blockLight == null || blockLight.get(i)) {
|
||||
- this.prepareSectionData(chunkPos, lightEngine, LightLayer.BLOCK, i, this.blockYMask, this.emptyBlockYMask, this.blockUpdates);
|
||||
+ DataLayer blockData = blockLayerListener.getDataLayerData(sectionPos);
|
||||
+ if (blockData != null) {
|
||||
+ if (blockData.isEmpty()) {
|
||||
+ emptyBlockYMask.set(i);
|
||||
+ } else {
|
||||
+ blockYMask.set(i);
|
||||
+ // Store in buffer temporarily - only clone at the end
|
||||
+ blockBuffer[blockCount++] = blockData.getData();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Create final arrays with exact sizes
|
||||
+ if (skyCount > 0) {
|
||||
+ this.skyUpdates = new byte[skyCount][];
|
||||
+ // Clone only at the end to minimize work
|
||||
+ for (int i = 0; i < skyCount; i++) {
|
||||
+ this.skyUpdates[i] = skyBuffer[i].clone();
|
||||
+ }
|
||||
+ } else {
|
||||
+ this.skyUpdates = EMPTY_ARRAY;
|
||||
+ }
|
||||
+
|
||||
+ if (blockCount > 0) {
|
||||
+ this.blockUpdates = new byte[blockCount][];
|
||||
+ // Clone only at the end to minimize work
|
||||
+ for (int i = 0; i < blockCount; i++) {
|
||||
+ this.blockUpdates[i] = blockBuffer[i].clone();
|
||||
}
|
||||
+ } else {
|
||||
+ this.blockUpdates = EMPTY_ARRAY;
|
||||
}
|
||||
+
|
||||
+ this.skyUpdateCount = skyCount;
|
||||
+ this.blockUpdateCount = blockCount;
|
||||
+ // Leaf end - Rewrite ClientboundLightUpdatePacketData
|
||||
}
|
||||
|
||||
public ClientboundLightUpdatePacketData(FriendlyByteBuf buffer, int x, int z) {
|
||||
@@ -47,8 +130,30 @@ public class ClientboundLightUpdatePacketData {
|
||||
this.blockYMask = buffer.readBitSet();
|
||||
this.emptySkyYMask = buffer.readBitSet();
|
||||
this.emptyBlockYMask = buffer.readBitSet();
|
||||
- this.skyUpdates = buffer.readList(DATA_LAYER_STREAM_CODEC);
|
||||
- this.blockUpdates = buffer.readList(DATA_LAYER_STREAM_CODEC);
|
||||
+
|
||||
+ // Leaf start - Rewrite ClientboundLightUpdatePacketData
|
||||
+ // Read lists directly as arrays to avoid intermediate collections
|
||||
+ List<byte[]> skyList = buffer.readList(DATA_LAYER_STREAM_CODEC);
|
||||
+ List<byte[]> blockList = buffer.readList(DATA_LAYER_STREAM_CODEC);
|
||||
+
|
||||
+ int skySize = skyList.size();
|
||||
+ int blockSize = blockList.size();
|
||||
+
|
||||
+ if (skySize > 0) {
|
||||
+ this.skyUpdates = skyList.toArray(new byte[skySize][]);
|
||||
+ } else {
|
||||
+ this.skyUpdates = EMPTY_ARRAY;
|
||||
+ }
|
||||
+
|
||||
+ if (blockSize > 0) {
|
||||
+ this.blockUpdates = blockList.toArray(new byte[blockSize][]);
|
||||
+ } else {
|
||||
+ this.blockUpdates = EMPTY_ARRAY;
|
||||
+ }
|
||||
+
|
||||
+ this.skyUpdateCount = skySize;
|
||||
+ this.blockUpdateCount = blockSize;
|
||||
+ // Leaf end - Rewrite ClientboundLightUpdatePacketData
|
||||
}
|
||||
|
||||
public void write(FriendlyByteBuf buffer) {
|
||||
@@ -56,25 +161,33 @@ public class ClientboundLightUpdatePacketData {
|
||||
buffer.writeBitSet(this.blockYMask);
|
||||
buffer.writeBitSet(this.emptySkyYMask);
|
||||
buffer.writeBitSet(this.emptyBlockYMask);
|
||||
- buffer.writeCollection(this.skyUpdates, DATA_LAYER_STREAM_CODEC);
|
||||
- buffer.writeCollection(this.blockUpdates, DATA_LAYER_STREAM_CODEC);
|
||||
- }
|
||||
|
||||
- private void prepareSectionData(
|
||||
- ChunkPos chunkPos, LevelLightEngine levelLightEngine, LightLayer lightLayer, int index, BitSet skyLight, BitSet blockLight, List<byte[]> updates
|
||||
- ) {
|
||||
- DataLayer dataLayerData = levelLightEngine.getLayerListener(lightLayer)
|
||||
- .getDataLayerData(SectionPos.of(chunkPos, levelLightEngine.getMinLightSection() + index));
|
||||
- if (dataLayerData != null) {
|
||||
- if (dataLayerData.isEmpty()) {
|
||||
- blockLight.set(index);
|
||||
- } else {
|
||||
- skyLight.set(index);
|
||||
- updates.add(dataLayerData.copy().getData());
|
||||
+ // Leaf start - Rewrite ClientboundLightUpdatePacketData
|
||||
+ // Avoid creating unnecessary objects when writing
|
||||
+ if (this.skyUpdateCount > 0) {
|
||||
+ // Use direct array access for efficiency
|
||||
+ buffer.writeVarInt(this.skyUpdateCount);
|
||||
+ for (int i = 0; i < this.skyUpdateCount; i++) {
|
||||
+ DATA_LAYER_STREAM_CODEC.encode(buffer, this.skyUpdates[i]);
|
||||
}
|
||||
+ } else {
|
||||
+ buffer.writeVarInt(0);
|
||||
}
|
||||
+
|
||||
+ if (this.blockUpdateCount > 0) {
|
||||
+ // Use direct array access for efficiency
|
||||
+ buffer.writeVarInt(this.blockUpdateCount);
|
||||
+ for (int i = 0; i < this.blockUpdateCount; i++) {
|
||||
+ DATA_LAYER_STREAM_CODEC.encode(buffer, this.blockUpdates[i]);
|
||||
+ }
|
||||
+ } else {
|
||||
+ buffer.writeVarInt(0);
|
||||
+ }
|
||||
+ // Leaf end - Rewrite ClientboundLightUpdatePacketData
|
||||
}
|
||||
|
||||
+ // Getter methods
|
||||
+
|
||||
public BitSet getSkyYMask() {
|
||||
return this.skyYMask;
|
||||
}
|
||||
@@ -84,7 +197,7 @@ public class ClientboundLightUpdatePacketData {
|
||||
}
|
||||
|
||||
public List<byte[]> getSkyUpdates() {
|
||||
- return this.skyUpdates;
|
||||
+ return this.skyUpdateCount > 0 ? java.util.Arrays.asList(this.skyUpdates) : List.of(); // Leaf - Rewrite ClientboundLightUpdatePacketData
|
||||
}
|
||||
|
||||
public BitSet getBlockYMask() {
|
||||
@@ -96,6 +209,6 @@ public class ClientboundLightUpdatePacketData {
|
||||
}
|
||||
|
||||
public List<byte[]> getBlockUpdates() {
|
||||
- return this.blockUpdates;
|
||||
+ return this.blockUpdateCount > 0 ? java.util.Arrays.asList(this.blockUpdates) : List.of(); // Leaf - Rewrite ClientboundLightUpdatePacketData
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user