From 33ac7e44459cf012ffdfd4092e7d8d55cc7b722b Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Wed, 30 Oct 2013 13:46:03 +0100 Subject: [PATCH] QmlProfiler: Make sure UI is properly rendered Do the QML based painting when requested inside the UI thread, and only copy the final canvas pixmap in the renderer thread (in paint()). To avoid excessive re-drawing delay the painting via a timer to the next event loop run. The previous logic was still from Qt Quick 1 times, where the paint() method was called in the GUI thread. This has changed in Qt Quick 2: Here the paint() method will be called (on Unix) in a separate renderer thread, making the drawRegion / onDrawRegion connections implicitly deferred. Change-Id: I298547013658e4cd1e94115305577bdb96cd0b2a Reviewed-by: Ulf Hermann Reviewed-by: Kai Koehne --- .../canvas/qdeclarativecontext2d.cpp | 3 -- .../qmlprofiler/canvas/qmlprofilercanvas.cpp | 39 ++++++++++++------- .../qmlprofiler/canvas/qmlprofilercanvas.h | 21 ++++------ 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d.cpp b/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d.cpp index be092b12ad7..f006657bfc7 100644 --- a/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d.cpp +++ b/src/plugins/qmlprofiler/canvas/qdeclarativecontext2d.cpp @@ -937,9 +937,6 @@ void Context2D::setupPainter() void Context2D::beginPainting() { - if (m_width <= 0 || m_height <=0) - return; - if (m_pixmap.width() != m_width || m_pixmap.height() != m_height) { if (m_painter.isActive()) m_painter.end(); diff --git a/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.cpp b/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.cpp index e0786808639..2927d8f27fc 100644 --- a/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.cpp +++ b/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.cpp @@ -39,36 +39,45 @@ namespace Internal { QmlProfilerCanvas::QmlProfilerCanvas() : m_context2d(new Context2D(this)) - , m_dirty(true) { setAcceptedMouseButtons(Qt::LeftButton); + m_drawTimer.setSingleShot(true); + connect(&m_drawTimer, SIGNAL(timeout()), this, SLOT(draw())); + + m_drawTimer.start(); } void QmlProfilerCanvas::requestPaint() { - update(); + if (m_context2d->size().width() != width() + || m_context2d->size().height() != height()) { + m_drawTimer.start(); + } else { + update(); + } } void QmlProfilerCanvas::requestRedraw() { - setDirty(true); + m_drawTimer.start(); +} + +// called from GUI thread. Draws into m_context2d. +void QmlProfilerCanvas::draw() +{ + QMutexLocker lock(&m_pixmapMutex); + m_context2d->reset(); + m_context2d->setSize(width(), height()); + + if (width() != 0 && height() != 0) + emit drawRegion(m_context2d, QRect(0, 0, width(), height())); update(); } +// called from OpenGL thread. Renders m_context2d into OpenGL buffer. void QmlProfilerCanvas::paint(QPainter *p) { - if (m_context2d->size().width() != width() || m_context2d->size().height() != height()) { - m_dirty = true; - m_context2d->setSize(width(), height()); - } - - if (m_dirty) { - m_context2d->reset(); - - emit drawRegion(m_context2d, QRect(0, 0, width(), height())); - setDirty(false); - } - + QMutexLocker lock(&m_pixmapMutex); p->drawPixmap(0, 0, m_context2d->pixmap()); } diff --git a/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.h b/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.h index f7837f2ed06..b320601396c 100644 --- a/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.h +++ b/src/plugins/qmlprofiler/canvas/qmlprofilercanvas.h @@ -31,6 +31,8 @@ #define QMLPROFILERCANVAS_H #include +#include +#include QT_BEGIN_NAMESPACE class Context2D; @@ -43,29 +45,19 @@ class QmlProfilerCanvas : public QQuickPaintedItem { Q_OBJECT - Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged) - public: QmlProfilerCanvas(); - bool dirty() const { return m_dirty; } - void setDirty(bool dirty) - { - if (m_dirty != dirty) { - m_dirty = dirty; - emit dirtyChanged(dirty); - } - } - signals: - void dirtyChanged(bool dirty); - void drawRegion(Context2D *ctxt, const QRect ®ion); public slots: void requestPaint(); void requestRedraw(); +private slots: + void draw(); + protected: virtual void paint(QPainter *); virtual void componentComplete(); @@ -73,7 +65,8 @@ protected: private: Context2D *m_context2d; - bool m_dirty; + QTimer m_drawTimer; + QMutex m_pixmapMutex; }; }