prometeu-runtime/discussion/workflow/plans/PLN-0012-scene-viewport-cache-structure.md
2026-04-13 20:19:40 +01:00

148 lines
5.0 KiB
Markdown

---
id: PLN-0012
ticket: scene-bank-and-viewport-cache-refactor
title: Plan - Scene Viewport Cache Structure
status: accepted
created: 2026-04-13
completed:
tags: [gfx, tilemap, runtime, render]
---
## Objective
Implement the `SceneViewportCache` as the operational render cache for one `SceneBank`, including one internal ringbuffer per layer and lightweight derived cache entries for raster acceleration.
## Background
`DEC-0013` locks `SceneViewportCache` as the renderer-facing view of scene data and prefers internal ringbuffer storage per layer. `PLN-0011` already established the canonical source as `SceneBank` with exactly four `SceneLayer`s in a fixed array and moved per-layer movement metadata to `motion_factor`. This plan isolates the cache data structure and update API before resolver and renderer integration.
## Scope
### Included
- Define `SceneViewportCache`.
- Define the per-layer internal ringbuffer structure.
- Define the cached tile entry format.
- Define cache update APIs for line, column, and area/region.
- Define full invalidation on scene swap.
### Excluded
- camera logic
- drift/hysteresis logic
- final renderer migration
- execution of blits into `back`
## Execution Steps
### Step 1 - Define cache entry and layer-cache structures
**What:**
Create the internal data model for one viewport cache layer and for cached tile entries.
**How:**
- Introduce a cache tile entry type that stores:
- resolved `glyph_id`
- resolved `palette_id`
- packed flip flags
- `active/empty`
- fast layer-local glyph bank reference/index
- Introduce one ringbuffer-backed layer-cache structure per scene layer.
- Keep ringbuffer internals encapsulated and out of public semantic APIs.
**File(s):**
- New HAL or driver-side viewport-cache module(s), likely under:
- `crates/console/prometeu-hal/src/`
- and/or `crates/console/prometeu-drivers/src/`
### Step 2 - Define `SceneViewportCache` as a four-layer aggregate
**What:**
Create the top-level cache aggregate for one `SceneBank`.
**How:**
- Represent one cache aggregate containing four internal layer caches aligned to `SceneBank.layers`.
- Thread through cache dimensions and tile-size assumptions for V1.
- Make the cache explicitly scene-derived and non-canonical.
**File(s):**
- New cache module(s)
- Any related exports in HAL/driver public surfaces
### Step 3 - Implement cache mutation APIs
**What:**
Define the update surface that later plans will use for rematerialization.
**How:**
- Add explicit APIs for:
- refresh line
- refresh column
- refresh area/region
- invalidate whole cache on scene swap
- Ensure corner refresh can use region updates without duplicate work on already-present tiles.
**File(s):**
- New cache module(s)
- Any helper modules shared with resolver integration
### Step 4 - Implement scene-to-cache materialization helpers
**What:**
Add helpers that copy canonical scene data into cache entries.
**How:**
- Build helpers that read canonical `SceneBank` / `SceneLayer` / `TileMap` data and populate cache entries.
- Keep the helpers unaware of camera policy; they should only perform requested materialization work.
- Ensure per-layer movement factors remain metadata of the scene layer, not cache-only state.
**File(s):**
- New cache/materialization helper module(s)
### Step 5 - Add focused tests for cache structure and update rules
**What:**
Protect the cache shape and update operations before wiring the resolver.
**How:**
- Add tests for:
- ringbuffer wrap behavior
- line refresh
- column refresh
- region refresh
- scene-swap invalidation
- no duplicate reload for corner-style region updates
**File(s):**
- Tests colocated with cache modules
## Test Requirements
### Unit Tests
- Each cache layer maintains ringbuffer invariants under wrap.
- Cache entry fields match the expected derived values from canonical scene tiles.
- Line/column/region refresh APIs only rewrite the requested area.
### Integration Tests
- Materialization from `SceneBank` into `SceneViewportCache` succeeds across all four layers.
### Manual Verification
- Inspect debug output or temporary probes to confirm cache updates do not expose ringbuffer details outside the cache boundary.
## Acceptance Criteria
- [ ] `SceneViewportCache` exists as a four-layer aggregate.
- [ ] Each layer cache uses internal ringbuffer storage.
- [ ] Cache entries store the lightweight derived raster fields defined by the decision.
- [ ] Explicit APIs exist for line, column, area/region, and full invalidation.
- [ ] Tests cover wrap and non-duplicative corner updates.
## Dependencies
- Depends on `PLN-0011` for canonical `SceneBank` / `SceneLayer` / `TileMap` types and the fixed four-layer shape.
- Source decision: `DEC-0013`
## Risks
- Over-designing cache entry shape can accidentally turn the cache into a second heavy scene representation.
- Ringbuffer implementation bugs can stay hidden until resolver integration if tests are too weak.
- Region refresh semantics can become ambiguous if API boundaries are not explicit early.