Add support for the HDRExtendedSrgbLinear color space on Metal
Request 16 bit floating point backbuffers and set the color space of the CAMetalLayer to kCGColorSpaceExtendedLinearSRGB if we set up the swap chain to use extended SRGB. Unfortunately the required CAMetalLayer.wantsExtendedDynamicRangeContent property is not yet available on iOS, so for now this is a macOS only feature. Change-Id: I28ab12cc0b829eded721061da2679be8e31d6b9d Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>bb10
parent
c253e65429
commit
ed5f33a3f1
|
|
@ -4033,6 +4033,10 @@ QSize QMetalSwapChain::surfacePixelSize()
|
|||
|
||||
bool QMetalSwapChain::isFormatSupported(Format f)
|
||||
{
|
||||
#ifdef Q_OS_MACOS
|
||||
if (@available(macOS 10.12, /*iOS 10.0,*/ *))
|
||||
return f == SDR || f == HDRExtendedSrgbLinear;
|
||||
#endif
|
||||
return f == SDR;
|
||||
}
|
||||
|
||||
|
|
@ -4064,6 +4068,13 @@ void QMetalSwapChain::chooseFormats()
|
|||
QRHI_RES_RHI(QRhiMetal);
|
||||
samples = rhiD->effectiveSampleCount(m_sampleCount);
|
||||
// pick a format that is allowed for CAMetalLayer.pixelFormat
|
||||
if (m_format == HDRExtendedSrgbLinear) {
|
||||
if (@available(macOS 10.12, /*iOS 10.0,*/ *)) {
|
||||
d->colorFormat = MTLPixelFormatRGBA16Float;
|
||||
d->rhiColorFormat = QRhiTexture::RGBA16F;
|
||||
return;
|
||||
}
|
||||
}
|
||||
d->colorFormat = m_flags.testFlag(sRGB) ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm;
|
||||
d->rhiColorFormat = QRhiTexture::BGRA8;
|
||||
}
|
||||
|
|
@ -4095,6 +4106,14 @@ bool QMetalSwapChain::createOrResize()
|
|||
chooseFormats();
|
||||
if (d->colorFormat != d->layer.pixelFormat)
|
||||
d->layer.pixelFormat = d->colorFormat;
|
||||
#ifdef Q_OS_MACOS
|
||||
if (@available(macOS 10.12, /*iOS 10.0,*/ *)) { // Can't enable this on iOS until wantsExtendedDynamicRangeContent is available
|
||||
if (m_format == HDRExtendedSrgbLinear) {
|
||||
d->layer.colorspace = CGColorSpaceCreateWithName(kCGColorSpaceExtendedLinearSRGB);
|
||||
d->layer.wantsExtendedDynamicRangeContent = YES;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_flags.testFlag(UsedAsTransferSource))
|
||||
d->layer.framebufferOnly = NO;
|
||||
|
|
@ -4189,4 +4208,26 @@ bool QMetalSwapChain::createOrResize()
|
|||
return true;
|
||||
}
|
||||
|
||||
QRhiSwapChainHdrInfo QMetalSwapChain::hdrInfo()
|
||||
{
|
||||
QRhiSwapChainHdrInfo info;
|
||||
info.limitsType = QRhiSwapChainHdrInfo::ColorComponentValue;
|
||||
if (m_format == SDR) {
|
||||
info.limits.colorComponentValue.maxColorComponentValue = 1;
|
||||
return info;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_MACOS
|
||||
info.isHardCodedDefaults = false;
|
||||
NSView *view = reinterpret_cast<NSView *>(window->winId());
|
||||
info.limits.colorComponentValue.maxColorComponentValue = view.window.screen.maximumExtendedDynamicRangeColorComponentValue;
|
||||
#else
|
||||
// ### Fixme: Maybe retrieve the brightness from the screen and if we're not at full brightness we might be able to do more.
|
||||
// For now, assume 2, in line with iPhone 12 specs that claim 625 nits max brightness and 1200 nits max HDR brightness.
|
||||
info.isHardCodedDefaults = true;
|
||||
info.limits.colorComponentValue.maxColorComponentValue = 2;
|
||||
#endif
|
||||
return info;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -330,6 +330,8 @@ struct QMetalSwapChain : public QRhiSwapChain
|
|||
|
||||
bool createOrResize() override;
|
||||
|
||||
virtual QRhiSwapChainHdrInfo hdrInfo() override;
|
||||
|
||||
void chooseFormats();
|
||||
|
||||
QWindow *window = nullptr;
|
||||
|
|
|
|||
Loading…
Reference in New Issue