perf(render): bound animation and alpha scratch residency
Complete Slice D3 by replacing the unbounded animation dictionary with a concurrent byte/count LRU and by putting the three retail alpha scratch owners behind one typed aggregate budget. Preserve immediate growth and draw order while reclaiming one-frame density spikes after sustained under-use. Close stale bounds-cache issue evidence without inventing a cache.
This commit is contained in:
parent
3e18fc2730
commit
f2644d42c2
18 changed files with 857 additions and 34 deletions
|
|
@ -360,7 +360,7 @@ ack-per-packet).
|
|||
|
||||
## #240 — RetailAnimationLoader caches every parsed Animation forever
|
||||
|
||||
**Status:** OPEN
|
||||
**Status:** DONE — 2026-07-24, Modern Runtime Slice D3
|
||||
**Severity:** MEDIUM
|
||||
**Filed:** 2026-07-24
|
||||
**Component:** content / animation
|
||||
|
|
@ -373,12 +373,14 @@ creature/object motion tables grows this monotonically — same class as the
|
|||
audio caches bounded on 2026-07-24, and structurally incapable of the
|
||||
plateau behavior the audit measured for entities/particles.
|
||||
|
||||
**Root cause / status:** 2026-07-24 audit review finding. Bound with the
|
||||
same LRU/byte-budget shape as `DatSoundCache` (2026-07-24) /
|
||||
`BoundedDatObjectCache`. Note sequencers retain references to loaded
|
||||
animations — eviction must not invalidate an Animation a live sequencer
|
||||
still holds (they keep the object alive; the cache only drops its own
|
||||
reference).
|
||||
**Fix:** `RetailAnimationLoader` now has one concurrent in-flight gate plus a
|
||||
64 MiB / 512-entry LRU (startup-configurable through
|
||||
`ResidencyBudgetOptions`). Duplicate requests coalesce, unrelated reads remain
|
||||
parallel, null and oversize results cannot grow the cache, and eviction only
|
||||
drops the cache reference. Live sequencers therefore keep their immutable
|
||||
`Animation` object valid. Deterministic count, byte-pressure, oversize, LRU,
|
||||
and concurrent-load tests cover the policy; the unified residency snapshot
|
||||
reports decoded bytes, budget, and evictions.
|
||||
|
||||
**Files:** `src/AcDream.Content/Vfx/RetailAnimationLoader.cs:19-53`.
|
||||
|
||||
|
|
@ -435,7 +437,7 @@ the ordered array on the publication object.
|
|||
|
||||
## #243 — ObjectMeshManager._boundsCache grows unbounded
|
||||
|
||||
**Status:** OPEN
|
||||
**Status:** DONE — 2026-07-24, stale audit finding closed by Slice D3
|
||||
**Severity:** LOW
|
||||
**Filed:** 2026-07-24
|
||||
**Component:** render
|
||||
|
|
@ -446,8 +448,12 @@ but the one unbounded container in a class where every other cache is
|
|||
deliberately budgeted, and another no-plateau curve for long-uptime
|
||||
sessions.
|
||||
|
||||
**Root cause / status:** 2026-07-24 audit review finding. Bound with the
|
||||
existing entry-count LRU shape; plan Slice D's accounting covers it.
|
||||
**Resolution:** The named field and insertion site do not exist in the current
|
||||
tree: a repository-wide search finds no `_boundsCache` and
|
||||
`ObjectMeshManager` has no bounds memoization owner. The review appears to
|
||||
have described an older or different tree. Slice D deliberately does not add
|
||||
a cache merely to bound it; current mesh/prepared/staging/arena owners are all
|
||||
reported through the residency ledger.
|
||||
|
||||
**Files:** `src/AcDream.App/Rendering/Wb/ObjectMeshManager.cs` (`_boundsCache`,
|
||||
insert site ~1757).
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Modern Runtime Slice D — Typed Asset Handles and Unified Residency
|
||||
|
||||
**Status:** active — D1 and D2 complete
|
||||
**Status:** active — D1 through D3 complete
|
||||
**Program:** `docs/plans/2026-07-24-modern-runtime-architecture.md`
|
||||
**Baseline:** Slice C closeout commit `a564c4b7`
|
||||
**Behavior contract:** no visual-quality or retail-behavior change
|
||||
|
|
@ -227,6 +227,19 @@ residence.
|
|||
- Bring deferred-alpha retained scratch behind a bounded capacity owner.
|
||||
- Close stale #243 after proving no current bounds cache exists.
|
||||
|
||||
**Complete 2026-07-24.** `RetailAnimationLoader` now uses a concurrent
|
||||
in-flight load gate feeding a byte-and-count bounded LRU. Cache eviction drops
|
||||
only the cache reference, so active sequencers retain valid immutable
|
||||
animations; duplicate DID requests coalesce while unrelated reads remain
|
||||
parallel. The shared retail alpha path now partitions its 16 MiB startup budget
|
||||
between the queue, object dispatcher, and particle renderer. Each physical
|
||||
owner grows immediately when a frame requires it, reports exact retained
|
||||
backing capacity, and shrinks only after repeated severe under-use. This bounds
|
||||
one-frame density spikes without changing draw order, particle content, or
|
||||
visible quality. Issue #240 is closed. Issue #243 is closed as a stale audit
|
||||
finding: no `_boundsCache`, bounds memo, or cited insertion site exists in the
|
||||
current source, so no replacement cache was invented.
|
||||
|
||||
### D4 — Diagnostics and forced pressure
|
||||
|
||||
- Publish aggregate and per-domain budgets/occupancy/fragmentation through the
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue