# Tasks ## 1. Event-driven rendering (stage 1) - [x] 1.1 Move simulation tick timing (dt accumulation, `simulation_tick()` calls) out of `redraw()` into the main dispatch loop; verify with `ctest --test-dir build` and by running `./build/wlgol` that animation still advances when unpaused - [x] 1.2 Add `screen_dirty` / `full_redraw` flags set from all content sources (tick, paint drag, click placement, pointer motion with active tool, tool select/rotate, grid-line toggle, `need_resize`); verify each source produces a repaint by exercising it in the app - [x] 1.3 Rework `wl_callack_done`/loop so a clean frame commits only a new frame callback (no attach, no damage) and a dirty frame renders only when the buffer is `released`, otherwise defers to the next callback; verify with `top` that paused idle CPU is ~0% and that unpausing at 20 tps renders without visual glitches - [x] 1.4 Update the FPS log line to report rendered frames per second and verify the printed values match expected render counts (≈20 while running, 0 while idle) ## 2. Incremental repaint (stage 2) - [x] 2.1 Add a `grid_rendered` snapshot buffer sized/moved together with `grid` in `canvas_resize` (helper in `grid.c`/`grid.h` is acceptable), and verify it survives a window resize without out-of-bounds access - [x] 2.2 Implement the per-row diff between `grid` and `grid_rendered` and a `repaint_cell()` that draws background, grid-line fragments on all four edges, and the cell body for each changed cell; verify by stepping (`ACTION_STEP`) a single-cell change and inspecting that only that cell's pixels change and shared edges stay intact - [x] 2.3 Track last-frame preview cells (and whether the preview was shown) and add them to the repaint set alongside the diff, drawing the new preview last; verify the preview leaves no smearing when moving the cursor and rotates/selects cleanly - [x] 2.4 Copy `grid` into `grid_rendered` at the end of each rendered frame and report damage as the bounding box of repainted cells (whole canvas on `full_redraw`); verify with `WAYLAND_DEBUG=1 ./build/wlgol` that damage rects match changed cells - [x] 2.5 Extend grid tests in `tests/test_grid.c` for the snapshot helper (resize copy bounds, snapshot/diff round-trip) and verify with `ctest --test-dir build` ## 3. Integration verification - [x] 3.1 Full visual pass vs the pre-change renderer: paused idle, painting while paused, pattern placement and rotation, grid-line toggle, resize with fractional scale, unpause at min/max speed — confirm no visual differences; measure CPU with `top` in each state and record before/after numbers