macOS: Respect color space set on NSWindow when flushing backingstore
By default Qt tries to avoid potentially costly color matching by not assigning an sRGB color space to our backingstore, even if that's what we in practice fill it with. We used to do this by assigning the display's color space, which effectively opts out of color matching, similar to the old behavior of the device RGB color space (which nowadays implies sRGB). By picking up the color space from the NSWindow instead, we allow the user to override the color space to trigger color matching, for example by explicitly setting it to NSColorSpace.sRGBColorSpace. NSWindow will fall back to the screen's color space if the window doesn't have one set. Task-number: QTBUG-47660 Change-Id: Iac8177e85e86fe9044a41eb2c93fbf26bb83c248 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
5b3c09e35f
commit
e6498362fd
@ -49,7 +49,14 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QNSWindowBackingStore : public QRasterBackingStore
|
||||
class QCocoaBackingStore : public QRasterBackingStore
|
||||
{
|
||||
protected:
|
||||
QCocoaBackingStore(QWindow *window);
|
||||
QCFType<CGColorSpaceRef> colorSpace() const;
|
||||
};
|
||||
|
||||
class QNSWindowBackingStore : public QCocoaBackingStore
|
||||
{
|
||||
public:
|
||||
QNSWindowBackingStore(QWindow *window);
|
||||
@ -64,7 +71,7 @@ private:
|
||||
void redrawRoundedBottomCorners(CGRect) const;
|
||||
};
|
||||
|
||||
class QCALayerBackingStore : public QPlatformBackingStore
|
||||
class QCALayerBackingStore : public QCocoaBackingStore
|
||||
{
|
||||
public:
|
||||
QCALayerBackingStore(QWindow *window);
|
||||
|
@ -48,11 +48,24 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
|
||||
QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
|
||||
: QRasterBackingStore(window)
|
||||
{
|
||||
}
|
||||
|
||||
QCFType<CGColorSpaceRef> QCocoaBackingStore::colorSpace() const
|
||||
{
|
||||
NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||
return QCFType<CGColorSpaceRef>::constructFromGet(view.window.colorSpace.CGColorSpace);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
QNSWindowBackingStore::QNSWindowBackingStore(QWindow *window)
|
||||
: QCocoaBackingStore(window)
|
||||
{
|
||||
}
|
||||
|
||||
QNSWindowBackingStore::~QNSWindowBackingStore()
|
||||
{
|
||||
}
|
||||
@ -175,11 +188,10 @@ void QNSWindowBackingStore::flush(QWindow *window, const QRegion ®ion, const
|
||||
Q_ASSERT_X(graphicsContext, "QCocoaBackingStore",
|
||||
"Focusing the view should give us a current graphics context");
|
||||
|
||||
// Prevent potentially costly color conversion by assigning the display color space
|
||||
// to the backingstore image. This does not copy the underlying image data.
|
||||
CGColorSpaceRef displayColorSpace = view.window.screen.colorSpace.CGColorSpace;
|
||||
// Tag backingstore image with color space based on the window.
|
||||
// Note: This does not copy the underlying image data.
|
||||
QCFType<CGImageRef> cgImage = CGImageCreateCopyWithColorSpace(
|
||||
QCFType<CGImageRef>(m_image.toCGImage()), displayColorSpace);
|
||||
QCFType<CGImageRef>(m_image.toCGImage()), colorSpace());
|
||||
|
||||
// Create temporary image to use for blitting, without copying image data
|
||||
NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:cgImage size:NSZeroSize] autorelease];
|
||||
@ -305,7 +317,7 @@ template<class R>
|
||||
constexpr backwards_t<R> backwards(R&& r) { return {std::forward<R>(r)}; }
|
||||
|
||||
QCALayerBackingStore::QCALayerBackingStore(QWindow *window)
|
||||
: QPlatformBackingStore(window)
|
||||
: QCocoaBackingStore(window)
|
||||
{
|
||||
qCDebug(lcQpaBackingStore) << "Creating QCALayerBackingStore for" << window;
|
||||
m_buffers.resize(1);
|
||||
@ -444,11 +456,7 @@ bool QCALayerBackingStore::recreateBackBufferIfNeeded()
|
||||
<< "based on requested" << m_requestedSize << "and dpr =" << devicePixelRatio;
|
||||
|
||||
static auto pixelFormat = QImage::toPixelFormat(QImage::Format_ARGB32_Premultiplied);
|
||||
|
||||
NSView *view = static_cast<QCocoaWindow *>(window()->handle())->view();
|
||||
auto colorSpace = QCFType<CGColorSpaceRef>::constructFromGet(view.window.screen.colorSpace.CGColorSpace);
|
||||
|
||||
m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace));
|
||||
m_buffers.back().reset(new GraphicsBuffer(requestedBufferSize, devicePixelRatio, pixelFormat, colorSpace()));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user