A brush dab on an A4 300 ppi CMYK page spent ~5 ms per touched tile in the
GPU canvas's tile upload: every pixel of the 256x256 tile went through the
CMYK -> sRGB transform on one thread. CMYK and Lab tiles now convert in
16-row bands in parallel, and a run of identical pixels (the transparent or
flat area around a dab) is converted once. Texels are bit-identical to the
per-pixel conversion.
The band workers enter the document's CMYK profile scope; before, the rayon
workers converting tiles did not, so a CMYK document tagged with its own
profile uploaded tiles through the built-in coated CMYK instead.
P33 (Windows 11, 32 threads, RTX 5070 Ti, 15 reps): p95 13.7-16.8 ms -> 2.6-3.3 ms.
enforce stays false: the committed baseline machine measures every row
over budget, so it is left for the next baseline.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Some drivers (e.g. Intel Vulkan on Linux/Windows) can't render to Rgba32Float,
so creating the 'fs_content' pipeline panicked with 'Format Rgba32Float is not
renderable' as soon as a document/image was opened. The accumulation format is
now chosen per adapter: Compositor::preferred_acc_format() keeps Rgba32Float
where it's a valid render target and falls back to Rgba16Float otherwise. The
compositor carries the format (pipelines, accumulation texture, byte size and
the readback half-decode all follow it); the app picks it from the eframe
adapter. Capable GPUs are unchanged (parity still exact, 18/18). A new test
forces the Rgba16Float path on any GPU and confirms it renders within display
tolerance (blend + adjustment). wasm green.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>