docs: pin the offscreen-renderer plan to what felis can offer #1

Merged
natsukium merged 1 commit from design-offscreen-plan into main 2026-09-25 23:19:07 +09:00
Owner

The design now works within what felis's offscreen renderer (natsukium/felis#465) actually offers. The backlog splits font pinning out as a prerequisite that only the golden tests need.

Why

The upstream renderer has no post stage offscreen, makes no promise about alpha, and centers a grid in any target with a spare cell. The earlier design assumed otherwise on each point, and also skipped frames without damage, which loses OSC color overrides, reverse video, image placement and blink-phase changes.

What changed

  • Upstream prerequisite: now lists what felis provides and its limits: an offscreen target with no post stage, a working resize, and read_frame with no alpha promise. Font pinning is its own part, because FontStack::new alone drops fallbacks and style faces. The claim that pipeline.md already anticipated a headless renderer consumer is dropped; that passage is about IPC pacing.
  • Timing: every output frame is rendered, and duplicates are detected by comparing the read-back bytes. A new section records why damage-driven frame skipping is rejected.
  • Frame size: the offscreen target is resized to the exact grid on each size frame, and each frame is padded into the top-left of the largest canvas on the CPU.
  • Theme and font: the RendererConfig is built from felis-client-core's public config types, because felis-client's conversion is private. A configured post shader is dropped with a warning.
  • Encoding: alpha is set to 255 after readback, with the reason.
  • Revisit if: now names the data-returning renderer_effect shape and its limit, and adds shader-styled recordings.
  • Source references are rebased to felis 5395be3f.
The design now works within what felis's offscreen renderer (natsukium/felis#465) actually offers. The backlog splits font pinning out as a prerequisite that only the golden tests need. ## Why The upstream renderer has no post stage offscreen, makes no promise about alpha, and centers a grid in any target with a spare cell. The earlier design assumed otherwise on each point, and also skipped frames without damage, which loses OSC color overrides, reverse video, image placement and blink-phase changes. ## What changed - **Upstream prerequisite:** now lists what felis provides and its limits: an offscreen target with no post stage, a working `resize`, and `read_frame` with no alpha promise. Font pinning is its own part, because `FontStack::new` alone drops fallbacks and style faces. The claim that `pipeline.md` already anticipated a headless renderer consumer is dropped; that passage is about IPC pacing. - **Timing:** every output frame is rendered, and duplicates are detected by comparing the read-back bytes. A new section records why damage-driven frame skipping is rejected. - **Frame size:** the offscreen target is resized to the exact grid on each `size` frame, and each frame is padded into the top-left of the largest canvas on the CPU. - **Theme and font:** the `RendererConfig` is built from felis-client-core's public config types, because felis-client's conversion is private. A configured post shader is dropped with a warning. - **Encoding:** alpha is set to 255 after readback, with the reason. - **Revisit if:** now names the data-returning `renderer_effect` shape and its limit, and adds shader-styled recordings. - Source references are rebased to felis `5395be3f`.
The upstream offscreen renderer has no post stage (its clock and the
trail shader's state would otherwise leak host time into the output),
promises nothing about alpha, and centers a grid in any target with a
spare cell. The design now works within that: every output frame is
rendered and deduplicated by comparing read-back bytes, the target is
resized to the exact grid and padded top-left on the CPU, and alpha is
forced to 255 before encoding.

Damage-driven frame skipping is rejected because OSC color overrides,
reverse video, image placement and blink-phase changes alter pixels
without dirtying a row, and a missed case drops a visible change
without an error. Font pinning is split out as a golden-test
prerequisite, and the base theme is built from felis-client-core's
public config types because felis-client's conversion is private.

Assisted-by: Claude Code
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
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
natsukium/felis-reel!1
No description provided.