perf(render): redraw on demand and only changed cells
Rendering used to clear the whole canvas and redraw every cell on every frame callback (~60 fps) even though the simulation ticks at 20 tps and starts paused, keeping CPU usage at ~85% while idle. Split simulation timing out of redraw() into the event loop and render only when displayed content can have changed (tick, painting, pattern placement, preview movement, grid-line toggle, resize); idle frames commit only a new frame callback. Repaint incrementally by diffing the grid against a rendered-state snapshot per row and redrawing just the changed cells, with damage limited to the repainted bounding box. Idle CPU drops to ~1% of one core; running frames render at tick rate (~20 fps) at microsecond cost. Adds grid_copy() snapshot helper with tests and archives the optimize-render-on-demand change with the new on-demand-rendering spec.
This commit is contained in:
+59
@@ -0,0 +1,59 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
Schedules window repaints for the Game of Life canvas: frames are produced only when displayed content changes, and only the changed cells are drawn, so idle CPU usage is near zero while the visible output stays identical to a full repaint.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Frame is rendered only on content change
|
||||
The system SHALL produce a new rendered frame only when displayed content has changed since the last rendered frame, and SHALL NOT redraw when it has not.
|
||||
|
||||
#### Scenario: Idle while paused
|
||||
- **WHEN** the simulation is paused, no tool is active, and no input arrives
|
||||
- **THEN** no new frame is rendered over consecutive display refreshes
|
||||
|
||||
#### Scenario: Tick changes grid
|
||||
- **WHEN** a simulation tick changes the grid while the simulation is running
|
||||
- **THEN** a new frame is rendered that reflects the new generation
|
||||
|
||||
#### Scenario: Edit marks content dirty
|
||||
- **WHEN** the user paints cells or places a pattern
|
||||
- **THEN** a new frame is rendered with the modified cells
|
||||
|
||||
#### Scenario: Preview follows pointer
|
||||
- **WHEN** a tool is selected and the pointer moves to a different cell
|
||||
- **THEN** a new frame is rendered with the pattern preview at the new position
|
||||
|
||||
#### Scenario: Preview-affecting action
|
||||
- **WHEN** the user selects a tool, rotates the active tool, or toggles grid lines
|
||||
- **THEN** a new frame is rendered reflecting the change
|
||||
|
||||
#### Scenario: Resize forces full redraw
|
||||
- **WHEN** the canvas size or scale changes
|
||||
- **THEN** a new frame is rendered over the whole canvas
|
||||
|
||||
### Requirement: Simulation advances independently of rendering
|
||||
The system SHALL accumulate simulation time and apply ticks based on elapsed time, regardless of whether frames are rendered.
|
||||
|
||||
#### Scenario: Ticks accumulate while idle
|
||||
- **WHEN** multiple tick intervals elapse without a rendered frame
|
||||
- **THEN** every elapsed interval results in exactly one applied tick
|
||||
|
||||
### Requirement: Only changed cells are repainted
|
||||
The system SHALL redraw only the cells whose state differs from the last rendered frame, drawing each changed cell's background, grid-line fragments, and cell state, and SHALL leave unchanged cells' pixels untouched.
|
||||
|
||||
#### Scenario: Single cell changes
|
||||
- **WHEN** exactly one cell changes state between rendered frames
|
||||
- **THEN** only that cell's pixel area is rewritten in the framebuffer
|
||||
|
||||
#### Scenario: Unchanged pixels are preserved
|
||||
- **WHEN** a frame is rendered after a change
|
||||
- **THEN** pixels of unchanged cells are identical to the previous frame
|
||||
|
||||
### Requirement: Damage is limited to the changed region
|
||||
The system SHALL report surface damage covering only the area repainted in the current frame.
|
||||
|
||||
#### Scenario: Small change damages small region
|
||||
- **WHEN** only a few cells changed
|
||||
- **THEN** the reported damage is limited to the union of those cells' areas rather than the whole surface
|
||||
Reference in New Issue
Block a user