diff -u a/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.h b/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.h --- a/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.h 2015-05-29 22:30:38.000000000 +0200 +++ b/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.h 2015-08-06 19:13:13.000000000 +0200 @@ -58,7 +58,6 @@ private: QImage m_qImage; - CGImageRef m_cgImage; QSize m_requestedSize; }; diff -u a/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.mm --- a/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.mm 2015-05-29 22:30:38.000000000 +0200 +++ b/qtbase/src/plugins/platforms/cocoa/qcocoabackingstore.mm 2015-08-06 19:51:48.000000000 +0200 @@ -47,14 +47,13 @@ QCocoaBackingStore::QCocoaBackingStore(QWindow *window) : QPlatformBackingStore(window) - , m_cgImage(0) { } QCocoaBackingStore::~QCocoaBackingStore() { - CGImageRelease(m_cgImage); - m_cgImage = 0; + if (QCocoaWindow *cocoaWindow = static_cast(window()->handle())) + [cocoaWindow->m_qtView clearBackingStore:this]; } QPaintDevice *QCocoaBackingStore::paintDevice() @@ -66,9 +65,6 @@ // either due to a window resize or devicePixelRatio change. QSize effectiveBufferSize = m_requestedSize * windowDevicePixelRatio; if (m_qImage.size() != effectiveBufferSize) { - CGImageRelease(m_cgImage); - m_cgImage = 0; - QImage::Format format = (window()->format().hasAlpha() || cocoaWindow->m_drawContentBorderGradient) ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32; m_qImage = QImage(effectiveBufferSize, format); @@ -81,15 +77,6 @@ void QCocoaBackingStore::flush(QWindow *win, const QRegion ®ion, const QPoint &offset) { - // A flush means that qImage has changed. Since CGImages are seen as - // immutable, CoreImage fails to pick up this change for m_cgImage - // (since it usually cached), so we must recreate it. We await doing this - // until one of the views needs it, since, together with calling - // "setNeedsDisplayInRect" instead of "displayRect" we will, in most - // cases, get away with doing this once for every repaint. Also note that - // m_cgImage is only a reference to the data inside m_qImage, it is not a copy. - CGImageRelease(m_cgImage); - m_cgImage = 0; if (!m_qImage.isNull()) { if (QCocoaWindow *cocoaWindow = static_cast(win->handle())) [cocoaWindow->m_qtView flushBackingStore:this region:region offset:offset]; diff -r -u a/qtbase/src/plugins/platforms/cocoa/qnsview.h b/qtbase/src/plugins/platforms/cocoa/qnsview.h --- a/qtbase/src/plugins/platforms/cocoa/qnsview.h 2015-05-29 22:30:38.000000000 +0200 +++ b/qtbase/src/plugins/platforms/cocoa/qnsview.h 2015-08-06 19:50:54.000000000 +0200 @@ -51,8 +51,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper)); @interface QT_MANGLE_NAMESPACE(QNSView) : NSView { - QImage m_backingStore; - qreal m_pixelRatio; + QCocoaBackingStore* m_backingStore; QPoint m_backingStoreOffset; CGImageRef m_maskImage; uchar *m_maskData; @@ -82,6 +81,7 @@ - (void)setQCocoaGLContext:(QCocoaGLContext *)context; #endif - (void)flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset; +- (void)clearBackingStore:(QCocoaBackingStore *)backingStore; - (void)setMaskRegion:(const QRegion *)region; - (void)invalidateWindowShadowIfNeeded; - (void)drawRect:(NSRect)dirtyRect; diff -r -u a/qtbase/src/plugins/platforms/cocoa/qnsview.mm b/qtbase/src/plugins/platforms/cocoa/qnsview.mm --- a/qtbase/src/plugins/platforms/cocoa/qnsview.mm 2015-05-29 22:30:38.000000000 +0200 +++ b/qtbase/src/plugins/platforms/cocoa/qnsview.mm 2015-08-07 17:12:12.000000000 +0200 @@ -143,7 +143,7 @@ { self = [super initWithFrame : NSMakeRect(0,0, 300,300)]; if (self) { - m_pixelRatio = 1.; + m_backingStore = 0; m_maskImage = 0; m_shouldInvalidateWindowShadow = false; m_window = 0; @@ -367,7 +367,7 @@ if (!m_platformWindow->m_inSetGeometry) QWindowSystemInterface::flushWindowSystemEvents(); else - m_backingStore = QImage(); + m_backingStore = 0; } } @@ -472,14 +472,20 @@ - (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset { - m_backingStore = backingStore->toImage(); - m_pixelRatio = backingStore->getBackingStoreDevicePixelRatio(); - m_backingStoreOffset = offset * m_pixelRatio; + m_backingStore = backingStore; + m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio(); foreach (QRect rect, region.rects()) { [self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; } } +- (void)clearBackingStore:(QCocoaBackingStore *)backingStore +{ + if (backingStore == m_backingStore) { + m_backingStore = 0; + } +} + - (BOOL) hasMask { return m_maskImage != 0; @@ -538,7 +544,7 @@ if (m_platformWindow->m_drawContentBorderGradient) NSDrawWindowBackground(dirtyRect); - if (m_backingStore.isNull()) + if (!m_backingStore) return; // Calculate source and target rects. The target rect is the dirtyRect: @@ -546,10 +552,11 @@ // The backing store source rect will be larger on retina displays. // Scale dirtyRect by the device pixel ratio: - CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * m_pixelRatio, - dirtyRect.origin.y * m_pixelRatio, - dirtyRect.size.width * m_pixelRatio, - dirtyRect.size.height * m_pixelRatio); + const qreal devicePixelRatio = m_backingStore->getBackingStoreDevicePixelRatio(); + CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * devicePixelRatio, + dirtyRect.origin.y * devicePixelRatio, + dirtyRect.size.width * devicePixelRatio, + dirtyRect.size.height * devicePixelRatio); NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext]; CGContextRef cgContext = (CGContextRef) [nsGraphicsContext graphicsPort]; @@ -575,7 +582,7 @@ dirtyBackingRect.size.width, dirtyBackingRect.size.height ); - CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore); + CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore->toImage()); CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect); // Optimization: Copy frame buffer content instead of blending for