From 93553bc31df1ed70cf587e43b8fa31e442fb8249 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Sat, 27 Aug 2011 13:22:13 +0200 Subject: [PATCH] implement non-threaded renderer again MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Change-Id: I17983667374d0ee7cf2a4a8907680671cef661d5 Reviewed-on: http://codereview.qt.nokia.com/3701 Reviewed-by: Qt Sanity Bot Reviewed-by: Samuel Rødal --- src/declarative/items/qsgcanvas.cpp | 84 ++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index bc642e4..052b439 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -66,9 +66,89 @@ QT_BEGIN_NAMESPACE DEFINE_BOOL_CONFIG_OPTION(qmlFixedAnimationStep, QML_FIXED_ANIMATION_STEP) +DEFINE_BOOL_CONFIG_OPTION(qmlNoThreadedRenderer, QML_BAD_GUI_RENDER_LOOP) extern Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha); +class QSGCanvasPlainRenderLoop : public QObject, public QSGCanvasRenderLoop +{ +public: + QSGCanvasPlainRenderLoop() + : updatePending(false) + , animationRunning(false) + { + qWarning("QSGCanvas: using non-threaded render loop. Be very sure to not access scene graph " + "objects outside the QSGItem::updatePaintNode() call. Failing to do so will cause " + "your code to crash on other platforms!"); + } + + virtual void paint() { + if (animationRunning && animationDriver()) + animationDriver()->advance(); + syncSceneGraph(); + makeCurrent(); + glViewport(0, 0, size.width(), size.height()); + renderSceneGraph(size); + swapBuffers(); + updatePending = false; + + if (animationRunning) + maybeUpdate(); + } + + virtual QImage grab() { + return qt_gl_read_framebuffer(size, false, false); + } + + virtual void startRendering() { + if (!glContext()) { + createGLContext(); + makeCurrent(); + initializeSceneGraph(); + } else { + makeCurrent(); + } + maybeUpdate(); + } + + virtual void stopRendering() { } + + virtual void maybeUpdate() { + if (!updatePending) { + QApplication::postEvent(this, new QEvent(QEvent::User)); + updatePending = true; + } + } + + virtual void animationStarted() { + animationRunning = true; + maybeUpdate(); + } + + virtual void animationStopped() { + animationRunning = false; + } + + virtual bool isRunning() const { return glContext(); } // Event loop is always running... + virtual void resize(const QSize &s) { size = s; } + virtual void setWindowSize(const QSize &s) { size = s; } + + bool event(QEvent *e) { + if (e->type() == QEvent::User) { + paint(); + return true; + } + return QObject::event(e); + } + + QSize size; + + uint updatePending : 1; + uint animationRunning : 1; +}; + + + /* Focus behavior ============== @@ -372,7 +452,9 @@ void QSGCanvasPrivate::init(QSGCanvas *c) // has a canvas.. rootItem->setFocus(true); - thread = new QSGCanvasRenderThread; + thread = qmlNoThreadedRenderer() + ? static_cast(new QSGCanvasPlainRenderLoop()) + : static_cast(new QSGCanvasRenderThread()); thread->renderer = q; thread->d = this; -- 2.7.4