Cocoa: Fix backing store performance regression.
Commit 916dfcb8
introduced a regression where QNSView
would hold a copy if the backing store QImage, which
would cause a detach and deep copy if/when the image
was painted on while the copy was held.
Revert back to the previous share-by-pointer scheme.
Make sure the following bugs stays fixed:
QTBUG-38377
QTBUG-42206
QTBUG-44313
Change-Id: Ib8049051d51947113f23b66ee61dc34c22388914
Task-number: QTBUG-46959
Reviewed-by: Gabriel de Dietrich <gabriel.dedietrich@theqtcompany.com>
This commit is contained in:
parent
dbb1e1936c
commit
53ecaade10
@ -44,6 +44,8 @@ QCocoaBackingStore::QCocoaBackingStore(QWindow *window)
|
||||
|
||||
QCocoaBackingStore::~QCocoaBackingStore()
|
||||
{
|
||||
if (QCocoaWindow *cocoaWindow = static_cast<QCocoaWindow *>(window()->handle()))
|
||||
[cocoaWindow->m_qtView clearBackingStore:this];
|
||||
}
|
||||
|
||||
QPaintDevice *QCocoaBackingStore::paintDevice()
|
||||
|
@ -51,8 +51,7 @@ QT_END_NAMESPACE
|
||||
Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
|
||||
|
||||
@interface QT_MANGLE_NAMESPACE(QNSView) : NSView <NSTextInputClient> {
|
||||
QImage m_backingStore;
|
||||
qreal m_pixelRatio;
|
||||
QCocoaBackingStore* m_backingStore;
|
||||
QPoint m_backingStoreOffset;
|
||||
CGImageRef m_maskImage;
|
||||
uchar *m_maskData;
|
||||
@ -86,6 +85,7 @@ Q_FORWARD_DECLARE_OBJC_CLASS(QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper));
|
||||
- (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;
|
||||
|
@ -135,7 +135,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
||||
{
|
||||
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;
|
||||
@ -371,7 +371,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
|
||||
if (!m_platformWindow->m_inSetGeometry)
|
||||
QWindowSystemInterface::flushWindowSystemEvents();
|
||||
else
|
||||
m_backingStore = QImage();
|
||||
m_backingStore = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,12 +476,16 @@ QT_WARNING_POP
|
||||
|
||||
- (void) flushBackingStore:(QCocoaBackingStore *)backingStore region:(const QRegion &)region offset:(QPoint)offset
|
||||
{
|
||||
m_backingStore = backingStore->toImage();
|
||||
m_pixelRatio = backingStore->getBackingStoreDevicePixelRatio();
|
||||
m_backingStoreOffset = offset * m_pixelRatio;
|
||||
foreach (QRect rect, region.rects()) {
|
||||
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
|
||||
@ -544,7 +548,7 @@ QT_WARNING_POP
|
||||
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:
|
||||
@ -552,10 +556,11 @@ QT_WARNING_POP
|
||||
|
||||
// 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];
|
||||
@ -581,7 +586,7 @@ QT_WARNING_POP
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user