Repository navigation
feat(馃崗): honor GPUCanvasConfiguration.colorSpace on iOS - #586
Merged
Merged
Conversation
configure() ignored colorSpace, so a canvas was always sRGB. "display-p3" now tags the CAMetalLayer Display P3 (extended Display P3 on rgba16float). Android still ignores it.
wcandillon
self-requested a review
October 22, 2026 06:13
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.
Problem
context.configure({ colorSpace })is part of the WebGPU spec (PredefinedColorSpace:"srgb"|"display-p3"), butGPUCanvasConfigurationdrops it, so a canvas is always sRGB. On iOS that matters wherever the canvas sits next to Display P3 content. react-native-skia's iOS canvas is Display P3, so a WebGPU canvas drawn beside it, or one that has to reproduce a Skia shader, needs a manual sRGB鈫擯3 conversion in its last pass, and anrgba16floatcanvas to carry the result.Change (iOS only)
GPUCanvasConfigurationreadscolorSpace("srgb"default,"display-p3"); any other value throws aTypeErroras in the browser.SurfaceInfokeeps it next to the configuration.applyCAMetalLayerColorSpacetakes it into account:srgb(unchanged)display-p3kCGColorSpaceDisplayP3rgba16floatkCGColorSpaceExtendedSRGBkCGColorSpaceExtendedDisplayP3Values keep the sRGB transfer function, as the spec says, and both constants exist from iOS 14, so this is within the package's iOS floor.
Android is untouched: it parses and ignores the option. The docs say so. Happy to look at the
SurfaceViewdata space as a follow-up if you want parity.Docs: a "Color space" section in
api/canvas.mdxandgetting-started/canvas.mdx. Tests inCanvasContext.spec.tsconfigure both values on both format paths and check that an unknown value is rejected. They only check configuration, because the layer colorspace is not readable from JS.Verification
Measured on an iPhone 12 (Release build, react-native-webgpu 0.13.0 with this diff applied). The same animated scenes were drawn two ways: a shader converting its Display P3 output to sRGB by hand into an
rgba16floatcanvas (the workaround this makes unnecessary), and the raw Display P3 values into a canvas configuredcolorSpace: "display-p3". I compared screenshots of the same state over the pixels whose channel spread is above 60, where a wrong set of primaries would show most:rgba16float,display-p3display-p3Flat areas differ by at most 1/255.
yarn test), an Android build, and a control with the layer left sRGB. I could only syntax-check the.mmagainst the Dawn 154 headers I had installed.Notes
The Skia side of the same problem, a Skia image wrapping a WebGPU texture being converted sRGB鈫扨3 when sampled, is a react-native-skia matter and not touched here.