fix(portal): synchronize destination presentation state

This commit is contained in:
Erik 2026-07-16 21:17:13 +02:00
parent 4b1bceefbb
commit e95f55f25b
42 changed files with 2815 additions and 288 deletions

View file

@ -125,6 +125,27 @@ before installing retail's distant light. The lifecycle, camera, animation,
and draw ordering are acdream-owned ports of `gmSmartBoxUI`; WorldBuilder never
implemented this UI viewport.
**Portal destination render-readiness seam (2026-07-16).**
`GpuWorldState.IsRenderReady` does not treat dictionary publication as a draw
barrier. `LandblockSpawnAdapter` retains the complete required-id set for each
landblock: atlas-tier GfxObjs plus the synthetic geometry ids prepared by the
independent EnvCell shell pipeline. `WbMeshAdapter.IsRenderDataReady` opens the
gate only after `ObjectMeshManager` has real GPU render data. Its bounded CPU
cache retains texture payloads and stages a missing GPU object through a
deduplicated upload queue on cache hit, covering eviction and revisit churn.
GPU upload is deliberately not an ownership acquire: atlas GfxObjs use their
landblock/entity pins, while synthetic EnvCell geometry uses a no-generic-decode
pin balanced from each landblock snapshot. A late upload after all owners have
released enters the evictable LRU instead of resurrecting a reference. After
publication pins the synthetic ids, the controller replays their immutable
environment/cell-structure/surface preparation descriptors; if a formerly
unowned mesh was evicted between worker scheduling and publication, this
schema-aware replay re-stages it without a generic GfxObj lookup.
Near-to-Far demotion is a separate App transaction: it releases EnvCell
rendering and landblock mesh pins while retaining the terrain slot. Core's
matching physics demotion preserves the terrain surface but removes indoor
cells, portals, buildings, and static shadow registrations.
**Workflow:** Before re-implementing any AC-specific rendering or dat-handling
algorithm, **check this inventory first**. If we already extracted it (🟢
sections), it's in `src/AcDream.App/Rendering/Wb/` — use our copy. If WB has
@ -194,6 +215,13 @@ Retail `TexMerge::CopyAndTile` (`0x00503580`) and `TexMerge::Merge`
| `SceneryHelpers` | Displace / RotateObj / ScaleObj / ObjAlign / CheckSlope |
| `SceneryInstance` | Per-spawn instance data |
acdream's streamed projection assigns generated instances local runtime IDs
through `AcDream.Core.World.ProceduralSceneryIdAllocator`. The namespace is
`0x8XXYYIII` (full X/Y bytes plus a 12-bit counter); bit 31 remains the stable
scenery classification seam. This is projection identity, not placement
behavior. The former 8-bit counter rejected dense retail-DAT landblocks before
their render transaction could publish (#218).
### Static objects (buildings, slabs, props — Setup + GfxObj + ObjDesc)
| Component | What it does |