Commit 33ac7e44 authored by Kai Koehne's avatar Kai Koehne

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: default avatarUlf Hermann <ulf.hermann@digia.com>
Reviewed-by: default avatarKai Koehne <kai.koehne@digia.com>
parent 0d65cf11
......@@ -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();
......
......@@ -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);
update();
m_drawTimer.start();
}
void QmlProfilerCanvas::paint(QPainter *p)
// called from GUI thread. Draws into m_context2d.
void QmlProfilerCanvas::draw()
{
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();
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()));
setDirty(false);
}
update();
}
// called from OpenGL thread. Renders m_context2d into OpenGL buffer.
void QmlProfilerCanvas::paint(QPainter *p)
{
QMutexLocker lock(&m_pixmapMutex);
p->drawPixmap(0, 0, m_context2d->pixmap());
}
......
......@@ -31,6 +31,8 @@
#define QMLPROFILERCANVAS_H
#include <QQuickPaintedItem>
#include <QTimer>
#include <QMutex>
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 &region);
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;
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment