Can MTKView display HDR CIImage/CVPixelBuffer?

I have tried everything but it looks to be impossible to get MTKView to display full range of colors of HDR CIImage made from CVPixelBuffer (in 10bit YUV format). Only builtin layers such as AVCaptureVideoPreviewLayer, AVPlayerLayer, AVSampleBufferDisplayLayer are able to fully display HDR images on iOS. Is MTKView incapable of displaying full BT2020_HLG color range? Why does MTKView clip colors no matter even if I set pixel Color format to bgra10_xr or bgra10_xr_srgb?

 convenience init(frame: CGRect, contentScale:CGFloat) {
        self.init(frame: frame)
        contentScaleFactor = contentScale
    }

    convenience init(frame: CGRect) {
        let device = MetalCamera.metalDevice
        self.init(frame: frame, device: device)
        colorPixelFormat = .bgra10_xr
        self.preferredFramesPerSecond = 30
    }

    override init(frame frameRect: CGRect, device: MTLDevice?) {
        guard let device = device else {
            fatalError("Can't use Metal")
        }

        guard let cmdQueue = device.makeCommandQueue(maxCommandBufferCount: 5) else {
            fatalError("Can't make Command Queue")
        }

        commandQueue = cmdQueue

        context = CIContext(mtlDevice: device, options: [CIContextOption.cacheIntermediates: false])

        super.init(frame: frameRect, device: device)

        self.framebufferOnly = false
        self.clearColor = MTLClearColor(red: 0, green: 0, blue: 0, alpha: 0)

    }

And then rendering code:

 override func draw(_ rect: CGRect) {

        guard let image = self.image else {
            return
        }

        let dRect = self.bounds
        let drawImage: CIImage

        let targetSize = dRect.size
        let imageSize = image.extent.size

        let scalingFactor = min(targetSize.width/imageSize.width, targetSize.height/imageSize.height)

        let scalingTransform = CGAffineTransform(scaleX: scalingFactor, y: scalingFactor)

        let translation:CGPoint = CGPoint(x: (targetSize.width - imageSize.width * scalingFactor)/2 , y: (targetSize.height - imageSize.height * scalingFactor)/2)
        let translationTransform = CGAffineTransform(translationX: translation.x, y: translation.y)
        let scalingTranslationTransform = scalingTransform.concatenating(translationTransform)

       drawImage = image.transformed(by: scalingTranslationTransform)

        let commandBuffer = commandQueue.makeCommandBufferWithUnretainedReferences()

        guard let texture = self.currentDrawable?.texture else {
            return
        }

        var colorSpace:CGColorSpace        

        if #available(iOS 14.0, *) {
            colorSpace = CGColorSpace(name: CGColorSpace.itur_2100_HLG)!
        } else {
            // Fallback on earlier versions
            colorSpace = drawImage.colorSpace ?? CGColorSpaceCreateDeviceRGB()
        }

        NSLog("Image \(colorSpace.name), \(image.colorSpace?.name)")
        context.render(drawImage, to: texture, commandBuffer: commandBuffer, bounds: dRect, colorSpace: colorSpace)

        commandBuffer?.present(self.currentDrawable!, afterMinimumDuration: 1.0/Double(self.preferredFramesPerSecond))
        commandBuffer?.commit()
    }

Unfortunately, there is no way to utilize the HDR display with Metal on iOS. (You can utilize the EDR APIs on macOS though)

On iOS, you can get some more headroom beyond 1.0 with the XR pixel formats (such as MTLPixelFormatBGR10_XR_sRGB ) but this is not true HDR.

Can MTKView display HDR CIImage/CVPixelBuffer?
 
 
Q