diff options
author | Fabien Freling <fabien.freling@nokia.com> | 2011-01-25 14:23:34 (GMT) |
---|---|---|
committer | Fabien Freling <fabien.freling@nokia.com> | 2011-01-26 11:25:48 (GMT) |
commit | 26d25ab46900d84b44e451c2a0a986bfed94a3f4 (patch) | |
tree | bbc66fa6f2d1c4f0126663efbadbaddc1020b686 /src/gui/kernel/qcocoaview_mac.mm | |
parent | 85b8631c2f30947e3c8364c903a4f85abb8f11e2 (diff) | |
download | Qt-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.mm | 114 |
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 |