feat(render): add transactional strip rendering - #190
Conversation
8e4fb0b to
a4e1547
Compare
…er op family Rgb565WindowTarget::blend duplicated Rgb565Target::blend verbatim modulo the local_offset translation — the exact place where the strip-equals-full-window invariant would drift silently if one copy were ever edited alone. Extract blend_rgb565_pixel and use it from both targets so the parity holds by construction. Pin that invariant with an integration suite: strip tilings (uneven, per-row, scale 2) reassemble byte-identically to a full render across every DrawList op family (RECT, GRAD_RECT both axes, SCISSOR, TRI, TEX_QUAD 8888, TEX_TRI, GLYPH_RUN, SRM-eligible 5650 TEX_QUAD), through the all-software window fallback and through SRM-over-PPA including a band split across the quad; offset windows leave the exterior untouched, and repeated strips stay byte-identical across mask reallocation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Verdict: fit to merge. Reviewed with the repo review workflow ( What was verifiedThe strip ≡ full-window invariant — empirically, past the PR's own matrix. The PR claims global gradient, glyph, texture, and triangle sampling survive the compact window, but its parity test only exercised RECT/GRAD_RECT at scale 1. I probed a 16×10 scene touching every DrawList op family (RECT, GRAD_RECT both axes, SCISSOR/SCISSOR_POP, TRI, TEX_QUAD 8888, TEX_TRI, GLYPH_RUN with a density-2 atlas, and an SRM-eligible one-to-one 5650 TEX_QUAD), with ops deliberately straddling strip boundaries:
7/7 pass — committed as Window-target asserts are unreachable on valid input. Every rasterizer ( Existing paths are behavior-preserving. Determinism / golden architecture: no impact. What was pushed (c2b187a)
Left alone, with reasons
Local gate
|
What changed
prepare_damage,commit_damage, andabort_damageoperations on the ESP32-P4 PPA rendererrender_stripfor full-viewport-width, tightly packed dirty stripsWhy
Asynchronous display hosts must render and submit several reusable strips before they can advance a persistent framebuffer's damage history. Coupling history updates to
render_incrementalcannot represent a failed or partially submitted display transaction.The split API keeps history unchanged until presentation succeeds, invalidates it on abort, and preserves global gradient, glyph, texture, and triangle sampling when software fallback writes into a compact strip.
Impact
Existing full-frame and incremental callers are unchanged. The new API is backend-neutral and keeps board/display ownership outside PocketJS Core.
Validation
cargo test --locked --manifest-path engine/core/Cargo.toml --features std— 100 passedcargo test --locked --manifest-path engine/backends/esp32p4-ppa/Cargo.toml --features std— 20 passedcargo check --locked --manifest-path engine/backends/esp32p4-ppa/Cargo.toml --features esp-idfgit diff --check