From 861e372b6ad81570d4f496e42fb25a6699b72f2f Mon Sep 17 00:00:00 2001 From: Piotr Mikolajczyk Date: Tue, 3 Nov 2020 11:43:22 +0100 Subject: Simpler fix to crashing Qml Map appearing 2nd+ time Previous solution did not take advantage of the QSGNode::OwnedByParent flag. Setting this flag to false allows to use parent() property to determine if the node has been removed from node tree. This amends 4fe9e0ed027134a833b2243597a2ccd00987b559 Fixes: QTBUG-85260 Change-Id: I705848483d7dc2639dffffa0ff66c682b3fffca0 Reviewed-by: Andy Shaw --- src/location/labs/qsg/qgeomapobjectqsgsupport.cpp | 40 +++++------------------ src/location/labs/qsg/qgeomapobjectqsgsupport_p.h | 3 +- 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp index cd180130..a978573d 100644 --- a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp +++ b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp @@ -48,32 +48,7 @@ static int findMapObject(QGeoMapObject *o, const QList &list) } return -1; } -namespace { -bool findNodeInStructure(QSGNode *root, QSGNode *item) -{ - if (root == nullptr || item == nullptr) - return false; - if (root == item) - return true; - auto currentChild = root->firstChild(); - // First check the direct child nodes and if not found let's dive deeper - bool bFound = (item == currentChild); - - while (!bFound && currentChild) { - currentChild = currentChild->nextSibling(); - bFound = (item == currentChild); - } - if (!bFound) { - currentChild = root->firstChild(); - while (!bFound && currentChild) { - bFound = findNodeInStructure(currentChild, item); - currentChild = currentChild->nextSibling(); - } - } - return bFound; -} -} bool QGeoMapObjectQSGSupport::createMapObjectImplementation(QGeoMapObject *obj, QGeoMapPrivate *d) { QExplicitlySharedDataPointer pimpl = @@ -182,11 +157,14 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *wind { if (!root) return; - if (!findNodeInStructure(root, m_mapObjectsRootNode)) - m_mapObjectsRootNode = nullptr; + + if (m_mapObjectsRootNode && m_mapObjectsRootNode->parent()) + root->appendChildNode(m_mapObjectsRootNode.get()); + if (!m_mapObjectsRootNode) { - m_mapObjectsRootNode = new QDeclarativePolygonMapItemPrivateOpenGL::RootNode(); - root->appendChildNode(m_mapObjectsRootNode); // PASSING OWNERSHIP! + m_mapObjectsRootNode = std::make_unique(); + root->appendChildNode(m_mapObjectsRootNode.get()); + m_mapObjectsRootNode->setFlag(QSGNode::OwnedByParent, false); } m_mapObjectsRootNode->removeAllChildNodes(); @@ -211,7 +189,7 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *wind MapObject &mo = m_mapObjects[i]; QQSGMapObject *sgo = mo.sgObject; QSGNode *oldNode = mo.qsgNode; - mo.qsgNode = sgo->updateMapObjectNode(oldNode, &mo.visibleNode, m_mapObjectsRootNode, window); + mo.qsgNode = sgo->updateMapObjectNode(oldNode, &mo.visibleNode, m_mapObjectsRootNode.get(), window); if (Q_UNLIKELY(!mo.qsgNode)) { qWarning() << "updateMapObjectNode for "<type() << " returned NULL"; } else if (mo.visibleNode && (mo.visibleNode->visible() != mo.object->visible())) { @@ -227,7 +205,7 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode *root, QQuickWindow *wind QQSGMapObject *sgo = mo.sgObject; QSGNode *oldNode = mo.qsgNode; sgo->updateGeometry(); // or subtree will be blocked - mo.qsgNode = sgo->updateMapObjectNode(oldNode, &mo.visibleNode, m_mapObjectsRootNode, window); + mo.qsgNode = sgo->updateMapObjectNode(oldNode, &mo.visibleNode, m_mapObjectsRootNode.get(), window); if (mo.qsgNode) { if (mo.visibleNode && (mo.visibleNode->visible() != mo.object->visible())) { mo.visibleNode->setVisible(mo.object->visible()); diff --git a/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h b/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h index 1ec966fa..cbbc0969 100644 --- a/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h +++ b/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h @@ -59,6 +59,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE struct Q_LOCATION_PRIVATE_EXPORT MapObject { @@ -85,7 +86,7 @@ public: QList m_pendingMapObjects; QList m_removedMapObjects; QGeoMap *m_map = nullptr; - QDeclarativePolygonMapItemPrivateOpenGL::RootNode *m_mapObjectsRootNode = nullptr; + std::unique_ptr m_mapObjectsRootNode; }; QT_END_NAMESPACE -- cgit v1.2.1