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 <ulf.hermann@digia.com>
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
This commit is contained in:
Kai Koehne
2013-10-30 13:46:03 +01:00
parent 0d65cf11d0
commit 33ac7e4445
3 changed files with 31 additions and 32 deletions

View File

@@ -937,9 +937,6 @@ void Context2D::setupPainter()
void Context2D::beginPainting() void Context2D::beginPainting()
{ {
if (m_width <= 0 || m_height <=0)
return;
if (m_pixmap.width() != m_width || m_pixmap.height() != m_height) { if (m_pixmap.width() != m_width || m_pixmap.height() != m_height) {
if (m_painter.isActive()) if (m_painter.isActive())
m_painter.end(); m_painter.end();

View File

@@ -39,36 +39,45 @@ namespace Internal {
QmlProfilerCanvas::QmlProfilerCanvas() QmlProfilerCanvas::QmlProfilerCanvas()
: m_context2d(new Context2D(this)) : m_context2d(new Context2D(this))
, m_dirty(true)
{ {
setAcceptedMouseButtons(Qt::LeftButton); setAcceptedMouseButtons(Qt::LeftButton);
m_drawTimer.setSingleShot(true);
connect(&m_drawTimer, SIGNAL(timeout()), this, SLOT(draw()));
m_drawTimer.start();
} }
void QmlProfilerCanvas::requestPaint() void QmlProfilerCanvas::requestPaint()
{ {
update(); if (m_context2d->size().width() != width()
|| m_context2d->size().height() != height()) {
m_drawTimer.start();
} else {
update();
}
} }
void QmlProfilerCanvas::requestRedraw() 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(); update();
} }
// called from OpenGL thread. Renders m_context2d into OpenGL buffer.
void QmlProfilerCanvas::paint(QPainter *p) void QmlProfilerCanvas::paint(QPainter *p)
{ {
if (m_context2d->size().width() != width() || m_context2d->size().height() != height()) { QMutexLocker lock(&m_pixmapMutex);
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);
}
p->drawPixmap(0, 0, m_context2d->pixmap()); p->drawPixmap(0, 0, m_context2d->pixmap());
} }

View File

@@ -31,6 +31,8 @@
#define QMLPROFILERCANVAS_H #define QMLPROFILERCANVAS_H
#include <QQuickPaintedItem> #include <QQuickPaintedItem>
#include <QTimer>
#include <QMutex>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class Context2D; class Context2D;
@@ -43,29 +45,19 @@ class QmlProfilerCanvas : public QQuickPaintedItem
{ {
Q_OBJECT Q_OBJECT
Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged)
public: public:
QmlProfilerCanvas(); QmlProfilerCanvas();
bool dirty() const { return m_dirty; }
void setDirty(bool dirty)
{
if (m_dirty != dirty) {
m_dirty = dirty;
emit dirtyChanged(dirty);
}
}
signals: signals:
void dirtyChanged(bool dirty);
void drawRegion(Context2D *ctxt, const QRect &region); void drawRegion(Context2D *ctxt, const QRect &region);
public slots: public slots:
void requestPaint(); void requestPaint();
void requestRedraw(); void requestRedraw();
private slots:
void draw();
protected: protected:
virtual void paint(QPainter *); virtual void paint(QPainter *);
virtual void componentComplete(); virtual void componentComplete();
@@ -73,7 +65,8 @@ protected:
private: private:
Context2D *m_context2d; Context2D *m_context2d;
bool m_dirty; QTimer m_drawTimer;
QMutex m_pixmapMutex;
}; };
} }