prometeu-runtime/discussion/workflow/plans/PLN-0020-cache-refresh-and-render-frame-path.md

125 lines
3.8 KiB
Markdown

---
id: PLN-0020
ticket: render-all-scene-cache-and-camera-integration
title: Plan - Cache Refresh and render_frame Path
status: accepted
created: 2026-04-14
completed:
tags: [gfx, runtime, render, cache, resolver, frame-composer]
---
## Objective
Connect `FrameComposer` to `SceneViewportResolver`, apply cache refreshes inside `FrameComposer`, and establish `render_frame()` as the canonical composition path for world + sprites + fades.
## Background
`DEC-0014` requires that cache refresh policy remain inside `FrameComposer` and that `FrameComposer.render_frame()` become the canonical frame entry while `Gfx` remains only the low-level execution backend.
## Scope
### Included
- apply `CacheRefreshRequest`s in `FrameComposer`
- connect camera/scene state to resolver updates
- use cache-backed world rendering in the frame path
- keep valid no-scene rendering (`sprites + fades`)
### Excluded
- HUD integration
- final retirement cleanup of legacy callsites
## Execution Steps
### Step 1 - Apply resolver refreshes inside `FrameComposer`
**What:**
Move cache-refresh orchestration fully into `FrameComposer`.
**How:**
- On active-scene frames:
- call resolver update with current camera and scene
- consume returned `CacheRefreshRequest`s
- apply them to `SceneViewportCache`
- Keep `Gfx` unaware of refresh semantics.
**File(s):**
- `crates/console/prometeu-drivers/src/frame_composer.rs`
### Step 2 - Define `render_frame()` as the canonical frame path
**What:**
Introduce the new frame service on `FrameComposer`.
**How:**
- Add `render_frame()` to `FrameComposer`.
- If a scene is active and renderable:
- prepare resolver update
- refresh cache
- call the cache-backed world path in `Gfx`
- If no scene is active:
- call the no-scene path for `sprites + fades`
**File(s):**
- `crates/console/prometeu-drivers/src/frame_composer.rs`
- `crates/console/prometeu-drivers/src/gfx.rs`
### Step 3 - Keep `Gfx` as backend only
**What:**
Narrow `Gfx` to backend-oriented composition responsibilities.
**How:**
- Ensure `Gfx` consumes prepared state from `FrameComposer`.
- Do not let `Gfx` regain ownership of cache refresh or scene orchestration.
- Keep low-level helpers for cache-backed copy paths, sprite drawing, and fades in `Gfx`.
**File(s):**
- `crates/console/prometeu-drivers/src/gfx.rs`
### Step 4 - Cover scene and no-scene frame paths
**What:**
Protect the two canonical frame modes.
**How:**
- Add tests for:
- active-scene world composition
- no-scene `sprites + fades`
- scene transition through unbind/rebind
- cache refresh behavior staying inside `FrameComposer`
**File(s):**
- `crates/console/prometeu-drivers/src/frame_composer.rs`
- `crates/console/prometeu-drivers/src/gfx.rs`
## Test Requirements
### Unit Tests
- `render_frame()` with no scene produces valid no-scene composition.
- `render_frame()` with a scene applies resolver refreshes before composition.
- cache refresh requests are applied by `FrameComposer`, not `Gfx`.
### Integration Tests
- scene bind + camera set + sprite emission + `render_frame()` produces the expected composed frame.
### Manual Verification
- Verify that no-scene frames still render sprites/fades without crashes or hidden clears.
## Acceptance Criteria
- [ ] `FrameComposer.render_frame()` exists and is the canonical frame path.
- [ ] Cache refreshes are applied inside `FrameComposer`.
- [ ] World rendering consumes the cache-backed path.
- [ ] No-scene `sprites + fades` behavior remains valid.
- [ ] `Gfx` remains backend-only for this path.
## Dependencies
- Depends on `PLN-0017`, `PLN-0018`, and `PLN-0019`
- Source decision: `DEC-0014`
## Risks
- If refresh application leaks into `Gfx`, the ownership split from `DEC-0014` collapses.
- If no-scene behavior is not tested explicitly, scene integration can accidentally make scene binding mandatory.