render: pin the cell instance bytes and paint cost #170

Merged
natsukium merged 1 commit from render/pin-paint-output into main 2026-10-18 18:50:25 +09:00
Owner

First of four PRs that extract the wgpu-free half of felis-render-wgpu (palette, box drawing, glyph index, cell painter) into a new felis-render-core crate, so a CPU-rendered client can reuse it instead of reimplementing it. This one changes no behavior; it pins what the later moves must preserve.

  • RowCache::paint_frame + CellFrame: the former Renderer::build_cell_instances body, moved verbatim, so the renderer and the tests share one path from a screen to the uploaded instances.
  • Golden test (row_cache/golden_tests.rs): seven small scenarios (SGR colors, screen reverse, wide/cluster cells with every cursor style, decorations incl. SGR 58, preedit + search, link preview, confirm over search) compared byte-for-byte against tests/fixtures/paint_frame/*.bin, over a real GlyphIndex at the production atlas sides. Regenerate with UPDATE_GOLDEN=1 / just golden.
  • Criterion bench paint_frame: full 200x60 repaint (~512 µs), one dirty row (~8.5 µs), cursor move (~16.7 µs), the baseline the painter move is measured against.
  • row_cache becomes pub mod with RowCache, RowCache::new, paint_frame, CellFrame public, as far as the bench needs.

Next: phase 2 creates felis-render-core with pure moves (palette, box_drawing, atlas) and a deny.toml wrappers ban keeping wgpu/winit out of it.

Verified: just check green locally; sol review PASS.

First of four PRs that extract the wgpu-free half of `felis-render-wgpu` (palette, box drawing, glyph index, cell painter) into a new `felis-render-core` crate, so a CPU-rendered client can reuse it instead of reimplementing it. This one changes no behavior; it pins what the later moves must preserve. - `RowCache::paint_frame` + `CellFrame`: the former `Renderer::build_cell_instances` body, moved verbatim, so the renderer and the tests share one path from a screen to the uploaded instances. - Golden test (`row_cache/golden_tests.rs`): seven small scenarios (SGR colors, screen reverse, wide/cluster cells with every cursor style, decorations incl. SGR 58, preedit + search, link preview, confirm over search) compared byte-for-byte against `tests/fixtures/paint_frame/*.bin`, over a real `GlyphIndex` at the production atlas sides. Regenerate with `UPDATE_GOLDEN=1` / `just golden`. - Criterion bench `paint_frame`: full 200x60 repaint (~512 µs), one dirty row (~8.5 µs), cursor move (~16.7 µs), the baseline the painter move is measured against. - `row_cache` becomes `pub mod` with `RowCache`, `RowCache::new`, `paint_frame`, `CellFrame` public, as far as the bench needs. Next: phase 2 creates `felis-render-core` with pure moves (palette, box_drawing, atlas) and a `deny.toml` `wrappers` ban keeping `wgpu`/`winit` out of it. Verified: `just check` green locally; sol review PASS.
render, docs, skills: pin the cell instance bytes and paint cost
All checks were successful
fuzz / cargo fuzz nightly long-run (pull_request) Has been skipped
darwin / detect relevant changes (pull_request) Successful in 9s
darwin / darwin docs-only no-op (pull_request) Has been skipped
windows / detect relevant changes (pull_request) Successful in 14s
windows / windows docs-only no-op (pull_request) Has been skipped
bench / instruction-count regression gate (pull_request) Successful in 47s
fuzz / cargo fuzz smoke (per target) (pull_request) Successful in 50s
darwin / build felis (aarch64-darwin) (pull_request) Successful in 2m40s
pr / nix flake check (pull_request) Successful in 1m19s
windows / cargo nextest (Windows) (pull_request) Successful in 3m55s
pr / cargo build / clippy / test / deny (pull_request) Successful in 1m41s
pr / wire schema is compatible with the base (pull_request) Successful in 3s
windows / frontend smoke (Windows) (pull_request) Successful in 38s
pr / frontend smoke (x86_64-linux) (pull_request) Successful in 29s
windows / cargo clippy (Windows cross) (pull_request) Successful in 15s
a06fc10600
The renderer-neutral half of felis-render-wgpu (painter, glyph index,
palette) is about to move into its own crate, and glyph sources will
switch from normalized uv to atlas pixels. Neither change may alter
what reaches the GPU, and the painter's unit tests assert fields
against a mock atlas, so they cannot show that.

RowCache::paint_frame is now the one path from a screen and its frame
state to the uploaded instances; the renderer and a byte-level golden
test both go through it, the test over a real GlyphIndex at the
production atlas sides. The paint_frame bench records the full,
one-row and cursor-move costs the move is measured against.

Assisted-by: Claude Code
natsukium deleted branch render/pin-paint-output 2026-10-18 18:50:25 +09:00
Sign in to join this conversation.
No reviewers
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
felis-terminal/felis!170
No description provided.