From c39067f20be926698d9ae32cc2ddd7981594058c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= <christian.stromme@qt.io> Date: Mon, 26 Oct 2020 21:18:42 +0100 Subject: [PATCH] Remove the shared pointer around the scene manager Change-Id: Ic5608d0361b23a2ea045b043227838947bd50ece Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io> --- src/quick3d/qquick3ddefaultmaterial.cpp | 20 +++---- src/quick3d/qquick3ddefaultmaterial_p.h | 2 +- src/quick3d/qquick3deffect.cpp | 4 +- src/quick3d/qquick3deffect_p.h | 2 +- src/quick3d/qquick3dmaterial.cpp | 12 ++-- src/quick3d/qquick3dmaterial_p.h | 2 +- src/quick3d/qquick3dmodel.cpp | 10 ++-- src/quick3d/qquick3dmodel_p.h | 2 +- src/quick3d/qquick3dobject.cpp | 65 +++++++++++----------- src/quick3d/qquick3dobject.h | 17 +++--- src/quick3d/qquick3dobject_p.h | 10 ++-- src/quick3d/qquick3dprincipledmaterial.cpp | 24 ++++---- src/quick3d/qquick3dprincipledmaterial_p.h | 2 +- src/quick3d/qquick3dsceneenvironment.cpp | 4 +- src/quick3d/qquick3dsceneenvironment_p.h | 2 +- src/quick3d/qquick3dscenerenderer.cpp | 2 +- src/quick3d/qquick3dscenerenderer_p.h | 4 +- src/quick3d/qquick3dtexture.cpp | 4 +- src/quick3d/qquick3dtexture_p.h | 2 +- src/quick3d/qquick3dviewport.cpp | 28 ++++++---- tools/shadergen/genshaders.cpp | 2 +- tools/shadergen/genshaders.h | 2 +- 22 files changed, 114 insertions(+), 108 deletions(-) diff --git a/src/quick3d/qquick3ddefaultmaterial.cpp b/src/quick3d/qquick3ddefaultmaterial.cpp index bdda20f2e..62018320c 100644 --- a/src/quick3d/qquick3ddefaultmaterial.cpp +++ b/src/quick3d/qquick3ddefaultmaterial.cpp @@ -1000,19 +1000,19 @@ void QQuick3DDefaultMaterial::itemChange(QQuick3DObject::ItemChange change, cons updateSceneManager(value.sceneManager); } -void QQuick3DDefaultMaterial::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager) +void QQuick3DDefaultMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager) { // Check all the resource value's windows, and update as necessary if (sceneManager) { - QQuick3DObjectPrivate::refSceneManager(m_diffuseMap, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_emissiveMap, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_specularReflectionMap, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_specularMap, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_roughnessMap, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_opacityMap, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_bumpMap, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_normalMap, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_translucencyMap, sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_diffuseMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_emissiveMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_specularReflectionMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_specularMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_roughnessMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_opacityMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_bumpMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_normalMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_translucencyMap, *sceneManager); } else { QQuick3DObjectPrivate::derefSceneManager(m_diffuseMap); QQuick3DObjectPrivate::derefSceneManager(m_emissiveMap); diff --git a/src/quick3d/qquick3ddefaultmaterial_p.h b/src/quick3d/qquick3ddefaultmaterial_p.h index 0d8cd056a..f3617e40a 100644 --- a/src/quick3d/qquick3ddefaultmaterial_p.h +++ b/src/quick3d/qquick3ddefaultmaterial_p.h @@ -232,7 +232,7 @@ private: LineWidthDirty = 0x00000800 }; - void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager); + void updateSceneManager(QQuick3DSceneManager *sceneManager); Lighting m_lighting = FragmentLighting; BlendMode m_blendMode = SourceOver; QColor m_diffuseColor; diff --git a/src/quick3d/qquick3deffect.cpp b/src/quick3d/qquick3deffect.cpp index b3a942d13..829432e23 100644 --- a/src/quick3d/qquick3deffect.cpp +++ b/src/quick3d/qquick3deffect.cpp @@ -1040,11 +1040,11 @@ void QQuick3DEffect::markDirty(QQuick3DEffect::Dirty type) } } -void QQuick3DEffect::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager) +void QQuick3DEffect::updateSceneManager(QQuick3DSceneManager *sceneManager) { if (sceneManager) { for (auto it : m_dynamicTextureMaps) - QQuick3DObjectPrivate::refSceneManager(it, sceneManager); + QQuick3DObjectPrivate::refSceneManager(it, *sceneManager); } else { for (auto it : m_dynamicTextureMaps) QQuick3DObjectPrivate::derefSceneManager(it); diff --git a/src/quick3d/qquick3deffect_p.h b/src/quick3d/qquick3deffect_p.h index f35c1da17..d81da180a 100644 --- a/src/quick3d/qquick3deffect_p.h +++ b/src/quick3d/qquick3deffect_p.h @@ -91,7 +91,7 @@ private: quint32 m_dirtyAttributes = 0xffffffff; - void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager); + void updateSceneManager(QQuick3DSceneManager *sceneManager); friend class QQuick3DSceneRenderer; QVector<QQuick3DShaderUtilsRenderPass *> m_passes; diff --git a/src/quick3d/qquick3dmaterial.cpp b/src/quick3d/qquick3dmaterial.cpp index 332522485..7ac2f5ae0 100644 --- a/src/quick3d/qquick3dmaterial.cpp +++ b/src/quick3d/qquick3dmaterial.cpp @@ -287,15 +287,15 @@ void QQuick3DMaterial::setDynamicTextureMap(QQuick3DTexture *textureMap, const Q update(); } -void QQuick3DMaterial::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager) +void QQuick3DMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager) { if (sceneManager) { - QQuick3DObjectPrivate::refSceneManager(m_lightmapIndirect, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_lightmapRadiosity, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_lightmapShadow, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_iblProbe, sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_lightmapIndirect, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_lightmapRadiosity, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_lightmapShadow, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_iblProbe, *sceneManager); for (auto it : m_dynamicTextureMaps) - QQuick3DObjectPrivate::refSceneManager(it, sceneManager); + QQuick3DObjectPrivate::refSceneManager(it, *sceneManager); } else { QQuick3DObjectPrivate::derefSceneManager(m_lightmapIndirect); QQuick3DObjectPrivate::derefSceneManager(m_lightmapRadiosity); diff --git a/src/quick3d/qquick3dmaterial_p.h b/src/quick3d/qquick3dmaterial_p.h index 68047bc24..4b499dd46 100644 --- a/src/quick3d/qquick3dmaterial_p.h +++ b/src/quick3d/qquick3dmaterial_p.h @@ -110,7 +110,7 @@ protected: public: void setDynamicTextureMap(QQuick3DTexture *textureMap, const QByteArray &name); private: - void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager); + void updateSceneManager(QQuick3DSceneManager *sceneManager); QQuick3DTexture *m_lightmapIndirect = nullptr; QQuick3DTexture *m_lightmapRadiosity = nullptr; QQuick3DTexture *m_lightmapShadow = nullptr; diff --git a/src/quick3d/qquick3dmodel.cpp b/src/quick3d/qquick3dmodel.cpp index cfb2d9049..f5e75c87d 100644 --- a/src/quick3d/qquick3dmodel.cpp +++ b/src/quick3d/qquick3dmodel.cpp @@ -501,16 +501,16 @@ void QQuick3DModel::markDirty(QQuick3DModel::QSSGModelDirtyType type) } } -void QQuick3DModel::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager) +void QQuick3DModel::updateSceneManager(QQuick3DSceneManager *sceneManager) { if (sceneManager) { sceneManager->dirtyBoundingBoxList.append(this); - QQuick3DObjectPrivate::refSceneManager(m_skeleton, sceneManager); - QQuick3DObjectPrivate::refSceneManager(m_geometry, sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_skeleton, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_geometry, *sceneManager); for (Material &mat : m_materials) { if (!mat.material->parentItem() && !QQuick3DObjectPrivate::get(mat.material)->sceneManager) { if (!mat.refed) { - QQuick3DObjectPrivate::refSceneManager(mat.material, sceneManager); + QQuick3DObjectPrivate::refSceneManager(mat.material, *sceneManager); mat.refed = true; } } @@ -557,7 +557,7 @@ void QQuick3DModel::qmlAppendMaterial(QQmlListProperty<QQuick3DMaterial> *list, } else { // If no valid parent was found, make sure the material refs our scene manager const auto &sceneManager = QQuick3DObjectPrivate::get(self)->sceneManager; if (sceneManager) { - QQuick3DObjectPrivate::get(material)->refSceneManager(sceneManager); + QQuick3DObjectPrivate::get(material)->refSceneManager(*sceneManager); // Have to keep track if we called refSceneManager because we // can end up in double deref attempts when a model is going // away, due to updateSceneManager() being called on diff --git a/src/quick3d/qquick3dmodel_p.h b/src/quick3d/qquick3dmodel_p.h index 75b2a9f4d..7fb7c9af3 100644 --- a/src/quick3d/qquick3dmodel_p.h +++ b/src/quick3d/qquick3dmodel_p.h @@ -165,7 +165,7 @@ private: quint32 m_dirtyAttributes = 0xffffffff; // all dirty by default void markDirty(QSSGModelDirtyType type); - void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &sceneManager); + void updateSceneManager(QQuick3DSceneManager *sceneManager); static void qmlAppendMaterial(QQmlListProperty<QQuick3DMaterial> *list, QQuick3DMaterial *material); static QQuick3DMaterial *qmlMaterialAt(QQmlListProperty<QQuick3DMaterial> *list, int index); diff --git a/src/quick3d/qquick3dobject.cpp b/src/quick3d/qquick3dobject.cpp index 0eb571b4f..5158d1758 100644 --- a/src/quick3d/qquick3dobject.cpp +++ b/src/quick3d/qquick3dobject.cpp @@ -104,13 +104,6 @@ QQuick3DObject::QQuick3DObject(QQuick3DObject *parent) QQuick3DObject::~QQuick3DObject() { Q_D(QQuick3DObject); - if (d->windowRefCount > 1) - d->windowRefCount = 1; // Make sure window is set to null in next call to derefWindow(). - if (d->parentItem) - setParentItem(nullptr); - else if (d->sceneManager) - QQuick3DObjectPrivate::derefSceneManager(this); - // XXX todo - optimize while (!d->childItems.isEmpty()) d->childItems.constFirst()->setParentItem(nullptr); @@ -119,6 +112,17 @@ QQuick3DObject::~QQuick3DObject() d->_stateGroup = nullptr; delete d->contentItem2d; d->contentItem2d = nullptr; + + if (d->parentItem) + setParentItem(nullptr); + + if (d->sceneRefCount > 1) { + qWarning("Unexpected ref. count %d\n", d->sceneRefCount); + d->sceneRefCount = 1; // Make sure the scene is set to null in next call to derefSceneManager(). + } + + if (!d->parentItem && d->sceneManager) + QQuick3DObjectPrivate::derefSceneManager(this); } void QQuick3DObject::update() @@ -192,7 +196,7 @@ void QQuick3DObject::setParentItem(QQuick3DObject *parentItem) QQuick3DObjectPrivate::derefSceneManager(this); d->parentItem = parentItem; if (parentSceneManager) - QQuick3DObjectPrivate::refSceneManager(this, parentSceneManager); + QQuick3DObjectPrivate::refSceneManager(this, *parentSceneManager); } d->dirty(QQuick3DObjectPrivate::ParentChanged); @@ -279,14 +283,14 @@ void QQuick3DObject::preSync() void QQuick3DObjectPrivate::updatePropertyListener(QQuick3DObject *newO, QQuick3DObject *oldO, - const QSharedPointer<QQuick3DSceneManager> &window, + QQuick3DSceneManager *sceneManager, const QByteArray &propertyKey, ConnectionMap &connections, const std::function<void(QQuick3DObject *)> &callFn) { // disconnect previous destruction listener if (oldO) { - if (window) + if (sceneManager) QQuick3DObjectPrivate::derefSceneManager(oldO); auto connection = connections.find(propertyKey); @@ -298,8 +302,8 @@ void QQuick3DObjectPrivate::updatePropertyListener(QQuick3DObject *newO, // listen for new map's destruction if (newO) { - if (window) - QQuick3DObjectPrivate::refSceneManager(newO, window); + if (sceneManager) + QQuick3DObjectPrivate::refSceneManager(newO, *sceneManager); auto connection = QObject::connect(newO, &QObject::destroyed, [callFn](){ callFn(nullptr); }); @@ -313,7 +317,7 @@ QQuick3DObjectPrivate::QQuick3DObjectPrivate(QQuick3DObjectPrivate::Type t) , nextDirtyItem(nullptr) , prevDirtyItem(nullptr) , sceneManager(nullptr) - , windowRefCount(0) + , sceneRefCount(0) , parentItem(nullptr) , sortedChildItems(&childItems) , subFocusItem(nullptr) @@ -978,28 +982,27 @@ void QQuick3DObjectPrivate::markSortedChildrenDirty(QQuick3DObject *child) Q_UNUSED(child); } -void QQuick3DObjectPrivate::refSceneManager(const QSharedPointer<QQuick3DSceneManager> &c) +void QQuick3DObjectPrivate::refSceneManager(QQuick3DSceneManager &c) { - // An item needs a window if it is referenced by another item which has a window. + // An item needs a scene manager if it is referenced by another item which has a scene manager. // Typically the item is referenced by a parent, but can also be referenced by a - // ShaderEffect or ShaderEffectSource. 'windowRefCount' counts how many items with - // a window is referencing this item. When the reference count goes from zero to one, - // or one to zero, the window of this item is updated and propagated to the children. - // As long as the reference count stays above zero, the window is unchanged. - // refWindow() increments the reference count. - // derefWindow() decrements the reference count. + // ShaderEffect or ShaderEffectSource. 'sceneRefCount' counts how many items with + // a scene manager is referencing this item. When the reference count goes from zero to one, + // or one to zero, the scene manager of this item is updated and propagated to the children. + // As long as the reference count stays above zero, the scene manager is unchanged. + // refSceneManager() increments the reference count. + // derefSceneManager() decrements the reference count. Q_Q(QQuick3DObject); - Q_ASSERT((sceneManager != nullptr) == (windowRefCount > 0)); - Q_ASSERT(c); - if (++windowRefCount > 1) { - if (c != sceneManager) + Q_ASSERT((sceneManager != nullptr) == (sceneRefCount > 0)); + if (++sceneRefCount > 1) { + if (&c != sceneManager) qWarning("QSSGObject: Cannot use same item on different windows at the same time."); return; // Window already set. } Q_ASSERT(sceneManager == nullptr); - sceneManager = c; + sceneManager = &c; // if (polishScheduled) // QSSGWindowPrivate::get(window)->itemsToPolish.append(q); @@ -1014,7 +1017,7 @@ void QQuick3DObjectPrivate::refSceneManager(const QSharedPointer<QQuick3DSceneMa dirty(Window); - itemChange(QQuick3DObject::ItemSceneChange, c); + itemChange(QQuick3DObject::ItemSceneChange, &c); } void QQuick3DObjectPrivate::derefSceneManager() @@ -1024,8 +1027,8 @@ void QQuick3DObjectPrivate::derefSceneManager() if (!sceneManager) return; // This can happen when destroying recursive shader effect sources. - if (--windowRefCount > 0) - return; // There are still other references, so don't set window to null yet. + if (--sceneRefCount > 0) + return; // There are still other references, so don't set the scene manager to null yet. removeFromDirtyList(); if (sceneManager) { @@ -1038,8 +1041,6 @@ void QQuick3DObjectPrivate::derefSceneManager() if (!parentItem) sceneManager->parentlessItems.remove(q); - sceneManager.reset(); - spatialNode = nullptr; for (int ii = 0; ii < childItems.count(); ++ii) { @@ -1047,6 +1048,8 @@ void QQuick3DObjectPrivate::derefSceneManager() QQuick3DObjectPrivate::derefSceneManager(child); } + sceneManager = nullptr; + dirty(Window); itemChange(QQuick3DObject::ItemSceneChange, sceneManager); diff --git a/src/quick3d/qquick3dobject.h b/src/quick3d/qquick3dobject.h index c19b3d5e9..759d43627 100644 --- a/src/quick3d/qquick3dobject.h +++ b/src/quick3d/qquick3dobject.h @@ -82,19 +82,16 @@ public: ItemEnabledHasChanged // value.boolValue }; - struct ItemChangeData { + union ItemChangeData { ItemChangeData(QQuick3DObject *v) : item(v) {} - ItemChangeData(const QSharedPointer<QQuick3DSceneManager> &v) : sceneManager(v) {} + ItemChangeData(QQuick3DSceneManager *v) : sceneManager(v) {} ItemChangeData(qreal v) : realValue(v) {} ItemChangeData(bool v) : boolValue(v) {} - ~ItemChangeData() {} - - QSharedPointer<QQuick3DSceneManager> sceneManager; - union { - QQuick3DObject *item; - qreal realValue; - bool boolValue; - }; + + QQuick3DObject *item; + QQuick3DSceneManager *sceneManager; + qreal realValue; + bool boolValue; }; explicit QQuick3DObject(QQuick3DObject *parent = nullptr); diff --git a/src/quick3d/qquick3dobject_p.h b/src/quick3d/qquick3dobject_p.h index 542a5708c..d86e9afc6 100644 --- a/src/quick3d/qquick3dobject_p.h +++ b/src/quick3d/qquick3dobject_p.h @@ -94,7 +94,7 @@ public: static void updatePropertyListener(QQuick3DObject *newO, QQuick3DObject *oldO, - const QSharedPointer<QQuick3DSceneManager> &window, + QQuick3DSceneManager *sceneManager, const QByteArray &propertyKey, ConnectionMap &connections, const std::function<void(QQuick3DObject *o)> &callFn); @@ -233,8 +233,8 @@ public: void setCulled(bool); - QSharedPointer<QQuick3DSceneManager> sceneManager; - int windowRefCount; + QQuick3DSceneManager *sceneManager = nullptr; + int sceneRefCount; QQuick3DObject *parentItem; @@ -247,10 +247,10 @@ public: void markSortedChildrenDirty(QQuick3DObject *child); - void refSceneManager(const QSharedPointer<QQuick3DSceneManager> &); + void refSceneManager(QQuick3DSceneManager &); void derefSceneManager(); - static void refSceneManager(QQuick3DObject *obj,const QSharedPointer<QQuick3DSceneManager> &mgr) + static void refSceneManager(QQuick3DObject *obj, QQuick3DSceneManager &mgr) { if (obj) QQuick3DObjectPrivate::get(obj)->refSceneManager(mgr); diff --git a/src/quick3d/qquick3dprincipledmaterial.cpp b/src/quick3d/qquick3dprincipledmaterial.cpp index a75cbfc31..bf4bea46d 100644 --- a/src/quick3d/qquick3dprincipledmaterial.cpp +++ b/src/quick3d/qquick3dprincipledmaterial.cpp @@ -1007,19 +1007,19 @@ void QQuick3DPrincipledMaterial::itemChange(QQuick3DObject::ItemChange change, c updateSceneManager(value.sceneManager); } -void QQuick3DPrincipledMaterial::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &window) +void QQuick3DPrincipledMaterial::updateSceneManager(QQuick3DSceneManager *sceneManager) { - // Check all the resource value's windows, and update as necessary - if (window) { - QQuick3DObjectPrivate::refSceneManager(m_baseColorMap, window); - QQuick3DObjectPrivate::refSceneManager(m_emissiveMap, window); - QQuick3DObjectPrivate::refSceneManager(m_specularReflectionMap, window); - QQuick3DObjectPrivate::refSceneManager(m_specularMap, window); - QQuick3DObjectPrivate::refSceneManager(m_roughnessMap, window); - QQuick3DObjectPrivate::refSceneManager(m_opacityMap, window); - QQuick3DObjectPrivate::refSceneManager(m_normalMap, window); - QQuick3DObjectPrivate::refSceneManager(m_metalnessMap, window); - QQuick3DObjectPrivate::refSceneManager(m_occlusionMap, window); + // Check all the resource value's scene manager, and update as necessary. + if (sceneManager) { + QQuick3DObjectPrivate::refSceneManager(m_baseColorMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_emissiveMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_specularReflectionMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_specularMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_roughnessMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_opacityMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_normalMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_metalnessMap, *sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_occlusionMap, *sceneManager); } else { QQuick3DObjectPrivate::derefSceneManager(m_baseColorMap); QQuick3DObjectPrivate::derefSceneManager(m_emissiveMap); diff --git a/src/quick3d/qquick3dprincipledmaterial_p.h b/src/quick3d/qquick3dprincipledmaterial_p.h index b9aa518f7..da9870fb2 100644 --- a/src/quick3d/qquick3dprincipledmaterial_p.h +++ b/src/quick3d/qquick3dprincipledmaterial_p.h @@ -231,7 +231,7 @@ private: LineWidthDirty = 0x00001000 }; - void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &window); + void updateSceneManager(QQuick3DSceneManager *window); // Note: The default values for properties that are also present in // QSSGShaderCustomMaterialAdapter must match the values there, because a diff --git a/src/quick3d/qquick3dsceneenvironment.cpp b/src/quick3d/qquick3dsceneenvironment.cpp index 92106b2d1..b1c654158 100644 --- a/src/quick3d/qquick3dsceneenvironment.cpp +++ b/src/quick3d/qquick3dsceneenvironment.cpp @@ -680,10 +680,10 @@ void QQuick3DSceneEnvironment::itemChange(QQuick3DObject::ItemChange change, con updateSceneManager(value.sceneManager); } -void QQuick3DSceneEnvironment::updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &manager) +void QQuick3DSceneEnvironment::updateSceneManager(QQuick3DSceneManager *manager) { if (manager) - QQuick3DObjectPrivate::refSceneManager(m_lightProbe, manager); + QQuick3DObjectPrivate::refSceneManager(m_lightProbe, *manager); else QQuick3DObjectPrivate::derefSceneManager(m_lightProbe); } diff --git a/src/quick3d/qquick3dsceneenvironment_p.h b/src/quick3d/qquick3dsceneenvironment_p.h index 61a775708..cb12019fa 100644 --- a/src/quick3d/qquick3dsceneenvironment_p.h +++ b/src/quick3d/qquick3dsceneenvironment_p.h @@ -218,7 +218,7 @@ private: static int qmlEffectsCount(QQmlListProperty<QQuick3DEffect> *list); static void qmlClearEffects(QQmlListProperty<QQuick3DEffect> *list); - void updateSceneManager(const QSharedPointer<QQuick3DSceneManager> &manager); + void updateSceneManager(QQuick3DSceneManager *manager); QQuick3DEnvironmentAAModeValues m_antialiasingMode = NoAA; QQuick3DEnvironmentAAQualityValues m_antialiasingQuality = High; diff --git a/src/quick3d/qquick3dscenerenderer.cpp b/src/quick3d/qquick3dscenerenderer.cpp index fe3058ec5..ab6f03d03 100644 --- a/src/quick3d/qquick3dscenerenderer.cpp +++ b/src/quick3d/qquick3dscenerenderer.cpp @@ -565,7 +565,7 @@ void QQuick3DSceneRenderer::synchronize(QQuick3DViewport *item, const QSize &siz m_importSceneManager->updateBoundingBoxes(m_sgContext->bufferManager()); m_importSceneManager->updateDirtyNodes(); } else { - m_importSceneManager.clear(); + m_importSceneManager = nullptr; } // Generate layer node diff --git a/src/quick3d/qquick3dscenerenderer_p.h b/src/quick3d/qquick3dscenerenderer_p.h index 89396cd9a..92659b646 100644 --- a/src/quick3d/qquick3dscenerenderer_p.h +++ b/src/quick3d/qquick3dscenerenderer_p.h @@ -86,8 +86,8 @@ private: void addNodeToLayer(QSSGRenderNode *node); void removeNodeFromLayer(QSSGRenderNode *node); QSSGRef<QSSGRenderContextInterface> m_sgContext; - QSharedPointer<QQuick3DSceneManager> m_sceneManager; - QSharedPointer<QQuick3DSceneManager> m_importSceneManager; + QQuick3DSceneManager *m_sceneManager = nullptr; + QQuick3DSceneManager *m_importSceneManager = nullptr; QSSGRenderLayer *m_layer = nullptr; QSize m_surfaceSize; void *data = nullptr; diff --git a/src/quick3d/qquick3dtexture.cpp b/src/quick3d/qquick3dtexture.cpp index 172101ce1..24fb76bf9 100644 --- a/src/quick3d/qquick3dtexture.cpp +++ b/src/quick3d/qquick3dtexture.cpp @@ -983,7 +983,7 @@ void QQuick3DTexture::itemChange(QQuick3DObject::ItemChange change, const QQuick if (m_textureData) { const auto &sceneManager = value.sceneManager; if (sceneManager) - QQuick3DObjectPrivate::refSceneManager(m_textureData, sceneManager); + QQuick3DObjectPrivate::refSceneManager(m_textureData, *sceneManager); else QQuick3DObjectPrivate::derefSceneManager(m_textureData); } @@ -1037,7 +1037,7 @@ void QQuick3DTexture::createLayerTexture() connect( layer, &QObject::destroyed, - manager.data(), + manager, [manager, layer]() { // this is on the render thread so all borked threading-wise (all data here is gui thread stuff...) but will survive manager->qsgDynamicTextures.removeAll(layer); diff --git a/src/quick3d/qquick3dtexture_p.h b/src/quick3d/qquick3dtexture_p.h index 15ca5274c..f7c342bb7 100644 --- a/src/quick3d/qquick3dtexture_p.h +++ b/src/quick3d/qquick3dtexture_p.h @@ -221,7 +221,7 @@ private: | DirtyFlags(DirtyFlag::TextureDataDirty); QMetaObject::Connection m_textureProviderConnection; QMetaObject::Connection m_textureUpdateConnection; - QSharedPointer<QQuick3DSceneManager> m_sceneManagerForLayer; + QQuick3DSceneManager *m_sceneManagerForLayer = nullptr; QQuickItem *m_initializedSourceItem = nullptr; void trySetSourceParent(); QHash<QByteArray, QMetaObject::Connection> m_connections; diff --git a/src/quick3d/qquick3dviewport.cpp b/src/quick3d/qquick3dviewport.cpp index 58db81e6b..a3ddf3ab3 100644 --- a/src/quick3d/qquick3dviewport.cpp +++ b/src/quick3d/qquick3dviewport.cpp @@ -100,9 +100,10 @@ QQuick3DViewport::QQuick3DViewport(QQuickItem *parent) m_sceneRoot = new QQuick3DSceneRootNode(this); m_environment = new QQuick3DSceneEnvironment(m_sceneRoot); m_renderStats = new QQuick3DRenderStats(m_sceneRoot); - QSharedPointer<QQuick3DSceneManager> sceneManager(new QQuick3DSceneManager(m_sceneRoot)); - QQuick3DObjectPrivate::get(m_sceneRoot)->refSceneManager(sceneManager); - connect(QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager.data(), &QQuick3DSceneManager::needsUpdate, + QQuick3DSceneManager *sceneManager = new QQuick3DSceneManager(m_sceneRoot); + QQuick3DObjectPrivate::get(m_sceneRoot)->refSceneManager(*sceneManager); + Q_ASSERT(sceneManager == QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager); + connect(sceneManager, &QQuick3DSceneManager::needsUpdate, this, &QQuickItem::update); } @@ -110,11 +111,14 @@ QQuick3DViewport::~QQuick3DViewport() { for (const auto &connection : qAsConst(m_connections)) disconnect(connection); - // Do not delete scenemanager along with sceneroot - auto &sceneManager = QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager; + auto sceneManager = QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager; if (sceneManager) sceneManager->setParent(nullptr); + delete m_sceneRoot; + m_sceneRoot = nullptr; + + delete sceneManager; // m_directRenderer must be destroyed on the render thread at the proper time, not here. // That's handled in releaseResources() + upon sceneGraphInvalidated @@ -501,15 +505,17 @@ void QQuick3DViewport::setImportScene(QQuick3DNode *inScene) m_importScene = inScene; if (m_importScene) { - // If the referenced scene doesn't have a manager, add one (scenes defined outside of an view3d) + // If the referenced scene doesn't have a manager use the one from the sceen root (scenes defined outside of an view3d) auto privateObject = QQuick3DObjectPrivate::get(m_importScene); if (!privateObject->sceneManager) { - QSharedPointer<QQuick3DSceneManager> manager(new QQuick3DSceneManager); - manager->setWindow(window()); - privateObject->refSceneManager(manager); + if (QQuick3DSceneManager *manager = QQuick3DObjectPrivate::get(m_sceneRoot)->sceneManager) { + manager->setWindow(window()); + privateObject->refSceneManager(*manager); + } + Q_ASSERT(privateObject->sceneManager); } - connect(privateObject->sceneManager.data(), &QQuick3DSceneManager::needsUpdate, + connect(privateObject->sceneManager, &QQuick3DSceneManager::needsUpdate, this, &QQuickItem::update); QQuick3DNode *scene = inScene; @@ -518,7 +524,7 @@ void QQuick3DViewport::setImportScene(QQuick3DNode *inScene) scene = rn ? rn->view3D()->importScene() : nullptr; if (scene) { - connect(QQuick3DObjectPrivate::get(scene)->sceneManager.data(), + connect(QQuick3DObjectPrivate::get(scene)->sceneManager, &QQuick3DSceneManager::needsUpdate, this, &QQuickItem::update); } diff --git a/tools/shadergen/genshaders.cpp b/tools/shadergen/genshaders.cpp index b5df490ba..c8d985cd7 100644 --- a/tools/shadergen/genshaders.cpp +++ b/tools/shadergen/genshaders.cpp @@ -77,7 +77,7 @@ static QQsbShaderFeatureSet toQsbShaderFeatureSet(const ShaderFeatureSetList &fe GenShaders::GenShaders(const QString &sourceDir) { - sceneManager.reset(new QQuick3DSceneManager); + sceneManager = new QQuick3DSceneManager; rhi = QRhi::create(QRhi::Null, nullptr); QRhiCommandBuffer *cb; diff --git a/tools/shadergen/genshaders.h b/tools/shadergen/genshaders.h index 6ec249c0c..ec458f152 100644 --- a/tools/shadergen/genshaders.h +++ b/tools/shadergen/genshaders.h @@ -56,7 +56,7 @@ struct GenShaders QRhi *rhi = nullptr; QSSGRef<QSSGRenderContextInterface> renderContext; - QSharedPointer<QQuick3DSceneManager> sceneManager; + QQuick3DSceneManager *sceneManager = nullptr; static void processFoo(const QSSGRef<QSSGRenderContextInterface> &renderContext, const MaterialParser::SceneData &sceneData); }; -- GitLab