summaryrefslogtreecommitdiffstats
path: root/src/quick3d/imports/scene3d/scene3drenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/quick3d/imports/scene3d/scene3drenderer.cpp')
-rw-r--r--src/quick3d/imports/scene3d/scene3drenderer.cpp58
1 files changed, 31 insertions, 27 deletions
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp
index b3cac0dcd..b96fc516d 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer.cpp
+++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp
@@ -138,11 +138,13 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
, m_lastMultisample(false)
, m_needsShutdown(true)
, m_blocking(false)
+ , m_forceRecreate(false)
{
Q_CHECK_PTR(m_item);
Q_CHECK_PTR(m_item->window());
m_window = m_item->window();
+ QObject::connect(m_item->window(), &QQuickWindow::afterSynchronizing, this, &Scene3DRenderer::synchronize, Qt::DirectConnection);
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
@@ -247,7 +249,30 @@ void Scene3DRenderer::onWindowChanged(QQuickWindow *w)
void Scene3DRenderer::synchronize()
{
- m_multisample = m_item->multisample();
+ if (m_item && m_window) {
+ m_multisample = m_item->multisample();
+
+ if (m_aspectEngine->rootEntity() != m_item->entity()) {
+ scheduleRootEntityChange();
+ }
+
+ const QSize boundingRectSize = m_item->boundingRect().size().toSize();
+ const QSize currentSize = boundingRectSize * m_window->effectiveDevicePixelRatio();
+ const bool sizeHasChanged = currentSize != m_lastSize;
+ const bool multisampleHasChanged = m_multisample != m_lastMultisample;
+ m_forceRecreate = sizeHasChanged || multisampleHasChanged;
+
+ if (sizeHasChanged) {
+ static const QMetaMethod setItemAreaAndDevicePixelRatio = setItemAreaAndDevicePixelRatioMethod();
+ setItemAreaAndDevicePixelRatio.invoke(m_item, Qt::QueuedConnection, Q_ARG(QSize, boundingRectSize),
+ Q_ARG(qreal, m_window->effectiveDevicePixelRatio()));
+ }
+
+ // Store the current size as a comparison
+ // point for the next frame
+ m_lastSize = currentSize;
+ m_lastMultisample = m_multisample;
+ }
}
void Scene3DRenderer::setSGNode(Scene3DSGNode *node)
@@ -261,51 +286,30 @@ void Scene3DRenderer::render()
{
QMutexLocker l(&m_windowMutex);
// Lock to ensure the window doesn't change while we are rendering
- if (!m_item || !m_window)
+ if (!m_window)
return;
- if (m_aspectEngine->rootEntity() != m_item->entity())
- scheduleRootEntityChange();
-
ContextSaver saver;
// The OpenGL state may be dirty from the previous QtQuick nodes, so reset
// it here to give Qt3D the clean state it expects
m_window->resetOpenGLState();
- const QSize boundingRectSize = m_item->boundingRect().size().toSize();
- 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;
-
- if (sizeHasChanged) {
- // 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, m_window->effectiveDevicePixelRatio()));
- }
-
// Rebuild FBO and textures if never created or a resize has occurred
- if ((m_multisampledFBO.isNull() || forceRecreate) && m_multisample) {
- m_multisampledFBO.reset(createMultisampledFramebufferObject(currentSize));
+ if ((m_multisampledFBO.isNull() || m_forceRecreate) && m_multisample) {
+ m_multisampledFBO.reset(createMultisampledFramebufferObject(m_lastSize));
if (m_multisampledFBO->format().samples() == 0 || !QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
m_multisample = false;
m_multisampledFBO.reset(nullptr);
}
}
- if (m_finalFBO.isNull() || forceRecreate) {
- m_finalFBO.reset(createFramebufferObject(currentSize));
+ if (m_finalFBO.isNull() || m_forceRecreate) {
+ m_finalFBO.reset(createFramebufferObject(m_lastSize));
m_texture.reset(m_window->createTextureFromId(m_finalFBO->texture(), m_finalFBO->size(), QQuickWindow::TextureHasAlphaChannel));
m_node->setTexture(m_texture.data());
}
- // Store the current size as a comparison
- // point for the next frame
- m_lastSize = currentSize;
- m_lastMultisample = m_multisample;
-
// Bind FBO
if (m_multisample) //Only try to use MSAA when available
m_multisampledFBO->bind();