aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-12-08 13:24:17 +0100
committerQt by Nokia <qt-info@nokia.com>2011-12-19 14:23:12 +0100
commit6efca58ab943bbd8c91c8f12ad47484677e2cf60 (patch)
treed1d5629d17451f36abaca975eed92d9132269e01 /src
parent8460eae44c241d5975b3041eedf6e08c9638fd41 (diff)
Implement "headless mode" for hidden QQuickCanvases
When all views are hidden, we stop the rendering thread, kill the OpenGL context and all scene graph content. The entire scenegraph is recreated based on the QML scene when a view is shown again. Change-Id: I734619d9f29263a5cdecbcc9b88c3808d1d64a7f Reviewed-by: Kim M. Kalland <kim.kalland@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquickcanvas.cpp51
-rw-r--r--src/quick/items/qquickwindowmanager.cpp18
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp7
3 files changed, 59 insertions, 17 deletions
diff --git a/src/quick/items/qquickcanvas.cpp b/src/quick/items/qquickcanvas.cpp
index 596db6c03e..0f281a3d1f 100644
--- a/src/quick/items/qquickcanvas.cpp
+++ b/src/quick/items/qquickcanvas.cpp
@@ -199,10 +199,22 @@ void QQuickCanvasPrivate::polishItems()
updateFocusItemTransform();
}
+void forceUpdate(QQuickItem *item)
+{
+ if (item->flags() & QQuickItem::ItemHasContents)
+ item->update();
+ QQuickItemPrivate::get(item)->dirty(QQuickItemPrivate::ChildrenUpdateMask);
+
+ QList <QQuickItem *> items = item->childItems();
+ for (int i=0; i<items.size(); ++i)
+ forceUpdate(items.at(i));
+}
void QQuickCanvasPrivate::syncSceneGraph()
{
if (!renderer) {
+ forceUpdate(rootItem);
+
QSGRootNode *rootNode = new QSGRootNode;
rootNode->appendChildNode(QQuickItemPrivate::get(rootItem)->itemNode());
renderer = context->createRenderer();
@@ -273,9 +285,9 @@ void QQuickCanvasPrivate::init(QQuickCanvas *c)
q->setSurfaceType(QWindow::OpenGLSurface);
q->setFormat(context->defaultSurfaceFormat());
- QObject::connect(context, SIGNAL(initialized()), q, SIGNAL(sceneGraphInitialized()));
- QObject::connect(context, SIGNAL(invalidated()), q, SIGNAL(sceneGraphInvalidated()));
- QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()));
+ QObject::connect(context, SIGNAL(initialized()), q, SIGNAL(sceneGraphInitialized()), Qt::DirectConnection);
+ QObject::connect(context, SIGNAL(invalidated()), q, SIGNAL(sceneGraphInvalidated()), Qt::DirectConnection);
+ QObject::connect(context, SIGNAL(invalidated()), q, SLOT(cleanupSceneGraph()), Qt::DirectConnection);
// ### TODO: remove QSGEngine
engine = new QSGEngine();
@@ -1686,11 +1698,42 @@ void QQuickCanvas::cleanupSceneGraph()
}
/*!
- \fn void QSGEngine::sceneGraphInitialized();
+ Returns the opengl context used for rendering.
+
+ If the scene graph is not ready, this function will return 0.
+
+ \sa sceneGraphInitialized(), sceneGraphInvalidated()
+ */
+
+QOpenGLContext *QQuickCanvas::openglContext() const
+{
+ Q_D(const QQuickCanvas);
+ if (d->context->isReady())
+ return d->context->glContext();
+ return 0;
+}
+
+
+/*!
+ \fn void QSGContext::sceneGraphInitialized()
This signal is emitted when the scene graph has been initialized.
This signal will be emitted from the scene graph rendering thread.
+
+ */
+
+
+/*!
+ \fn void QSGContext::sceneGraphInvalidated()
+
+ This signal is emitted when the scene graph has been invalidated.
+
+ This signal implies that the opengl rendering context used
+ has been invalidated and all user resources tied to that context
+ should be released.
+
+ This signal will be emitted from the scene graph rendering thread.
*/
/*!
diff --git a/src/quick/items/qquickwindowmanager.cpp b/src/quick/items/qquickwindowmanager.cpp
index 6c752943e7..ea17cae8f1 100644
--- a/src/quick/items/qquickwindowmanager.cpp
+++ b/src/quick/items/qquickwindowmanager.cpp
@@ -452,7 +452,7 @@ void QQuickRenderThreadSingleContextWindowManager::handleRemovedWindows()
while (m_removed_windows.size()) {
QQuickCanvas *canvas = m_removed_windows.takeLast();
#ifdef THREAD_DEBUG
- printf(" RenderThread: removing %p\n", canvas);
+ printf(" RenderThread: removing %p\n", canvas);
#endif
QQuickCanvasPrivate::get(canvas)->cleanupNodesOnShutdown();
@@ -527,8 +527,13 @@ void QQuickRenderThreadSingleContextWindowManager::run()
printf("QML Rendering Thread Started\n");
#endif
- if (!gl)
- initialize();
+ lock();
+ Q_ASSERT(!gl);
+ initialize();
+ // Wake GUI as it is waiting for the GL context to have appeared, as
+ // an indication that the render thread is now running.
+ wake();
+ unlock();
while (!shouldExit) {
lock();
@@ -895,10 +900,6 @@ void QQuickRenderThreadSingleContextWindowManager::paint(QQuickCanvas *canvas)
printf("GUI: paint called: %p\n", canvas);
#endif
- return;
-
-
-
lockInGui();
exhaustSyncEvent();
@@ -963,7 +964,10 @@ void QQuickRenderThreadSingleContextWindowManager::startRendering()
renderThreadAwakened = false;
inSync = false;
+ lockInGui();
start(); // Start the render thread...
+ wait();
+ unlockInGui();
// Animations will now be driven from the rendering thread.
if (animationTimer >= 0) {
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index a81571e5d8..5af7c76b16 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -87,9 +87,7 @@ class QSGContextPrivate : public QObjectPrivate
{
public:
QSGContextPrivate()
- : rootNode(0)
- , renderer(0)
- , gl(0)
+ : gl(0)
, distanceFieldCacheManager(0)
, flashMode(qmlFlashMode())
, distanceFieldDisabled(qmlDisableDistanceField())
@@ -101,9 +99,6 @@ public:
{
}
- QSGRootNode *rootNode;
- QSGRenderer *renderer;
-
QOpenGLContext *gl;
QHash<QSGMaterialType *, QSGMaterialShader *> materials;