computeCoverage only: single-pass gather + delta prefix-sum coverage#589
Open
treeform wants to merge 1 commit into
Open
computeCoverage only: single-pass gather + delta prefix-sum coverage#589treeform wants to merge 1 commit into
treeform wants to merge 1 commit into
Conversation
Minimal variant of #586 keeping only the computeCoverage changes: - Gather subsample hits in one pass over the entries (each entry loaded once instead of once per subsample line), bucketed per line - Accumulate coverage as int16 deltas and convert with one prefix-sum pass per scanline (NEON on arm64) instead of adding sample coverage to every covered pixel per subsample - Track covered regions so blending only touches real coverage, removing the per-scanline zeroMem for Overwrite/Normal blends - Store 1/m in PartitionEntry, replacing the per-hit divide Ghostscript Tiger: master 6.96-7.03 ms, this branch 6.48-6.56 ms (interleaved runs; full #586 measures 6.04-6.20 ms in the same runs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Summary
Minimal variant of #586 per guzba's request: everything reverted except the
computeCoveragechanges (plus the1/minverse inPartitionEntryand the small bits that necessarily reach outside —fillCoveragegaining an offset/len window, the extra scratch seqs infillShapes, asortHitsoffset overload, andwalktakingopenArray).Not included (vs #586): thread-local scratch reuse, the
partitionSegmentsrewrite (numEntries, slope-based clipping, alloc reuse),shapesToSegmentsinto a reused buffer,newSeqUninit, blender hoisting / inlinedblendNormalin the trapezoid path.Timings
Ghostscript Tiger,
nim c -d:danger tests/bench_svg.nim, M-series Mac. All three binaries run interleaved in the same session to control for machine load (the box was moderately loaded; ratios were stable across rounds even as absolute numbers drifted):So the computeCoverage rework is the meat (~60% of the total win); the scratch/allocation/partitionSegments changes in #586 account for the remaining ~4-5%.
What the computeCoverage change does
int16delta buffer. One prefix-sum pass per scanline (NEON-vectorized on arm64, scalar elsewhere) produces the exact same coverage bytes. The deltas buffer is provably re-zeroed by the pass itself.fillCoverageand clearing only touch real coverage instead of the full path-bounds width for Overwrite/Normal blends. On the tiger that's 1.69M blended pixels per render down to 1.08M against an 810k-pixel image.PartitionEntry.invMreplaces the per-hit divide with a multiply (also used bysolveX).Correctness
Every
test_svgandtest_pathsxray score matches master to 4 decimal places (remaining last-bit differences come from(y-b)*invMvs(y-b)/m).test_images_draw,test_paints,test_contexts,test_fontspass.🤖 Generated with Claude Code