148 lines
4.7 KiB
Markdown
148 lines
4.7 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 `Scene`, 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. 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 `Scene`.
|
|
|
|
**How:**
|
|
- Represent one cache aggregate containing four internal layer caches.
|
|
- 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 `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 `Scene` 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 `Scene` / `SceneLayer` / `TileMap` types.
|
|
- 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.
|