diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-04-04 11:34:33 +0200 |
---|---|---|
committer | Laszlo Agocs <laszlo.agocs@qt.io> | 2017-04-05 09:06:07 +0000 |
commit | 01e15dd236b23395139fed61686ea4b98da4ea7d (patch) | |
tree | ae56ed7b902c5ec70039f1cd43600ecadf9488a8 | |
parent | efcaf4dc9e46f1ab8d6426a8c31b0a11dfbed94e (diff) |
Hook Scene3D cleanup on scenegraphInvalidated too
The invalidated signal is nice since it works in all cases, both with
real QQuickWindows and ones driven via QQuickRenderControl (e.g. QQuickWidget).
With QQuickWidget just relying on windowChanged is pretty bad since the
window change comes way too late due to the diffeerences in widget
handling internals.
Task-number: QTBUG-52132
Change-Id: I8639e4d60514eeeb00fa9dda2329de6088f2a44d
Reviewed-by: Andy Nichols <andy.nichols@qt.io>
-rw-r--r-- | src/quick3d/imports/scene3d/scene3drenderer.cpp | 30 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3drenderer_p.h | 4 |
2 files changed, 24 insertions, 10 deletions
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp index f52a071eb..88f3be3c1 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer.cpp +++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp @@ -122,12 +122,14 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp , m_cleaner(nullptr) , m_multisample(false) // this value is not used, will be synced from the Scene3DItem instead , m_lastMultisample(false) + , m_needsShutdown(true) { Q_CHECK_PTR(m_item); Q_CHECK_PTR(m_item->window()); QObject::connect(m_item->window(), &QQuickWindow::beforeRendering, this, &Scene3DRenderer::render, Qt::DirectConnection); - QObject::connect(m_item, &QQuickItem::windowChanged, this, &Scene3DRenderer::onWindowChangedQueued, Qt::QueuedConnection); + QObject::connect(m_item->window(), &QQuickWindow::sceneGraphInvalidated, this, &Scene3DRenderer::onSceneGraphInvalidated, Qt::DirectConnection); + QObject::connect(m_item, &QQuickItem::windowChanged, this, &Scene3DRenderer::onWindowChanged, Qt::QueuedConnection); Q_ASSERT(QOpenGLContext::currentContext()); ContextSaver saver; @@ -173,7 +175,7 @@ void Scene3DRenderer::setCleanerHelper(Scene3DCleaner *cleaner) } } -// Executed in the QtQuick render thread. +// Executed in the QtQuick render thread (which may even be the gui/main with QQuickWidget / RenderControl). void Scene3DRenderer::shutdown() { qCDebug(Scene3D) << Q_FUNC_INFO << QThread::currentThread(); @@ -195,19 +197,29 @@ void Scene3DRenderer::shutdown() static_cast<QRenderAspectPrivate*>(QRenderAspectPrivate::get(m_renderAspect))->renderShutdown(); } -// SGThread -void Scene3DRenderer::onWindowChangedQueued(QQuickWindow *w) +// QtQuick render thread (which may also be the gui/main thread with QQuickWidget / RenderControl) +void Scene3DRenderer::onSceneGraphInvalidated() { - if (w == nullptr) { - qCDebug(Scene3D) << Q_FUNC_INFO << QThread::currentThread(); + qCDebug(Scene3D) << Q_FUNC_INFO << QThread::currentThread(); + if (m_needsShutdown) { + m_needsShutdown = false; shutdown(); - // Will only trigger something with the Loader case - // The window closed cases is handled by the window's destroyed - // signal QMetaObject::invokeMethod(m_cleaner, "cleanup"); } } +void Scene3DRenderer::onWindowChanged(QQuickWindow *w) +{ + qCDebug(Scene3D) << Q_FUNC_INFO << QThread::currentThread() << w; + if (!w) { + if (m_needsShutdown) { + m_needsShutdown = false; + shutdown(); + QMetaObject::invokeMethod(m_cleaner, "cleanup"); + } + } +} + void Scene3DRenderer::synchronize() { m_multisample = m_item->multisample(); diff --git a/src/quick3d/imports/scene3d/scene3drenderer_p.h b/src/quick3d/imports/scene3d/scene3drenderer_p.h index f28501f31..ab1db1010 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer_p.h +++ b/src/quick3d/imports/scene3d/scene3drenderer_p.h @@ -90,7 +90,8 @@ public: public Q_SLOTS: void render(); void shutdown(); - void onWindowChangedQueued(QQuickWindow *w); + void onSceneGraphInvalidated(); + void onWindowChanged(QQuickWindow *w); private: Scene3DItem *m_item; // Will be released by the QQuickWindow/QML Engine @@ -104,6 +105,7 @@ private: QSize m_lastSize; bool m_multisample; bool m_lastMultisample; + bool m_needsShutdown; friend class Scene3DCleaner; }; |