From 0a7eb034f402637e139072dc19579775a416e2a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 15 Aug 2017 17:33:25 +0200 Subject: macOS: Restore support for layered mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After 871966 we now do drawing as a result of drawRect calls, but layer backed mode was not taken into account. This restores support for both pull and push-mode drawing in layer-backed mode. Change-Id: I35039ee9eb4486206f9f92f8230df104473368c9 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoabackingstore.mm | 35 +++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'src/plugins/platforms/cocoa/qcocoabackingstore.mm') diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index b684435823..61f44e37d1 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -48,6 +48,7 @@ Q_LOGGING_CATEGORY(lcCocoaBackingStore, "qt.qpa.cocoa.backingstore"); QCocoaBackingStore::QCocoaBackingStore(QWindow *window) : QRasterBackingStore(window) + , m_cgImage(nullptr) { } @@ -69,6 +70,18 @@ QImage::Format QCocoaBackingStore::format() const return QRasterBackingStore::format(); } +void QCocoaBackingStore::beginPaint(const QRegion ®ion) +{ + m_cgImage = nullptr; + QRasterBackingStore::beginPaint(region); +} + +void QCocoaBackingStore::endPaint() +{ + QRasterBackingStore::endPaint(); + m_cgImage = m_image.toCGImage(); +} + #if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_12) static const NSCompositingOperation NSCompositingOperationCopy = NSCompositeCopy; static const NSCompositingOperation NSCompositingOperationSourceOver = NSCompositeSourceOver; @@ -107,6 +120,25 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo qCDebug(lcCocoaBackingStore) << "Flushing" << region << "of" << view << qPrintable(targetViewDescription); } + if (view.layer) { + // In layer-backed mode, locking focus on a view does not give the right + // view transformation, and doesn't give us a graphics context to render + // via when drawing outside of the display cycle. Instead we tell AppKit + // that we want to update the layer's content, via [NSView wantsUpdateLayer], + // which result in AppKit not creating a backingstore for each layer, and + // we then directly set the layer's backingstore (content) to our backingstore, + // masked to the part of the subview that is relevant. + // FIXME: Figure out if there's a way to do partial updates + view.layer.contents = (__bridge id)static_cast(m_cgImage); + if (view != topLevelView) { + view.layer.contentsRect = CGRectApplyAffineTransform( + [view convertRect:view.bounds toView:topLevelView], + // The contentsRect is in unit coordinate system + CGAffineTransformMakeScale(1.0 / m_image.width(), 1.0 / m_image.height())); + } + return; + } + // Normally a NSView is drawn via drawRect, as part of the display cycle in the // main runloop, via setNeedsDisplay and friends. AppKit will lock focus on each // individual view, starting with the top level and then traversing any subviews, @@ -156,8 +188,7 @@ void QCocoaBackingStore::flush(QWindow *window, const QRegion ®ion, const QPo "Focusing the view should give us a current graphics context"); // Create temporary image to use for blitting, without copying image data - NSImage *backingStoreImage = [[[NSImage alloc] - initWithCGImage:QCFType(m_image.toCGImage()) size:NSZeroSize] autorelease]; + NSImage *backingStoreImage = [[[NSImage alloc] initWithCGImage:m_cgImage size:NSZeroSize] autorelease]; if ([topLevelView hasMask]) { // FIXME: Implement via NSBezierPath and addClip -- cgit v1.2.3