I have provided a test UIKit app which displays three different images, side by side, each inside a separate MTKView. Each image is tagged with a different color profile:
- Display P3
- uRGB
- Test RGB (from an image supplied in Apple's ImageApp sample).
I set up default values for all color spaces and formats. I then check if the image is tagged and, if so, I override those values with state from the tagged color space.
The variables I am setting:
- “workingColorSpace” in the Metal CIContext, default = sRGB
- “workingFormat” in the Metal CIContext, default = RGBAf
- “outputColorSpace” in the Metal CIContext, default = displayP3
- “colorPixelFormat” in the MTKView, default = bgra8Unorm
- “colorSpace” in a CIRenderDestination that I use in the MTKView delegate draw method
The “colorSpace” default value = CGColorSpaceCreateDeviceRGB()
I also set “pixelFormat” in CIRenderDestination with the MTKView.colorPixelFormat.
If the image is tagged, I override the following values with the tagged colorSpace:
- CIContext.workingColorSpace
- CIContext.outputColorSpace
- CIRenderDestination.colorSpace
If the tagged colorSpace.isWideGamutRGB = true, then I set the CIRenderDestination.colorSpace to extendedSRGB, ignoring the color space in the tagged wide gamut color space, as well as set the colorPixelFormat = bgr10_xr
Results:
- The above scenario will properly render the DisplayP3 image, and the uRGB image. The “Test RGB” image fails:
- If I do not override the CIRenderDestination.colorSpace with a value from the tagged image, then the “Test RGB” image succeeds, but the “uRGB” image fails to render properly:
Question: Do I have everything hooked up correctly and, if so, why does one image fail, and the other succeed?
Link to sample project:
https://www.dropbox.com/scl/fi/57u2fcrgdvys7jtzykzxt/ColorSpaceTest.zip?rlkey=unjeeiu7mi0wx9wfpylt78nwd&dl=0
Update: If the colorspace supports wideGamut, then I set the colorspace in the CAMetalLayer to extendedSRGB, instead of the tagged colorspace:
if let taggedColorSpace = image.colorSpace,
let metalLayer = self.layer as? CAMetalLayer {
metalLayer.colorspace = isWideGamutRGB ? CGColorSpace(name: CGColorSpace.extendedSRGB) : taggedColorSpace
}