diff options
Diffstat (limited to 'src/quick3d/imports/scene3d')
-rw-r--r-- | src/quick3d/imports/scene3d/qtquickscene3dplugin.cpp | 6 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dcleaner.cpp | 6 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dcleaner_p.h | 2 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3ditem.cpp | 45 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3ditem_p.h | 7 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dlogging.cpp | 2 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dlogging_p.h | 2 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3drenderer.cpp | 70 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3drenderer_p.h | 7 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dsgmaterial_p.h | 4 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp | 10 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h | 1 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dsgnode.cpp | 3 | ||||
-rw-r--r-- | src/quick3d/imports/scene3d/scene3dsgnode_p.h | 2 |
14 files changed, 113 insertions, 54 deletions
diff --git a/src/quick3d/imports/scene3d/qtquickscene3dplugin.cpp b/src/quick3d/imports/scene3d/qtquickscene3dplugin.cpp index 7103a1bb8..6b9ec96f8 100644 --- a/src/quick3d/imports/scene3d/qtquickscene3dplugin.cpp +++ b/src/quick3d/imports/scene3d/qtquickscene3dplugin.cpp @@ -37,9 +37,11 @@ ** ****************************************************************************/ -#include <QtQml> #include "qtquickscene3dplugin.h" -#include "scene3ditem_p.h" + +#include <QtQml> + +#include <scene3ditem_p.h> QT_BEGIN_NAMESPACE diff --git a/src/quick3d/imports/scene3d/scene3dcleaner.cpp b/src/quick3d/imports/scene3d/scene3dcleaner.cpp index 06b795c8a..ec371410d 100644 --- a/src/quick3d/imports/scene3d/scene3dcleaner.cpp +++ b/src/quick3d/imports/scene3d/scene3dcleaner.cpp @@ -38,13 +38,13 @@ ****************************************************************************/ #include "scene3dcleaner_p.h" -#include "scene3dlogging_p.h" -#include "scene3drenderer_p.h" #include <Qt3DCore/qaspectengine.h> - #include <QtCore/qthread.h> +#include <scene3dlogging_p.h> +#include <scene3drenderer_p.h> + QT_BEGIN_NAMESPACE namespace Qt3DRender { diff --git a/src/quick3d/imports/scene3d/scene3dcleaner_p.h b/src/quick3d/imports/scene3d/scene3dcleaner_p.h index 6ec2c7e6b..a246cbde7 100644 --- a/src/quick3d/imports/scene3d/scene3dcleaner_p.h +++ b/src/quick3d/imports/scene3d/scene3dcleaner_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include <QObject> +#include <QtCore/QObject> QT_BEGIN_NAMESPACE diff --git a/src/quick3d/imports/scene3d/scene3ditem.cpp b/src/quick3d/imports/scene3d/scene3ditem.cpp index 4a5c959c4..c31f4aa97 100644 --- a/src/quick3d/imports/scene3d/scene3ditem.cpp +++ b/src/quick3d/imports/scene3d/scene3ditem.cpp @@ -38,23 +38,26 @@ ****************************************************************************/ #include "scene3ditem_p.h" -#include "scene3dcleaner_p.h" -#include "scene3dlogging_p.h" -#include "scene3drenderer_p.h" -#include "scene3dsgnode_p.h" #include <Qt3DCore/QAspectEngine> #include <Qt3DCore/qentity.h> -#include <Qt3DRender/qcamera.h> -#include <Qt3DRender/QRenderAspect> -#include <Qt3DRender/qrendersurfaceselector.h> -#include <Qt3DRender/private/qrendersurfaceselector_p.h> #include <Qt3DInput/QInputAspect> #include <Qt3DInput/qinputsettings.h> #include <Qt3DLogic/qlogicaspect.h> +#include <Qt3DRender/QRenderAspect> +#include <Qt3DRender/qcamera.h> +#include <Qt3DRender/qrendersurfaceselector.h> - +#include <QtGui/qguiapplication.h> +#include <QtGui/qoffscreensurface.h> #include <QtQuick/qquickwindow.h> +#include <QtQuick/qquickrendercontrol.h> + +#include <Qt3DRender/private/qrendersurfaceselector_p.h> +#include <scene3dcleaner_p.h> +#include <scene3dlogging_p.h> +#include <scene3drenderer_p.h> +#include <scene3dsgnode_p.h> QT_BEGIN_NAMESPACE @@ -179,7 +182,7 @@ void Scene3DItem::applyRootEntityChange() QList<Qt3DRender::QCamera *> cameras = m_entity->findChildren<Qt3DRender::QCamera *>(); if (cameras.isEmpty()) { - qWarning() << "No camera found and automatic aspect ratio requested"; + qCDebug(Scene3D) << "No camera found and automatic aspect ratio requested"; } else { m_camera = cameras.first(); setCameraAspectModeHelper(); @@ -191,7 +194,7 @@ void Scene3DItem::applyRootEntityChange() if (inputSettings) { inputSettings->setEventSource(this); } else { - qWarning() << "No Input Settings found, keyboard and mouse events won't be handled"; + qCDebug(Scene3D) << "No Input Settings found, keyboard and mouse events won't be handled"; } } } @@ -202,11 +205,25 @@ void Scene3DItem::setWindowSurface(QObject *rootObject) // Set the item's window surface if it appears // the surface wasn't set on the surfaceSelector - if (surfaceSelector && !surfaceSelector->surface()) - surfaceSelector->setSurface(this->window()); + if (surfaceSelector && !surfaceSelector->surface()) { + // We may not have a real, exposed QQuickWindow when the Quick rendering + // is redirected via QQuickRenderControl (f.ex. QQuickWidget). + if (QWindow *rw = QQuickRenderControl::renderWindowFor(this->window())) { + // rw is the top-level window that is backed by a native window. Do + // not use that though since we must not clash with e.g. the widget + // backingstore compositor in the gui thread. + m_dummySurface = new QOffscreenSurface; + m_dummySurface->setParent(qGuiApp); // parent to something suitably long-living + m_dummySurface->setFormat(rw->format()); + m_dummySurface->create(); + surfaceSelector->setSurface(m_dummySurface); + } else { + surfaceSelector->setSurface(this->window()); + } + } } -void Scene3DItem::setItemArea(const QSize &area) +void Scene3DItem::setItemArea(QSize area) { Qt3DRender::QRenderSurfaceSelector *surfaceSelector = Qt3DRender::QRenderSurfaceSelectorPrivate::find(m_entity); if (surfaceSelector) diff --git a/src/quick3d/imports/scene3d/scene3ditem_p.h b/src/quick3d/imports/scene3d/scene3ditem_p.h index 09859a763..e0ce3addc 100644 --- a/src/quick3d/imports/scene3d/scene3ditem_p.h +++ b/src/quick3d/imports/scene3d/scene3ditem_p.h @@ -51,11 +51,13 @@ // We mean it. // -#include <QQuickItem> #include <QtCore/qpointer.h> +#include <QtQuick/QQuickItem> QT_BEGIN_NAMESPACE +class QOffscreenSurface; + namespace Qt3DCore { class QAspectEngine; class QEntity; @@ -86,7 +88,7 @@ public: bool multisample() const; void setMultisample(bool enable); - void setItemArea(const QSize &area); + Q_INVOKABLE void setItemArea(QSize area); bool isHoverEnabled() const; enum CameraAspectRatioMode { @@ -131,6 +133,7 @@ private: QPointer<Qt3DRender::QCamera> m_camera; CameraAspectRatioMode m_cameraAspectRatioMode; + QOffscreenSurface *m_dummySurface; }; } // Qt3DRender diff --git a/src/quick3d/imports/scene3d/scene3dlogging.cpp b/src/quick3d/imports/scene3d/scene3dlogging.cpp index b9582799b..b6656541b 100644 --- a/src/quick3d/imports/scene3d/scene3dlogging.cpp +++ b/src/quick3d/imports/scene3d/scene3dlogging.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE namespace Qt3DRender { -Q_LOGGING_CATEGORY(Scene3D, "Qt3D.Scene3D") +Q_LOGGING_CATEGORY(Scene3D, "Qt3D.Scene3D", QtWarningMsg) } // Qt3DRender diff --git a/src/quick3d/imports/scene3d/scene3dlogging_p.h b/src/quick3d/imports/scene3d/scene3dlogging_p.h index 0f9448d42..91430939f 100644 --- a/src/quick3d/imports/scene3d/scene3dlogging_p.h +++ b/src/quick3d/imports/scene3d/scene3dlogging_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include <QLoggingCategory> +#include <QtCore/QLoggingCategory> QT_BEGIN_NAMESPACE diff --git a/src/quick3d/imports/scene3d/scene3drenderer.cpp b/src/quick3d/imports/scene3d/scene3drenderer.cpp index 3065b19ac..b32191391 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer.cpp +++ b/src/quick3d/imports/scene3d/scene3drenderer.cpp @@ -38,27 +38,36 @@ ****************************************************************************/ #include "scene3drenderer_p.h" -#include "scene3dcleaner_p.h" -#include "scene3ditem_p.h" -#include "scene3dlogging_p.h" -#include "scene3dsgnode_p.h" -#include <Qt3DRender/qrenderaspect.h> -#include <Qt3DRender/private/qrenderaspect_p.h> #include <Qt3DCore/qaspectengine.h> -#include <Qt3DCore/private/qaspectengine_p.h> - -#include <QtQuick/qquickwindow.h> - +#include <Qt3DRender/qrenderaspect.h> +#include <QtCore/qthread.h> #include <QtGui/qopenglcontext.h> #include <QtGui/qopenglframebufferobject.h> +#include <QtQuick/qquickwindow.h> -#include <QtCore/qthread.h> +#include <Qt3DRender/private/qrenderaspect_p.h> +#include <Qt3DCore/private/qaspectengine_p.h> +#include <scene3dcleaner_p.h> +#include <scene3ditem_p.h> +#include <scene3dlogging_p.h> +#include <scene3dsgnode_p.h> QT_BEGIN_NAMESPACE namespace Qt3DRender { +namespace { + +inline QMetaMethod setItemAreaMethod() +{ + const int idx = Scene3DItem::staticMetaObject.indexOfMethod("setItemArea(QSize)"); + Q_ASSERT(idx != -1); + return Scene3DItem::staticMetaObject.method(idx); +} + +} // anonymous + class ContextSaver { public: @@ -120,14 +129,18 @@ Scene3DRenderer::Scene3DRenderer(Scene3DItem *item, Qt3DCore::QAspectEngine *asp , m_multisampledFBO(nullptr) , m_finalFBO(nullptr) , m_texture(nullptr) + , m_node(nullptr) + , 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 +186,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 +208,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(); @@ -238,8 +261,11 @@ void Scene3DRenderer::render() const bool multisampleHasChanged = m_multisample != m_lastMultisample; const bool forceRecreate = sizeHasChanged || multisampleHasChanged; - if (sizeHasChanged) - m_item->setItemArea(boundingRectSize); + if (sizeHasChanged) { + // We are in the QSGRenderThread (doing a direct call would result in a race) + static const QMetaMethod setItemArea = setItemAreaMethod(); + setItemArea.invoke(m_item, Qt::QueuedConnection, Q_ARG(QSize, boundingRectSize)); + } // Rebuild FBO and textures if never created or a resize has occurred if ((m_multisampledFBO.isNull() || forceRecreate) && m_multisample) { diff --git a/src/quick3d/imports/scene3d/scene3drenderer_p.h b/src/quick3d/imports/scene3d/scene3drenderer_p.h index 9ff5e7f36..ab1db1010 100644 --- a/src/quick3d/imports/scene3d/scene3drenderer_p.h +++ b/src/quick3d/imports/scene3d/scene3drenderer_p.h @@ -51,8 +51,7 @@ // We mean it. // -#include <QObject> - +#include <QtCore/QObject> #include <QtCore/qsize.h> QT_BEGIN_NAMESPACE @@ -91,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 @@ -105,6 +105,7 @@ private: QSize m_lastSize; bool m_multisample; bool m_lastMultisample; + bool m_needsShutdown; friend class Scene3DCleaner; }; diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h b/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h index f3817dc05..df431e452 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h +++ b/src/quick3d/imports/scene3d/scene3dsgmaterial_p.h @@ -52,10 +52,10 @@ // #include <QtQuick/QSGMaterial> -#include "scene3dsgmaterialshader_p.h" - #include <QtQuick/qsgtexture.h> +#include <scene3dsgmaterialshader_p.h> + QT_BEGIN_NAMESPACE namespace Qt3DRender { diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp index 5ce0f4d60..8a4585558 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp +++ b/src/quick3d/imports/scene3d/scene3dsgmaterialshader.cpp @@ -38,12 +38,13 @@ ****************************************************************************/ #include "scene3dsgmaterialshader_p.h" -#include "scene3dsgmaterial_p.h" #include <QtGui/qopenglcontext.h> #include <QtGui/qopenglfunctions.h> #include <QtGui/qsurfaceformat.h> +#include <scene3dsgmaterial_p.h> + QT_BEGIN_NAMESPACE namespace { @@ -71,6 +72,13 @@ namespace Qt3DRender { QSGMaterialType Scene3DSGMaterialShader::type; +Scene3DSGMaterialShader::Scene3DSGMaterialShader() + : QSGMaterialShader() + , m_matrixId(-1) + , m_opacityId(-1) +{ +} + const char * const *Scene3DSGMaterialShader::attributeNames() const { static char const *const attr[] = { "qt_VertexPosition", "qt_VertexTexCoord", 0 }; diff --git a/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h b/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h index 64d281ec4..a1222b07d 100644 --- a/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h +++ b/src/quick3d/imports/scene3d/scene3dsgmaterialshader_p.h @@ -60,6 +60,7 @@ namespace Qt3DRender { class Scene3DSGMaterialShader : public QSGMaterialShader { public: + Scene3DSGMaterialShader(); void updateState(const RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial) Q_DECL_FINAL; const char * const *attributeNames() const Q_DECL_FINAL; diff --git a/src/quick3d/imports/scene3d/scene3dsgnode.cpp b/src/quick3d/imports/scene3d/scene3dsgnode.cpp index ae0a07350..8806b59a9 100644 --- a/src/quick3d/imports/scene3d/scene3dsgnode.cpp +++ b/src/quick3d/imports/scene3d/scene3dsgnode.cpp @@ -38,10 +38,11 @@ ****************************************************************************/ #include "scene3dsgnode_p.h" -#include "scene3dlogging_p.h" #include <QtCore/qthread.h> +#include <scene3dlogging_p.h> + QT_BEGIN_NAMESPACE namespace Qt3DRender { diff --git a/src/quick3d/imports/scene3d/scene3dsgnode_p.h b/src/quick3d/imports/scene3d/scene3dsgnode_p.h index f7b21e2b9..68b68eea5 100644 --- a/src/quick3d/imports/scene3d/scene3dsgnode_p.h +++ b/src/quick3d/imports/scene3d/scene3dsgnode_p.h @@ -53,7 +53,7 @@ #include <QtQuick/QSGGeometryNode> -#include "scene3dsgmaterial_p.h" +#include <scene3dsgmaterial_p.h> QT_BEGIN_NAMESPACE |