summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel/qcocoaview_mac.mm
diff options
context:
space:
mode:
authorFabien Freling <fabien.freling@nokia.com>2011-01-25 14:23:34 (GMT)
committerFabien Freling <fabien.freling@nokia.com>2011-01-26 11:25:48 (GMT)
commit26d25ab46900d84b44e451c2a0a986bfed94a3f4 (patch)
treebbc66fa6f2d1c4f0126663efbadbaddc1020b686 /src/gui/kernel/qcocoaview_mac.mm
parent85b8631c2f30947e3c8364c903a4f85abb8f11e2 (diff)
downloadQt-26d25ab46900d84b44e451c2a0a986bfed94a3f4.zip
Qt-26d25ab46900d84b44e451c2a0a986bfed94a3f4.tar.gz
Qt-26d25ab46900d84b44e451c2a0a986bfed94a3f4.tar.bz2
Move the flushing to [view drawRect:rect]
Instead of flushing by grabbing the Core Graphics context, we do it directly in the drawRect: method. This approach allows us to call flush() many times and only proceed to flush when the system is ready. Reviewed-by: Richard Moe Gustavsen
Diffstat (limited to 'src/gui/kernel/qcocoaview_mac.mm')
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm114
1 files changed, 91 insertions, 23 deletions
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 6059946..e50c401 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -52,6 +52,8 @@
#include <private/qmultitouch_mac_p.h>
#include <private/qevent_p.h>
#include <private/qbackingstore_p.h>
+#include <private/qwindowsurface_raster_p.h>
+#include <private/qunifiedtoolbarsurface_mac_p.h>
#include <qscrollarea.h>
#include <qhash.h>
@@ -530,8 +532,86 @@ static int qCocoaViewCount = 0;
if (!qwidget)
return;
+ // Getting context.
+ CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+ qt_mac_retain_graphics_context(context);
+
// We use a different graphics system.
- if (QApplicationPrivate::graphicsSystem() != 0 && !qwidgetprivate->isInUnifiedToolbar) {
+ if (QApplicationPrivate::graphicsSystem() != 0) {
+
+ // Raster engine.
+ if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) {
+
+ if (!qwidgetprivate->isInUnifiedToolbar) {
+
+ // Qt handles the painting occuring inside the window.
+ // Cocoa also keeps track of all widgets as NSView and therefore might
+ // ask for a repainting of a widget even if Qt is already taking care of it.
+ //
+ // The only valid reason for Cocoa to call drawRect: is for window manipulation
+ // (ie. resize, ...).
+ //
+ // Qt will then forward the update to the children.
+ if (!qwidget->isWindow()) {
+ qt_mac_release_graphics_context(context);
+ return;
+ }
+
+ QRasterWindowSurface *winSurface = dynamic_cast<QRasterWindowSurface *>(qwidget->windowSurface());
+ if (!winSurface || !winSurface->needsFlush) {
+ qt_mac_release_graphics_context(context);
+ return;
+ }
+
+ // Clip to region.
+ const QVector<QRect> &rects = winSurface->regionToFlush.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ const QRect &rect = rects.at(i);
+ CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()));
+ }
+ CGContextClip(context);
+
+ QRect r = winSurface->regionToFlush.boundingRect();
+ const CGRect area = CGRectMake(r.x(), r.y(), r.width(), r.height());
+
+ qt_mac_draw_image(context, winSurface->imageContext(), area, area);
+
+ winSurface->needsFlush = false;
+ winSurface->regionToFlush = QRegion();
+
+ } else {
+
+ QUnifiedToolbarSurface *unifiedSurface = dynamic_cast<QUnifiedToolbarSurface *>(qwidgetprivate->unifiedSurface);
+ if (!unifiedSurface || !qwidgetprivate->flushRequested) {
+ qt_mac_release_graphics_context(context);
+ return;
+ }
+
+ // We render the content of the toolbar in the surface.
+ unifiedSurface->updateToolbarOffset(qwidget);
+ QRect beginPaintRect(qwidgetprivate->toolbar_offset.x(), qwidgetprivate->toolbar_offset.y(), qwidget->geometry().width(), qwidget->geometry().height());
+ QRegion beginPaintRegion(beginPaintRect);
+
+ unifiedSurface->beginPaint(beginPaintRegion);
+ qwidget->render(unifiedSurface->paintDevice(), qwidgetprivate->toolbar_offset, QRegion(), QWidget::DrawChildren);
+
+ int areaX = qwidgetprivate->toolbar_offset.x();
+ int areaY = qwidgetprivate->toolbar_offset.y();
+ int areaWidth = qwidget->geometry().width();
+ int areaHeight = qwidget->geometry().height();
+ const CGRect area = CGRectMake(areaX, areaY, areaWidth, areaHeight);
+ const CGRect drawingArea = CGRectMake(0, 0, areaWidth, areaHeight);
+
+ qt_mac_draw_image(context, unifiedSurface->imageContext(), area, drawingArea);
+
+ qwidgetprivate->flushRequested = false;
+
+ }
+
+ CGContextFlush(context);
+ qt_mac_release_graphics_context(context);
+ return;
+ }
// Qt handles the painting occuring inside the window.
// Cocoa also keeps track of all widgets as NSView and therefore might
@@ -553,19 +633,8 @@ static int qCocoaViewCount = 0;
return;
}
- CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
- CGContextRetain(cg);
- qwidgetprivate->hd = cg;
-
- // We steal the CGContext for flushing in the unified toolbar with the raster engine.
- if (QApplicationPrivate::graphicsSystem() != 0 && qwidgetprivate->isInUnifiedToolbar) {
- qwidgetprivate->cgContext = cg;
- qwidgetprivate->hasOwnContext = true;
- qwidgetprivate->unifiedSurface->flush(qwidget, qwidgetprivate->ut_rg, qwidgetprivate->ut_pt);
- return;
- }
-
- CGContextSaveGState(cg);
+ // Native engine.
+ qwidgetprivate->hd = context;
if (qwidget->isVisible() && qwidget->updatesEnabled()) { //process the actual paint event.
if (qwidget->testAttribute(Qt::WA_WState_InPaintEvent))
@@ -600,18 +669,18 @@ static int qCocoaViewCount = 0;
engine->setSystemClip(qrgn);
if (qwidgetprivate->extra && qwidgetprivate->extra->hasMask) {
CGRect widgetRect = CGRectMake(0, 0, qwidget->width(), qwidget->height());
- CGContextTranslateCTM (cg, 0, widgetRect.size.height);
- CGContextScaleCTM(cg, 1, -1);
+ CGContextTranslateCTM (context, 0, widgetRect.size.height);
+ CGContextScaleCTM(context, 1, -1);
if (qwidget->isWindow())
- CGContextClearRect(cg, widgetRect);
- CGContextClipToMask(cg, widgetRect, qwidgetprivate->extra->imageMask);
- CGContextScaleCTM(cg, 1, -1);
- CGContextTranslateCTM (cg, 0, -widgetRect.size.height);
+ CGContextClearRect(context, widgetRect);
+ CGContextClipToMask(context, widgetRect, qwidgetprivate->extra->imageMask);
+ CGContextScaleCTM(context, 1, -1);
+ CGContextTranslateCTM (context, 0, -widgetRect.size.height);
}
if (qwidget->isWindow() && !qwidgetprivate->isOpaque
&& !qwidget->testAttribute(Qt::WA_MacBrushedMetal)) {
- CGContextClearRect(cg, NSRectToCGRect(aRect));
+ CGContextClearRect(context, NSRectToCGRect(aRect));
}
// Check for alien widgets, use qwidgetPrivate->drawWidget() to draw the widget if this
@@ -653,8 +722,7 @@ static int qCocoaViewCount = 0;
" widget outside of the PaintEvent");
}
qwidgetprivate->hd = 0;
- CGContextRestoreGState(cg);
- CGContextRelease(cg);
+ qt_mac_release_graphics_context(context);
}
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent