render: repaint and upload only the rows a frame changed #424
No reviewers
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis!424
Loading…
Reference in a new issue
No description provided.
Delete branch "render/incremental-instances"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #403
Per keystroke the client rebuilt every cell instance and re-uploaded the whole bg/fg/deco instance buffers, so one echoed character cost a full-grid walk plus a full-buffer copy.
The renderer now keeps cell instances across frames in fixed-stride row slots (
crates/felis-render-wgpu/src/row_cache.rs), repaints only the rows the client's shadowScreenBuffermarked dirty plus the cursor's old/new rows, and uploads only the changed byte ranges:Queue::write_bufferper changed run;(epoch, version)it last took.Every input that reaches all rows falls back to a full repaint (geometry, cell metrics, viewport, selection, chrome rows, pre-edit, DECSCNM, shape frame, glyph atlas recycle, theme/palette, font reload, atlas thrash, slot overflow). If padded slots would exceed half the device buffer limit, rows stay packed and every frame repaints them all, the same as before. The property test
incremental_frames_match_a_full_rebuilddrives random shadow writes, scrolls, resizes, cursor/paint-state changes, sized cells, and both padded and packed limits, and after every frame it compares the result with a from-scratch walk.ring_slots_track_the_source_through_ranged_writescovers the ring.Measurements
Linux, niri 60 Hz, NVIDIA (adapter confirmed), release builds, interleaved with base
a53cd63e, wl-latency harness, 154x61:(foot control ~2.2 ms p50.) End-to-end p50 does not move because vsync and compositor time dominate it. A 212x93 scroll flood, where every row repaints, costs ~5% more per frame (601/604 -> 628/647 us). That cost and the whole-grid glyph populate walk are split into #422.
macOS (M4 Max): the felis-render-wgpu suite passes with the mapped upload mode. A GUI check could not run because the screen was locked.
natsukium referenced this pull request2026-09-25 10:47:31 +09:00