Created
August 15, 2019 15:15
-
-
Save torarnv/d9f1ebf1545b2ac68e5b51eea8f0f1b5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git i/src/plugins/platforms/cocoa/qcocoabackingstore.mm w/src/plugins/platforms/cocoa/qcocoabackingstore.mm | |
index af50aabe15..f9e2f792eb 100644 | |
--- i/src/plugins/platforms/cocoa/qcocoabackingstore.mm | |
+++ w/src/plugins/platforms/cocoa/qcocoabackingstore.mm | |
@@ -46,6 +46,13 @@ | |
#include <QuartzCore/CATransaction.h> | |
+#if !defined(QT_APPLE_NO_PRIVATE_APIS) | |
+extern "C" { | |
+CGContextRef CGIOSurfaceContextCreate(IOSurfaceRef, size_t, size_t, size_t, size_t, CGColorSpaceRef, CGBitmapInfo); | |
+CGImageRef CGIOSurfaceContextCreateImage(CGContextRef); | |
+} | |
+#endif | |
+ | |
QT_BEGIN_NAMESPACE | |
QCocoaBackingStore::QCocoaBackingStore(QWindow *window) | |
@@ -531,6 +538,26 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion, | |
qCInfo(lcQpaBackingStore) << "Flushing" << backBufferSurface | |
<< "to" << flushedView.layer << "of" << flushedView; | |
+#if !defined(QT_APPLE_NO_PRIVATE_APIS) | |
+ CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host; | |
+ size_t bitsPerComponent = 8; | |
+ size_t bitsPerPixel = 32; | |
+ QSize bufferSize = m_buffers.back()->size(); | |
+ QCFType<CGContextRef> context = CGIOSurfaceContextCreate(m_buffers.back()->surface(), | |
+ bufferSize.width(), bufferSize.height(), bitsPerComponent, bitsPerPixel, | |
+ colorSpace(), bitmapInfo); | |
+ | |
+ QCFType<CGImageRef> image = CGIOSurfaceContextCreateImage(context); | |
+ | |
+ if (flushedView != backingStoreView) { | |
+ auto rect = [flushedView convertRect:flushedView.bounds toView:backingStoreView]; | |
+ auto scale = flushedView.layer.contentsScale; | |
+ rect = CGRectApplyAffineTransform(rect, CGAffineTransformMakeScale(scale, scale)); | |
+ image = CGImageCreateWithImageInRect(image, rect); | |
+ } | |
+ | |
+ flushedView.layer.contents = (__bridge id)static_cast<CGImageRef>(image); | |
+#else | |
flushedView.layer.contents = backBufferSurface; | |
if (flushedView != backingStoreView) { | |
@@ -540,6 +567,7 @@ void QCALayerBackingStore::flush(QWindow *flushedWindow, const QRegion ®ion, | |
// The contentsRect is in unit coordinate system | |
CGAffineTransformMakeScale(1.0 / backingStoreSize.width, 1.0 / backingStoreSize.height)); | |
} | |
+#endif | |
// Since we may receive multiple flushes before a new frame is started, we do not | |
// swap any buffers just yet. Instead we check in the next beginPaint if the layer's | |
diff --git i/src/widgets/kernel/qwidget.cpp w/src/widgets/kernel/qwidget.cpp | |
index 574a490ec7..0682bca3c3 100644 | |
--- i/src/widgets/kernel/qwidget.cpp | |
+++ w/src/widgets/kernel/qwidget.cpp | |
@@ -5433,9 +5433,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP | |
} | |
sourced->context = 0; | |
- // Native widgets need to be marked dirty on screen so painting will be done in correct context | |
- // Same check as in the no effects case below. | |
- if (backingStore && !onScreen && !asRoot && (q->internalWinId() || !q->nativeParentWidget()->isWindow())) | |
+ if (backingStore) | |
backingStore->markDirtyOnScreen(rgn, q, offset); | |
return; | |
@@ -5554,8 +5552,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP | |
sendPaintEvent(toBePainted); | |
} | |
- // Native widgets need to be marked dirty on screen so painting will be done in correct context | |
- if (backingStore && !onScreen && !asRoot && (q->internalWinId() || (q->nativeParentWidget() && !q->nativeParentWidget()->isWindow()))) | |
+ if (backingStore) | |
backingStore->markDirtyOnScreen(toBePainted, q, offset); | |
//restore | |
diff --git i/src/widgets/kernel/qwidgetbackingstore.cpp w/src/widgets/kernel/qwidgetbackingstore.cpp | |
index 48fc73a867..00d963811e 100644 | |
--- i/src/widgets/kernel/qwidgetbackingstore.cpp | |
+++ w/src/widgets/kernel/qwidgetbackingstore.cpp | |
@@ -333,9 +333,6 @@ void QWidgetBackingStore::beginPaint(QRegion &toClean, QWidget *widget, QBacking | |
Q_UNUSED(widget); | |
Q_UNUSED(toCleanIsInTopLevelCoordinates); | |
- // Always flush repainted areas. | |
- dirtyOnScreen += toClean; | |
- | |
#ifdef QT_NO_PAINT_DEBUG | |
backingStore->beginPaint(toClean); | |
#else | |
@@ -714,8 +711,7 @@ void QWidgetBackingStore::markDirtyOnScreen(const QRegion ®ion, QWidget *widg | |
// Top-level. | |
if (widget == tlw) { | |
- if (!widget->testAttribute(Qt::WA_WState_InPaintEvent)) | |
- dirtyOnScreen += region; | |
+ dirtyOnScreen += region; | |
return; | |
} | |
@@ -723,8 +719,7 @@ void QWidgetBackingStore::markDirtyOnScreen(const QRegion ®ion, QWidget *widg | |
if (!hasPlatformWindow(widget) && !widget->isWindow()) { | |
QWidget *nativeParent = widget->nativeParentWidget(); // Alien widgets with the top-level as the native parent (common case). | |
if (nativeParent == tlw) { | |
- if (!widget->testAttribute(Qt::WA_WState_InPaintEvent)) | |
- dirtyOnScreen += region.translated(topLevelOffset); | |
+ dirtyOnScreen += region.translated(topLevelOffset); | |
return; | |
} | |
@@ -1175,11 +1170,6 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg | |
return; | |
} | |
- if (exposedWidget != tlw) | |
- markDirtyOnScreen(exposedRegion, exposedWidget, exposedWidget->mapTo(tlw, QPoint())); | |
- else | |
- markDirtyOnScreen(exposedRegion, exposedWidget, QPoint()); | |
- | |
if (syncAllowed()) | |
doSync(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment