diff --git a/src/quick3d/qquick3ddefaultmaterial.cpp b/src/quick3d/qquick3ddefaultmaterial.cpp index bdda20f2e7cef2ecd7e196a8966b244ee00b0cee..62018320ce65bf4318f835b45d21644f59c04c13 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 0d8cd056a459d96fb9495a9032139edcd44c925f..f3617e40a56e5787349088d536127d7669f1408e 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 b3a942d139ef62ee757ad0d2ec4fc9ed04d4c1e5..829432e23cdc4db448be7e193e10b724821837b8 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 f35c1da1786b2ae3a7e65f049cc9bd53e6970e6b..d81da180aac0ca22ab58bf2bfe6d89636d436aa1 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 332522485840c166b90bc9fc5bbda0d7104c63c3..7ac2f5ae0e828fb4c0bd383605cf767d09ff3637 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 68047bc24f0c44e3ef853b00d7a22b4532fe5362..4b499dd46db921e63336fb3126abda326a1fd5fa 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 cfb2d9049df72981458cce8b8f6f823cfe6207b1..f5e75c87d6f77e6cae49383c5da0a66fb48ed2c1 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 75b2a9f4dce126c455dfeeac3f8c3a5f6c395f61..7fb7c9af3c1bd3f4f4b23b36c3b22c9996ae9cf3 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 0eb571b4f5720df9af8cceac72463d1df471d358..5158d175814f1077324a3405c02e3b1f45b1e750 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 c19b3d5e96b0031a056f4bd00232cd6abfc04f36..759d43627fb42922d8b8318c1a8258ede7cfce54 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 542a5708c25e703a2d3a9c10a28f6df14e4b929c..d86e9afc638e2b80381aa4864a1a5117b7d81761 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 a75cbfc31ffe87382552d652ca74efc78eb4bd87..bf4bea46d6bcc95fdd543233066211b1813852d2 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 b9aa518f7529160b2385b384152c525e5abefa0b..da9870fb241ae854f3f9ae7125bd09821cde9c42 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 92106b2d1e453bec7bd1edf51d28802ea01fd3d8..b1c654158d048a80a0d0d66e7e562074da2e50dd 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 61a7757089d39ee16019d7b1389c52f873562bc7..cb12019fa6bb4c38d288814f0eb2efe19da35db3 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 fe3058ec5486db07abc98a4e30583d3cd37c7b47..ab6f03d0381d3dc9d36a8405dbda772f32fb81c1 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 89396cd9ab27866b874df4b297c2bc05650a2656..92659b646a1515f7f3ec2ffd470011b622d21b63 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 172101ce191dbd4a61ed1f2961a54100568d0fe0..24fb76bf98f86d3b5cb8244e448b6d41379e6b78 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 15ca5274cf657b8611e240e13dae33962e99fce2..f7c342bb714fe2b78f7c8d6536c8604e3cec8506 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 58db81e6ba3e1b43c34726273e0485de55ffa226..a3ddf3ab33467eb56e8c9035aaf700223291ae2a 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 b5df490ba37e4e3cae4bdcbb2b548f83fbb519b1..c8d985cd7a1142e7cbe9fb36cbacf0a64b6c45aa 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 6ec249c0ca72afcb564395c8fdf8baac837e43a4..ec458f15270304177f2170bc85f435b559f1bcfb 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); };