diff options
author | Timur Pocheptsov <Timur.Pocheptsov@digia.com> | 2014-10-28 11:41:34 +0100 |
---|---|---|
committer | Timur Pocheptsov <Timur.Pocheptsov@digia.com> | 2014-10-28 13:32:02 +0100 |
commit | 916dfcb8275bcce6b39606cd0b930239a60dc5df (patch) | |
tree | 1e079bf0eff8a42072f9727ec91cc4b4e83f7992 /src | |
parent | 148aa0e3e35f9bdf3e68fdf2c9cc509d2e093275 (diff) | |
download | qtbase-916dfcb8275bcce6b39606cd0b930239a60dc5df.tar.gz |
OS X - Cocoa backing store and drawRect
m_backingStore pointer has a limited 'lifetime' - usually
it is set in -flushBackingStore:region:offset: method, then -drawRect:
is invoked/forced by -setNeedsDisplayInRect:, after that it's dangerous to
have a non-null pointer to a backing store (and we reset it).
But if Cocoa invokes drawRect (due to some reason) our null backing store pointer is also
not good. This patch instead is using a shared resource (QImage) from a backing store.
This patch also makes getBackingStoreCGImage() redundant - -drawRect: was the only
place we called it.
Task-number: QTBUG-42206
Change-Id: Ie7726336f05d07c52f660f6326ae5cef114201dd
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.h | 5 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoabackingstore.mm | 13 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview.mm | 22 |
4 files changed, 13 insertions, 30 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.h b/src/plugins/platforms/cocoa/qcocoabackingstore.h index bfff5c3266..917f020132 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.h +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.h @@ -51,12 +51,9 @@ public: QPaintDevice *paintDevice(); void flush(QWindow *widget, const QRegion ®ion, const QPoint &offset); -#ifndef QT_NO_OPENGL - QImage toImage() const Q_DECL_OVERRIDE; -#endif + QImage toImage() const; void resize (const QSize &size, const QRegion &); bool scroll(const QRegion &area, int dx, int dy); - CGImageRef getBackingStoreCGImage(); qreal getBackingStoreDevicePixelRatio(); private: diff --git a/src/plugins/platforms/cocoa/qcocoabackingstore.mm b/src/plugins/platforms/cocoa/qcocoabackingstore.mm index e13e295511..ba1198c19c 100644 --- a/src/plugins/platforms/cocoa/qcocoabackingstore.mm +++ b/src/plugins/platforms/cocoa/qcocoabackingstore.mm @@ -96,12 +96,10 @@ void QCocoaBackingStore::flush(QWindow *win, const QRegion ®ion, const QPoint } } -#ifndef QT_NO_OPENGL QImage QCocoaBackingStore::toImage() const { return m_qImage; } -#endif void QCocoaBackingStore::resize(const QSize &size, const QRegion &) { @@ -121,17 +119,6 @@ bool QCocoaBackingStore::scroll(const QRegion &area, int dx, int dy) return true; } -CGImageRef QCocoaBackingStore::getBackingStoreCGImage() -{ - if (!m_cgImage) - m_cgImage = qt_mac_toCGImage(m_qImage); - - // Warning: do not retain/release/cache the returned image from - // outside the backingstore since it shares data with a QImage and - // needs special memory considerations. - return m_cgImage; -} - qreal QCocoaBackingStore::getBackingStoreDevicePixelRatio() { return m_qImage.devicePixelRatio(); diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h index 8b23f84a25..8d8df13dc3 100644 --- a/src/plugins/platforms/cocoa/qnsview.h +++ b/src/plugins/platforms/cocoa/qnsview.h @@ -51,7 +51,8 @@ QT_END_NAMESPACE Q_FORWARD_DECLARE_OBJC_CLASS(QNSViewMouseMoveHelper); @interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> { - QCocoaBackingStore* m_backingStore; + QImage m_backingStore; + qreal m_pixelRatio; QPoint m_backingStoreOffset; CGImageRef m_maskImage; uchar *m_maskData; diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 458e0ff924..1f1bc36bf2 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -143,7 +143,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; { self = [super initWithFrame : NSMakeRect(0,0, 300,300)]; if (self) { - m_backingStore = 0; + m_pixelRatio = 1.; m_maskImage = 0; m_shouldInvalidateWindowShadow = false; m_window = 0; @@ -466,8 +466,9 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; - (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset { - m_backingStore = backingStore; - m_backingStoreOffset = offset * m_backingStore->getBackingStoreDevicePixelRatio(); + m_backingStore = backingStore->toImage(); + m_pixelRatio = backingStore->getBackingStoreDevicePixelRatio(); + m_backingStoreOffset = offset * m_pixelRatio; foreach (QRect rect, region.rects()) { [self setNeedsDisplayInRect:NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height())]; } @@ -531,7 +532,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; if (m_platformWindow->m_drawContentBorderGradient) NSDrawWindowBackground(dirtyRect); - if (!m_backingStore) + if (m_backingStore.isNull()) return; // Calculate source and target rects. The target rect is the dirtyRect: @@ -539,11 +540,10 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; // The backing store source rect will be larger on retina displays. // Scale dirtyRect by the device pixel ratio: - 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); + CGRect dirtyBackingRect = CGRectMake(dirtyRect.origin.x * m_pixelRatio, + dirtyRect.origin.y * m_pixelRatio, + dirtyRect.size.width * m_pixelRatio, + dirtyRect.size.height * m_pixelRatio); NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext]; CGContextRef cgContext = (CGContextRef) [nsGraphicsContext graphicsPort]; @@ -569,7 +569,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; dirtyBackingRect.size.width, dirtyBackingRect.size.height ); - CGImageRef bsCGImage = m_backingStore->getBackingStoreCGImage(); + CGImageRef bsCGImage = qt_mac_toCGImage(m_backingStore); CGImageRef cleanImg = CGImageCreateWithImageInRect(bsCGImage, backingStoreRect); // Optimization: Copy frame buffer content instead of blending for @@ -586,8 +586,6 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; CGImageRelease(subMask); [self invalidateWindowShadowIfNeeded]; - - m_backingStore = 0; } - (BOOL) isFlipped |