Files
photocraft/docs/select-mask-sparse-refine.md
T
Khawar Zamman WaniandFredApps a38e544faf Make Select and Mask refinement and previews tile-sparse (#10732)
* Make Select and Mask refinement and previews tile-sparse

* Preserve finite mask extent when copying sparse pixels

* Keep solid preview coverage shared during conversion

* Preserve alpha sharing and document sparse refinement limits

* Refine mixed tiles in bounded parallel batches

* Skip guide sampling for constant refinement halos

* Balance sparse refinement batches using measured queue size

* Preserve default alpha and cancel sparse refinement cooperatively

* Address review follow-ups: cancellation after completed flush, stroke assertions, and docstrings

* Fix merge: bind tile bytes to avoid temporary borrow in matting

---------

Co-authored-by: FredApps <fredapps@users.noreply.github.com>
2026-11-05 14:22:03 +01:00

4.2 KiB
Raw Blame History

Sparse Select and Mask refinement (#8822)

Measured 2026-11-01. Refinement writes a zero-default GRAY8 Surface, skips empty tiles, shares solid interiors, and filters mixed blocks in bounded native parallel batches. The queue holds at most 24 blocks and its conservative combined scratch estimate is limited to 512 MiB. Wasm processes the same bounded work sequentially.

Release measurements

Benchmark run, Ubuntu 24.04 hosted runner, RAYON_NUM_THREADS=4, five repetitions per configuration, alternating queue-size order. All rows below come from that same run. Values are medians. The benchmark compares the previous dense tiled implementation (retained under cfg(test)) with the sparse implementation and varies only its queue size. Production uses a fixed queue limit; the benchmark's environment-variable tuning exists only on the scratch branch.

Fixture Dense time (ms) Sparse queue 4 (ms) Sparse queue 24 (ms) Dense peak RSS (KiB) Sparse queue 24 peak RSS (KiB)
Small selection on 6000 × 4000 canvas 6.819 6.792 6.968 9,352 9,332
Select All, 6000 × 4000 54.782 12.863 12.309 56,220 12,892
Thin diagonal, 6000 × 4000 434.603 483.662 348.148 70,868 54,208
Select All, 100,000 × 100,000 Not run 501.262 455.635 Not run 113,988
Thin diagonal, 100,000 × 100,000 Not run 12,305.541 8,475.229 Not run 198,912

Queue 24 reduces the 24 MP diagonal time by 28% against queue 4 and by 20% against the dense reference. The 100k² diagonal improves by 31% against queue 4. The small selection is essentially unchanged; the measurements do not establish a universal speedup. Queue 24 uses more memory than queue 4 on diagonals (54,208 vs 43,016 KiB for 24 MP; 198,912 vs 186,944 KiB for 100k²), while keeping work bounded.

Each measurement runs in a fresh process. Time covers refinement and, for the dense reference, conversion to the output Surface. RSS is the whole process high-water mark, including fixture construction and output checksum calculation; it is not the scratch estimate or a measurement of the desktop app's total memory. Image sampling uses a constant synthetic RGBA8 source, radius 4 and feather 1; the diagonal is a 3 px brush stroke. These fixtures do not measure a textured guide, every radius, or every colour mode. The dense reference is never executed on 100k² fixtures.

Output checksums cover tile coordinates and tile bytes, reusing hashes for shared buffers. Every implementation and queue size produced the same checksum for each fixture. Small-image regression tests separately compare dense and sparse bytes directly, including non-aligned origins, holes, soft coverage, smart radius, and add/restore strokes.

Reproduce using the measurement script and fixture at scratch commit 3f41ac0b. The scratch workflow and runtime queue selector are excluded from the feature PR.

Preview checks

Preview evidence run compares the previous dense Coverage implementation with sparse float-tile Coverage. All six decoded RGBA pairs match exactly: Overlay, Black & White, and On Layers, each with Show Edge off/on, using overlapping add/restore brush strokes. The overlay and edge-band captures were also inspected visually. These are composed preview images, not full-window screenshots; unchanged workspace controls are not assessed by them.

Remaining limits

Candidate work is capped at 1,048,576 blocks; scratch estimates, checked offsets and fallible output writes reject oversized requests before changing the document. Remove Background passes a cooperative interrupt; cancellation is checked while building candidates, between blocks, before batch execution and on workers before filtering. A cancelled refinement discards its partial output. The sparse representation does not make an inherently dense, detailed output small. Refine Hair, Object Aware and Presets remain open, so TOOL-214-1 stays partial and readiness percentages and performance-budget enforcement are unchanged.