aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2011-09-30 14:26:56 +1000
committerQt by Nokia <qt-info@nokia.com>2011-09-30 10:37:05 +0200
commitf07805ff56f9a2236f22ed7614aa8c4fc0dfdb46 (patch)
tree2a9b6937cec6b97e9074aba0199c61ef54f27b17 /src
parentf32a83bfcf5a667a81fdd2020f119cdeec79a9f1 (diff)
Add a QSGCanvas incubation controller
Change-Id: I0324c32240746b013eeefaae2dfaa390d6e777e5 Task-number: QTBUG-21151 Reviewed-on: http://codereview.qt-project.org/5828 Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/declarative/items/qsgcanvas.cpp60
-rw-r--r--src/declarative/items/qsgcanvas.h3
-rw-r--r--src/declarative/items/qsgcanvas_p.h8
-rw-r--r--src/declarative/items/qsgview.cpp6
4 files changed, 76 insertions, 1 deletions
diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp
index cdef37ffa3..2ced204804 100644
--- a/src/declarative/items/qsgcanvas.cpp
+++ b/src/declarative/items/qsgcanvas.cpp
@@ -60,6 +60,7 @@
#include <QtGui/qmatrix4x4.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qabstractanimation.h>
+#include <QtDeclarative/qdeclarativeincubator.h>
#include <private/qdeclarativedebugtrace_p.h>
@@ -78,6 +79,45 @@ void QSGCanvasPrivate::updateFocusItemTransform()
qApp->inputPanel()->setInputItemTransform(QSGItemPrivate::get(focus)->itemToCanvasTransform());
}
+class QSGCanvasIncubationController : public QObject, public QDeclarativeIncubationController
+{
+public:
+ QSGCanvasIncubationController(QSGCanvasPrivate *canvas)
+ : m_canvas(canvas), m_eventSent(false) {}
+
+protected:
+ virtual bool event(QEvent *e)
+ {
+ if (e->type() == QEvent::User) {
+ Q_ASSERT(m_eventSent);
+
+ bool *amtp = m_canvas->thread->allowMainThreadProcessing();
+ while (incubatingObjectCount()) {
+ if (amtp)
+ incubateWhile(amtp);
+ else
+ incubateFor(5);
+ QCoreApplication::processEvents();
+ }
+
+ m_eventSent = false;
+ }
+ return QObject::event(e);
+ }
+
+ virtual void incubatingObjectCountChanged(int count)
+ {
+ if (count && !m_eventSent) {
+ m_eventSent = true;
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ }
+ }
+
+private:
+ QSGCanvasPrivate *m_canvas;
+ bool m_eventSent;
+};
+
class QSGCanvasPlainRenderLoop : public QObject, public QSGCanvasRenderLoop
{
public:
@@ -416,6 +456,7 @@ QSGCanvasPrivate::QSGCanvasPrivate()
, thread(0)
, animationDriver(0)
, renderTarget(0)
+ , incubationController(0)
{
}
@@ -792,6 +833,8 @@ QSGCanvas::~QSGCanvas()
QSGItemPrivate *rootItemPrivate = QSGItemPrivate::get(d->rootItem);
rootItemPrivate->removeFromDirtyList();
+ delete d->incubationController; d->incubationController = 0;
+
delete d->rootItem; d->rootItem = 0;
d->cleanupNodes();
}
@@ -1830,6 +1873,21 @@ QImage QSGCanvas::grabFrameBuffer()
return d->thread ? d->thread->grab() : QImage();
}
+/*!
+ Returns an incubation controller that splices incubation between frames
+ for this canvas. QSGView automatically installs this controller for you.
+
+ The controller is owned by the canvas and will be destroyed when the canvas
+ is deleted.
+*/
+QDeclarativeIncubationController *QSGCanvas::incubationController() const
+{
+ Q_D(const QSGCanvas);
+
+ if (!d->incubationController)
+ d->incubationController = new QSGCanvasIncubationController(const_cast<QSGCanvasPrivate *>(d));
+ return d->incubationController;
+}
void QSGCanvasRenderLoop::createGLContext()
@@ -1878,6 +1936,7 @@ void QSGCanvasRenderThread::run()
#ifdef THREAD_DEBUG
printf(" RenderThread: aquired sync lock...\n");
#endif
+ allowMainThreadProcessingFlag = false;
QCoreApplication::postEvent(this, new QEvent(QEvent::User));
#ifdef THREAD_DEBUG
printf(" RenderThread: going to sleep...\n");
@@ -1895,6 +1954,7 @@ void QSGCanvasRenderThread::run()
inSync = false;
// Wake GUI after sync to let it continue animating and event processing.
+ allowMainThreadProcessingFlag = true;
wake();
unlock();
#ifdef THREAD_DEBUG
diff --git a/src/declarative/items/qsgcanvas.h b/src/declarative/items/qsgcanvas.h
index a2bb278c0a..094fe40553 100644
--- a/src/declarative/items/qsgcanvas.h
+++ b/src/declarative/items/qsgcanvas.h
@@ -56,6 +56,7 @@ class QSGItem;
class QSGEngine;
class QSGCanvasPrivate;
class QOpenGLFramebufferObject;
+class QDeclarativeIncubationController;
class Q_DECLARATIVE_EXPORT QSGCanvas : public QWindow
{
@@ -85,6 +86,8 @@ public:
void setRenderTarget(QOpenGLFramebufferObject *fbo);
QOpenGLFramebufferObject *renderTarget() const;
+ QDeclarativeIncubationController *incubationController() const;
+
Q_SIGNALS:
void frameSwapped();
void sceneGraphInitialized();
diff --git a/src/declarative/items/qsgcanvas_p.h b/src/declarative/items/qsgcanvas_p.h
index 6a8e0a0ce0..4a53e6bb1b 100644
--- a/src/declarative/items/qsgcanvas_p.h
+++ b/src/declarative/items/qsgcanvas_p.h
@@ -84,6 +84,7 @@ class QSGCanvasPrivate;
class QTouchEvent;
class QSGCanvasRenderLoop;
+class QSGCanvasIncubationController;
class QSGCanvasPrivate : public QWindowPrivate
{
@@ -167,6 +168,8 @@ public:
QOpenGLFramebufferObject *renderTarget;
QHash<int, QSGItem *> itemForTouchPointId;
+
+ mutable QSGCanvasIncubationController *incubationController;
};
class QSGCanvasRenderLoop
@@ -196,6 +199,7 @@ public:
virtual void animationStarted() = 0;
virtual void animationStopped() = 0;
virtual void moveContextToThread(QSGContext *) { }
+ virtual bool *allowMainThreadProcessing() { return 0; }
protected:
void initializeSceneGraph() { d->initializeSceneGraph(); }
@@ -226,6 +230,7 @@ class QSGCanvasRenderThread : public QThread, public QSGCanvasRenderLoop
public:
QSGCanvasRenderThread()
: mutex(QMutex::NonRecursive)
+ , allowMainThreadProcessingFlag(true)
, animationRunning(false)
, isGuiBlocked(0)
, isPaintCompleted(false)
@@ -258,6 +263,7 @@ public:
void setWindowSize(const QSize &size) { windowSize = size; }
void maybeUpdate();
void moveContextToThread(QSGContext *c) { c->moveToThread(this); }
+ bool *allowMainThreadProcessing() { return &allowMainThreadProcessingFlag; }
bool event(QEvent *);
@@ -271,6 +277,8 @@ public:
QMutex mutex;
QWaitCondition condition;
+ bool allowMainThreadProcessingFlag;
+
QSize windowSize;
QSize renderedSize;
diff --git a/src/declarative/items/qsgview.cpp b/src/declarative/items/qsgview.cpp
index 236fd4ec1f..7d9a451e33 100644
--- a/src/declarative/items/qsgview.cpp
+++ b/src/declarative/items/qsgview.cpp
@@ -62,9 +62,13 @@ DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
void QSGViewPrivate::init()
{
+ Q_Q(QSGView);
+
QDeclarativeEnginePrivate::get(&engine)->sgContext = QSGCanvasPrivate::context;
- QDeclarativeInspectorService::instance()->addView(q_func());
+ engine.setIncubationController(q->incubationController());
+
+ QDeclarativeInspectorService::instance()->addView(q);
}
QSGViewPrivate::QSGViewPrivate()