summaryrefslogtreecommitdiff
blob: 4bd70b99abbf81b0315b727136d057cdaa8c9fe6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
From 861e372b6ad81570d4f496e42fb25a6699b72f2f Mon Sep 17 00:00:00 2001
From: Piotr Mikolajczyk <piotr.mikolajczyk@qt.io>
Date: Tue, 3 Nov 2020 11:43:22 +0100
Subject: [PATCH] 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 <andy.shaw@qt.io>
---
 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 cd1801305..a978573d6 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<MapObject> &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<QGeoMapObjectPrivate> 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<QDeclarativePolygonMapItemPrivateOpenGL::RootNode>();
+        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 "<<mo.object->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 1ec966fa9..cbbc09691 100644
--- a/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h
+++ b/src/location/labs/qsg/qgeomapobjectqsgsupport_p.h
@@ -59,6 +59,7 @@
 #include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
 #include <QtLocation/private/qdeclarativepolygonmapitem_p_p.h>
 #include <QtCore/qpointer.h>
+#include <memory>
 
 QT_BEGIN_NAMESPACE
 struct Q_LOCATION_PRIVATE_EXPORT MapObject {
@@ -85,7 +86,7 @@ public:
     QList<MapObject> m_pendingMapObjects;
     QList<MapObject> m_removedMapObjects;
     QGeoMap *m_map = nullptr;
-    QDeclarativePolygonMapItemPrivateOpenGL::RootNode *m_mapObjectsRootNode = nullptr;
+    std::unique_ptr<QDeclarativePolygonMapItemPrivateOpenGL::RootNode> m_mapObjectsRootNode;
 };
 
 QT_END_NAMESPACE
-- 
2.16.3