summaryrefslogtreecommitdiffstats
path: root/src/quick3d/imports/scene3d/scene3drenderer.cpp
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2018-01-18 10:58:43 +0100
committerLiang Qi <liang.qi@qt.io>2018-01-18 10:58:43 +0100
commit3c7562963625f4baaa6d692ad51df46171bbd7ed (patch)
treeb5710d4ad4456a187c179c004caa9d1a8a2b92a7 /src/quick3d/imports/scene3d/scene3drenderer.cpp
parent907869e8f87bab55671bfabf29f773cc01f40b68 (diff)
parent02d01a68971747f01a270226f6474190736939cf (diff)
Merge remote-tracking branch 'origin/5.9.4' into 5.9
Diffstat (limited to 'src/quick3d/imports/scene3d/scene3drenderer.cpp')
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer.cpp26
1 files changed, 17 insertions, 9 deletions
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp
index f95839e1b..1c9fec4d2 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer.cpp
+++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp
@@ -131,6 +131,7 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
, m_texture(nullptr)
, m_node(nullptr)
, m_cleaner(nullptr)
+ , m_window(nullptr)
, m_multisample(false) // this value is not used, will be synced from the Scene3DItem instead
, m_lastMultisample(false)
, m_needsShutdown(true)
@@ -139,9 +140,16 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
Q_CHECK_PTR(m_item);
Q_CHECK_PTR(m_item->window());
+ m_window = m_item->window();
QObject::connect(m_item->window(), &QQuickWindow::beforeRendering, this, &Scene3DRenderer::render, Qt::DirectConnection);
QObject::connect(m_item->window(), &QQuickWindow::sceneGraphInvalidated, this, &Scene3DRenderer::onSceneGraphInvalidated, Qt::DirectConnection);
+ // So that we can schedule the cleanup
QObject::connect(m_item, &QQuickItem::windowChanged, this, &Scene3DRenderer::onWindowChanged, Qt::QueuedConnection);
+ // Main thread -> updates the rendering window
+ QObject::connect(m_item, &QQuickItem::windowChanged, [this] (QQuickWindow *w) {
+ QMutexLocker l(&m_windowMutex);
+ m_window = w;
+ });
Q_ASSERT(QOpenGLContext::currentContext());
ContextSaver saver;
@@ -249,11 +257,11 @@ void Scene3DRenderer::setSGNode(Scene3DSGNode *node)
void Scene3DRenderer::render()
{
- if (!m_item || !m_item->window())
+ QMutexLocker l(&m_windowMutex);
+ // Lock to ensure the window doesn't change while we are rendering
+ if (!m_item || !m_window)
return;
- QQuickWindow *window = m_item->window();
-
if (m_aspectEngine->rootEntity() != m_item->entity())
scheduleRootEntityChange();
@@ -261,10 +269,10 @@ void Scene3DRenderer::render()
// The OpenGL state may be dirty from the previous QtQuick nodes, so reset
// it here to give Qt3D the clean state it expects
- window->resetOpenGLState();
+ m_window->resetOpenGLState();
const QSize boundingRectSize = m_item->boundingRect().size().toSize();
- const QSize currentSize = boundingRectSize * window->effectiveDevicePixelRatio();
+ const QSize currentSize = boundingRectSize * m_window->effectiveDevicePixelRatio();
const bool sizeHasChanged = currentSize != m_lastSize;
const bool multisampleHasChanged = m_multisample != m_lastMultisample;
const bool forceRecreate = sizeHasChanged || multisampleHasChanged;
@@ -273,7 +281,7 @@ void Scene3DRenderer::render()
// We are in the QSGRenderThread (doing a direct call would result in a race)
static const QMetaMethod setItemAreaAndDevicePixelRatio = setItemAreaAndDevicePixelRatioMethod();
setItemAreaAndDevicePixelRatio.invoke(m_item, Qt::QueuedConnection, Q_ARG(QSize, boundingRectSize),
- Q_ARG(qreal, window->effectiveDevicePixelRatio()));
+ Q_ARG(qreal, m_window->effectiveDevicePixelRatio()));
}
// Rebuild FBO and textures if never created or a resize has occurred
@@ -287,7 +295,7 @@ void Scene3DRenderer::render()
if (m_finalFBO.isNull() || forceRecreate) {
m_finalFBO.reset(createFramebufferObject(currentSize));
- m_texture.reset(window->createTextureFromId(m_finalFBO->texture(), m_finalFBO->size(), QQuickWindow::TextureHasAlphaChannel));
+ m_texture.reset(m_window->createTextureFromId(m_finalFBO->texture(), m_finalFBO->size(), QQuickWindow::TextureHasAlphaChannel));
m_node->setTexture(m_texture.data());
}
@@ -327,13 +335,13 @@ void Scene3DRenderer::render()
// Reset the state used by the Qt Quick scenegraph to avoid any
// interference when rendering the rest of the UI.
- window->resetOpenGLState();
+ m_window->resetOpenGLState();
// Mark material as dirty to request a new frame
m_node->markDirty(QSGNode::DirtyMaterial);
// Request next frame
- window->update();
+ m_window->update();
}
} // namespace Qt3DRender