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.cpp70
1 files changed, 38 insertions, 32 deletions
diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp
index da63c32d8..bc75e0861 100644
--- a/src/quick3d/imports/scene3d/scene3drenderer.cpp
+++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp
@@ -165,7 +165,7 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp
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::beforeSynchronizing, this, &Scene3DRenderer::beforeSynchronize, 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
@@ -266,7 +266,8 @@ void Scene3DRenderer::onWindowChanged(QQuickWindow *w)
}
}
-void Scene3DRenderer::synchronize()
+// Render Thread, GUI locked
+void Scene3DRenderer::beforeSynchronize()
{
if (m_item && m_window) {
@@ -274,20 +275,19 @@ void Scene3DRenderer::synchronize()
// We could otherwise enter a deadlock state
if (!m_allowRendering.tryAcquire(std::max(m_allowRendering.available(), 1)))
return;
-
m_shouldRender = true;
+ // Check size / multisampling
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;
+ const bool forceRecreate = sizeHasChanged || multisampleHasChanged;
+ // Store the current size as a comparison
+ // point for the next frame
+ m_lastSize = currentSize;
+ m_lastMultisample = m_multisample;
if (sizeHasChanged) {
static const QMetaMethod setItemAreaAndDevicePixelRatio = setItemAreaAndDevicePixelRatioMethod();
@@ -295,13 +295,37 @@ void Scene3DRenderer::synchronize()
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;
+ // Rebuild FBO if size/multisampling has changed
+ const bool usesFBO = m_compositingMode == Scene3DItem::FBO;
+ if (usesFBO) {
+ // Rebuild FBO and textures if never created or a resize has occurred
+ if ((m_multisampledFBO.isNull() || forceRecreate) && m_multisample) {
+ m_multisampledFBO.reset(createMultisampledFramebufferObject(m_lastSize));
+ if (m_multisampledFBO->format().samples() == 0 || !QOpenGLFramebufferObject::hasOpenGLFramebufferBlit()) {
+ m_multisample = false;
+ m_multisampledFBO.reset(nullptr);
+ }
+ }
+
+ const bool generateNewTexture = m_finalFBO.isNull() || forceRecreate;
+ if (generateNewTexture) {
+ m_finalFBO.reset(createFramebufferObject(m_lastSize));
+ m_texture.reset(m_window->createTextureFromId(m_finalFBO->texture(), m_finalFBO->size(), QQuickWindow::TextureHasAlphaChannel));
+ }
+
+ // Set texture on node
+ if (m_node && (!m_node->texture() || generateNewTexture))
+ m_node->setTexture(m_texture.data());
+ }
+
+ if (m_aspectEngine->rootEntity() != m_item->entity()) {
+ scheduleRootEntityChange();
+ }
+ // Mark SGNodes as dirty so that QQuick will trigger some rendering
if (m_node)
m_node->markDirty(QSGNode::DirtyMaterial);
+
m_item->update();
}
}
@@ -321,13 +345,13 @@ void Scene3DRenderer::setSGNode(Scene3DSGNode *node)
m_node = node;
}
+// Render Thread, Main Thread is unlocked at this point
void Scene3DRenderer::render()
{
QMutexLocker l(&m_windowMutex);
// Lock to ensure the window doesn't change while we are rendering
if (!m_window || !m_shouldRender)
return;
-
m_shouldRender = false;
ContextSaver saver;
@@ -339,24 +363,6 @@ void Scene3DRenderer::render()
// Create and bind FBO if using the FBO compositing mode
const bool usesFBO = m_compositingMode == Scene3DItem::FBO;
if (usesFBO) {
- // Rebuild FBO and textures if never created or a resize has occurred
- 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() || 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());
- }
-
-
- m_forceRecreate = false;
-
// Bind FBO
if (m_multisample) //Only try to use MSAA when available
m_multisampledFBO->bind();