perf(core): elide redundant raster clears - #412
Draft
lfkdsk wants to merge 1 commit into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
render_scaled_implclears the framebuffer to opaque black before every fullrender. When the DrawList's first drawing command provably covers the whole target
with an opaque colour, that clear writes 130,560 pixels that the next command
immediately overwrites.
The proof stays deliberately narrow: the first command must be a
RECTorGRAD_RECTwhose colour words all carry alpha 255 and whose rectangle coversthe target, optionally preceded by one full-target root
SCISSOR. Transparentfirst operations, partial or clipped rectangles, transforms and TRIs, empty or
truncated streams and unknown opcodes all keep the clear.
Measured on
mainAn 8-process microbenchmark moves the eligible path from 18,013 ns to 9,058 ns
per render (−49.7%) and leaves the fallback path at 13,722 → 13,706 ns
(−0.12%). A d1/s1 full-render hero replay goes 84.466 → 73.082 ms (−13.5%). The
wasm grows 606 bytes.
Where it applies, and where it does not
This only helps callers that enter the full raster clear:
tests/golden.ts,tools/tape.tsrecord/replay/--png,hosts/simand the launcher screenshotsthat consume it, the Vita software rasterizer, the Apple/Symbian ARGB
full-redraw fallback, and the ESP32-PPA RGB565 ordered fallback. PSP draws
glyphs through GE hardware and is unaffected.
It fires on all 180 frames of a full-render replay and zero times on 180
incremental-render frames, so on the already-incremental web path its
attributable benefit is 0 ms / 0%. Stacked with #411 rather than added to it,
the d2/s2 hero replay goes from 260.030 ms (glyph sparse alone) to 212.682 ms
(−18.2%).
Verification
A 522-case matrix compares against clean
mainbyte for byte: viewports4×3/5×3/7×5/4.9×3.1/480×272/479.7×271.4, scales 1/2/3, ~29 first-command shapes
including negative origins, dimensions at −1/0/+1 of the target, leading
full/oversize/undersize/shifted scissors, gradient directions, semitransparent
and alpha-254 colours, TRI/empty/truncated/unknown opcodes, across RGBA8, ARGB
and RGB565. Every framebuffer is seeded with nonzero bytes so a missing write
cannot hide behind zero initialisation; 216 of the 522 cases take the elision
branch and none leak.
The coverage predicate and the rasterizer's rect fill share the same integer
xy()/wh()helpers, so there is no second rounding rule that could leave astale edge pixel; a rectangle one pixel short in any direction keeps the clear.
Suite behaviour matches clean
mainexactly: the same five unit failures and thesame frame-0 divergence of the committed
hero-maintape hashes.