68df7b96
Clarify dirty-row rendering edge cases
a73x 2026-04-08 18:20
diff --git a/docs/superpowers/specs/2026-04-08-dirty-row-rendering-design.md b/docs/superpowers/specs/2026-04-08-dirty-row-rendering-design.md index ff2cfcb..c058edd 100644 --- a/docs/superpowers/specs/2026-04-08-dirty-row-rendering-design.md +++ b/docs/superpowers/specs/2026-04-08-dirty-row-rendering-design.md @@ -82,6 +82,19 @@ Behavior: - If `layout_dirty == true`, repack all rows and upload the full packed buffer. - Otherwise, overwrite only the changed row byte ranges and cursor byte range in the GPU instance buffer. ### Dirty-flag lifecycle Dirty flags are consumed by the renderer cache and must be cleared only after cache state has been brought in sync with the current render state. Rules: - Read `term.render_state.dirty` and `row_data.items(.dirty)` immediately after `term.snapshot()`. - Complete all required row-cache rebuilds, cursor-cache rebuilds, and any repack decisions before clearing flags. - Clear `term.render_state.dirty` and any consumed row dirty flags only after CPU cache state is updated successfully. - If a rebuild, repack, atlas insertion, or upload-preparation step fails, do not clear dirty flags for that frame. This prevents both permanent “always dirty” behavior and lost updates caused by clearing too early. ### No redraw If terminal state is not dirty and no window/swapchain event forces a frame, skip both cache work and draw submission. @@ -99,6 +112,12 @@ Behavior: - Copy the provided slice into the instance buffer at `offset_instances * @sizeOf(Instance)`. - Unmap memory. Important fallback rule: - If capacity growth is required, `uploadInstanceRange` must not attempt to preserve prior GPU contents implicitly. - Buffer growth forces `layout_dirty = true`, followed by full repack and a full-buffer upload from `packed_instances`. - Partial range uploads are only valid when the underlying GPU buffer remains allocated and existing offsets stay valid. Keep `uploadInstances` for full-buffer writes. No pipeline or draw-call structure changes are required. @@ -150,6 +169,9 @@ Add tests before implementation for: - Layout remains stable when a rebuilt row keeps the same instance count. - Layout becomes dirty when a rebuilt row changes instance count. - Packing offsets remain contiguous after full repack. - Cursor-only updates rebuild cursor cache without requiring unrelated row rebuilds. - Instance-buffer growth during a partial update forces full repack/full upload fallback. - Dirty flags are cleared only after cache refresh planning succeeds. Verification after implementation: