Reuse the PView frame input, publish mutation-invalidated landblock views, and avoid constructing optional shadow iterators while preserving title and lifecycle visibility facts.
69 lines
3 KiB
Markdown
69 lines
3 KiB
Markdown
# Slice H-a4 — retained frame scratch and diagnostic traversal
|
|
|
|
## Scope
|
|
|
|
This is a behavior-preserving ownership/allocation correction. It does not
|
|
change retail visibility, PView construction, spatial ordering, collision
|
|
debug drawing, title facts, or lifecycle checkpoint facts.
|
|
|
|
## Findings
|
|
|
|
Three independent steady-frame allocation sources remained:
|
|
|
|
1. `WorldSceneRenderer` constructed one `RetailPViewFrameInput` reference
|
|
object for every PView frame even though `DrawInside` consumes it
|
|
synchronously.
|
|
2. `GpuWorldState.LandblockEntries` and `LandblockBounds` were C# iterator
|
|
methods, so merely obtaining each sequence constructed fresh iterator
|
|
state. The underlying spatial membership changed only at update-thread
|
|
publication boundaries.
|
|
3. `WorldSceneDiagnosticsController` passed
|
|
`ShadowObjectRegistry.AllEntriesForDebug()` to the DebugVM publisher even
|
|
when no developer UI consumer existed. The publisher correctly avoided
|
|
enumeration, but the yield sequence itself had already been constructed.
|
|
|
|
The execution plan initially described landblock visibility counting as an
|
|
unconsumed diagnostic. That was incorrect in the current application:
|
|
`WorldRenderFrameOutcome` feeds the always-visible FPS/title `lb V/T` values
|
|
and connected lifecycle snapshots. Returning a neutral count would therefore
|
|
change observable behavior and invalidate lifecycle evidence. The count is
|
|
retained; only its iterator allocation is removed.
|
|
|
|
## Implementation
|
|
|
|
- `WorldSceneRenderer` owns one `RetailPViewFrameInput` and resets every field
|
|
before the synchronous `DrawInside` call. The input is publicly read-only
|
|
and internally mutable so downstream render owners cannot change borrowed
|
|
frame facts.
|
|
- `GpuWorldState` exposes retained entry, no-animated-index entry, and bounds
|
|
lists. They rebuild only after landblock membership, resident entity-list,
|
|
animated-index, or AABB changes. Existing render-traversal slot order is
|
|
preserved exactly.
|
|
- Landblock diagnostic counting uses indexed access over the retained bounds
|
|
view.
|
|
- Shadow enumeration is constructed only when the DebugVM is mounted. The
|
|
independent collision-wireframe switch keeps its existing enumeration.
|
|
- `InteriorEntityPartition` remains untouched while the G4 referee is still
|
|
retained. Its removal and issue #241 close remain G5 work after the user
|
|
accepts the G4 visual gate.
|
|
|
|
## Conformance
|
|
|
|
- Stable retained render-view getters allocate zero bytes over 1,000 polls.
|
|
- A spatial mutation refreshes the same borrowed list identity and publishes
|
|
the new count.
|
|
- Two successive PView frames receive the same input object, reset with the
|
|
current frame values.
|
|
- Existing quiescence, render traversal, animated-index, PView executor,
|
|
abort/recovery, and DebugVM tests remain unchanged in behavior.
|
|
|
|
## Rollback boundary
|
|
|
|
This work is independent of the G4 production-source cutover. If tomorrow's
|
|
visual gate rejects G4, use:
|
|
|
|
```text
|
|
git revert ef1d263337997bb030eadb7b8e71d73dc659907a
|
|
```
|
|
|
|
Do not revert this Slice H-a4 commit, G3, or the portal-warmup corrections.
|