perf(rendering): retain synchronous frame scratch

Reuse the PView frame input, publish mutation-invalidated landblock views, and avoid constructing optional shadow iterators while preserving title and lifecycle visibility facts.
This commit is contained in:
Erik 2026-07-25 05:28:30 +02:00
parent b9cbf5e040
commit b3427554c3
10 changed files with 397 additions and 129 deletions

View file

@ -68,6 +68,44 @@ public sealed class GpuWorldStateRenderTraversalTests
Assert.False(state.TryGetRenderTraversalSortKey(pending, out _));
}
[Fact]
public void StableRenderViews_AllocateOnlyWhenSpatialContentChanges()
{
var state = new GpuWorldState();
state.AddLandblock(Landblock(
FirstLandblock,
Entity(1, 0x80000001u)));
state.SetLandblockAabb(
FirstLandblock,
new Vector3(1f, 2f, 3f),
new Vector3(4f, 5f, 6f));
var entries = state.LandblockEntries;
var bounds = state.LandblockBounds;
_ = entries.Count;
_ = bounds.Count;
long before = GC.GetAllocatedBytesForCurrentThread();
for (int iteration = 0; iteration < 1_000; iteration++)
{
_ = state.LandblockEntries.Count;
_ = state.LandblockBounds.Count;
}
long allocated = GC.GetAllocatedBytesForCurrentThread() - before;
Assert.Equal(0, allocated);
Assert.Same(entries, state.LandblockEntries);
Assert.Same(bounds, state.LandblockBounds);
state.AddLandblock(Landblock(
SecondLandblock,
Entity(2, 0x80000002u)));
Assert.Same(entries, state.LandblockEntries);
Assert.Same(bounds, state.LandblockBounds);
Assert.Equal(2, entries.Count);
Assert.Equal(2, bounds.Count);
}
private static void AssertSort(
GpuWorldState state,
WorldEntity entity,