acdream/src/AcDream.App/Rendering/Wb
Erik 3639a6f4ac feat(perf): Tier 1 entity classification cache
Per docs/plans/2026-05-10-perf-tiers-2-3-roadmap.md Tier 1: cache the
per-(entity, meshRef, batch) classification (TextureCache lookup,
GroupKey hash, _groups dict insert) so the per-frame Draw inner loop
becomes "look up cache → walk assignments → append matrix to group's
Matrices list."

For static entities (~95% of world: trees, rocks, buildings, scenery),
the answer never changes between frames. Cache once at first visit;
reuse permanently. Per-frame work for static drops from 4 expensive
operations per (meshRef, batch) to 1 list-append.

Estimated entity dispatcher: 3.5ms → ~1-1.5ms median at radius=12.
Should land inside the 2.0ms spec budget.

Implementation:
- New EntityClassificationCache class (per-meshRef list of cached
  (group ref, baked-PartTransform) tuples) keyed by entity.Id.
- ClassifyEntity does the one-time work; result populates _groups and
  the cache.
- Draw inner loop: cache lookup → for each assignment, model =
  PartTransform × entityWorld; group.Matrices.Add(model).
- Cache miss when ClassifyEntity finds NO mesh loaded yet (Vao == 0)
  → don't store; retry next frame. Avoids cache thrash during the
  streaming-in window.
- Public InvalidateEntity(uint id) + ClearEntityCache() for explicit
  invalidation hooks. Wiring (palette swap on ObjDescEvent, MeshRefs
  hot-swap) is post-A.5 follow-up — for now, cache-stale entities
  show their pre-swap appearance until next respawn.

Tier 2 (static/dynamic split with persistent groups) and Tier 3 (GPU
compute culling) tracked in the roadmap doc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 09:45:18 +02:00
..
AcSurfaceMetadata.cs phase(N.4): AcSurfaceMetadata side-table for WB-pristine surface props 2026-05-08 13:08:56 +02:00
AcSurfaceMetadataTable.cs phase(N.4): AcSurfaceMetadata side-table for WB-pristine surface props 2026-05-08 13:08:56 +02:00
AnimatedEntityState.cs phase(N.4) Tasks 16+18+19: AnimatedEntityState + AnimPartChange + HiddenParts 2026-05-08 14:37:09 +02:00
BindlessSupport.cs fix(N.5b): black terrain — switch to uvec2 handle + sampler constructor 2026-05-09 12:53:21 +02:00
DrawElementsIndirectCommand.cs phase(N.5) Task 7: dispatcher SSBO + indirect buffer infrastructure 2026-05-08 20:25:29 +02:00
EntitySpawnAdapter.cs feat(A.5 T18): use cached WorldEntity AABB in dispatcher; populate at register 2026-05-10 08:20:20 +02:00
ITextureCachePerInstance.cs phase(N.4) Task 17: EntitySpawnAdapter for server-spawned per-instance content 2026-05-08 14:46:34 +02:00
IWbMeshAdapter.cs phase(N.4): WbMeshAdapter stub + IWbMeshAdapter interface 2026-05-08 13:18:50 +02:00
LandblockSpawnAdapter.cs phase(N.4) Task 11: LandblockSpawnAdapter (atlas-tier ref-count bridge) 2026-05-08 13:53:38 +02:00
WbDrawDispatcher.cs feat(perf): Tier 1 entity classification cache 2026-05-10 09:45:18 +02:00
WbMeshAdapter.cs phase(N.4) Tasks 22+23 fixup: trigger WB mesh loads + correct SurfaceId source 2026-05-08 15:50:21 +02:00