commit:     6c15f422ef1ae2def29a3b9fc1ad9f3c7b77bad3
Author:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
AuthorDate: Fri Jan  1 16:46:32 2021 +0000
Commit:     Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
CommitDate: Sat Jan  2 01:22:32 2021 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=6c15f422

dev-qt/qtlocation: Fix QSG Render Thread crash

See also: https://bugreports.qt.io/browse/QTBUG-85260

Package-Manager: Portage-3.0.12, Repoman-3.0.2
Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org>

 ...location-5.15.2-qsg-render-thread-crash-1.patch |  66 ++++++++++++
 ...location-5.15.2-qsg-render-thread-crash-2.patch | 115 +++++++++++++++++++++
 dev-qt/qtlocation/qtlocation-5.15.2-r1.ebuild      |  50 +++++++++
 3 files changed, 231 insertions(+)

diff --git 
a/dev-qt/qtlocation/files/qtlocation-5.15.2-qsg-render-thread-crash-1.patch 
b/dev-qt/qtlocation/files/qtlocation-5.15.2-qsg-render-thread-crash-1.patch
new file mode 100644
index 00000000000..d4cd0188d1a
--- /dev/null
+++ b/dev-qt/qtlocation/files/qtlocation-5.15.2-qsg-render-thread-crash-1.patch
@@ -0,0 +1,66 @@
+From 4fe9e0ed027134a833b2243597a2ccd00987b559 Mon Sep 17 00:00:00 2001
+From: Piotr Mikolajczyk <[email protected]>
+Date: Tue, 29 Sep 2020 10:41:23 +0200
+Subject: [PATCH] Fix crash when showing Map QML comp. for 2nd+ time
+
+Crash caused by storing pointer to a node that could be deleted elsewhere
+
+Fixes: QTBUG-85260
+Change-Id: I871123322fac84b8bf91e9bab8ecad08e75c2854
+Reviewed-by: Paolo Angelelli <[email protected]>
+---
+ src/location/labs/qsg/qgeomapobjectqsgsupport.cpp | 29 ++++++++++++++++++++++-
+ 1 file changed, 28 insertions(+), 1 deletion(-)
+
+diff --git a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp 
b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+index 0e1df8f6c..cd1801305 100644
+--- a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
++++ b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+@@ -48,7 +48,32 @@ 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 =
+@@ -157,9 +182,11 @@ void QGeoMapObjectQSGSupport::updateMapObjects(QSGNode 
*root, QQuickWindow *wind
+ {
+     if (!root)
+         return;
++    if (!findNodeInStructure(root, m_mapObjectsRootNode))
++         m_mapObjectsRootNode = nullptr;
+     if (!m_mapObjectsRootNode) {
+         m_mapObjectsRootNode = new 
QDeclarativePolygonMapItemPrivateOpenGL::RootNode();
+-        root->appendChildNode(m_mapObjectsRootNode);
++        root->appendChildNode(m_mapObjectsRootNode); // PASSING OWNERSHIP!
+     }
+ 
+     m_mapObjectsRootNode->removeAllChildNodes();
+-- 
+2.16.3

diff --git 
a/dev-qt/qtlocation/files/qtlocation-5.15.2-qsg-render-thread-crash-2.patch 
b/dev-qt/qtlocation/files/qtlocation-5.15.2-qsg-render-thread-crash-2.patch
new file mode 100644
index 00000000000..4bd70b99abb
--- /dev/null
+++ b/dev-qt/qtlocation/files/qtlocation-5.15.2-qsg-render-thread-crash-2.patch
@@ -0,0 +1,115 @@
+From 861e372b6ad81570d4f496e42fb25a6699b72f2f Mon Sep 17 00:00:00 2001
+From: Piotr Mikolajczyk <[email protected]>
+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 <[email protected]>
+---
+ 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

diff --git a/dev-qt/qtlocation/qtlocation-5.15.2-r1.ebuild 
b/dev-qt/qtlocation/qtlocation-5.15.2-r1.ebuild
new file mode 100644
index 00000000000..7799c0163e0
--- /dev/null
+++ b/dev-qt/qtlocation/qtlocation-5.15.2-r1.ebuild
@@ -0,0 +1,50 @@
+# Copyright 1999-2021 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=7
+
+inherit qt5-build
+
+DESCRIPTION="Location (places, maps, navigation) library for the Qt5 framework"
+
+if [[ ${QT5_BUILD_TYPE} == release ]]; then
+       KEYWORDS="~amd64 ~arm ~arm64 ~x86"
+fi
+
+IUSE=""
+
+RDEPEND="
+       dev-libs/icu:=
+       ~dev-qt/qtcore-${PV}
+       ~dev-qt/qtdeclarative-${PV}
+       ~dev-qt/qtgui-${PV}
+       ~dev-qt/qtnetwork-${PV}
+       ~dev-qt/qtpositioning-${PV}[qml]
+       ~dev-qt/qtsql-${PV}
+       sys-libs/zlib
+"
+DEPEND="${RDEPEND}
+       ~dev-qt/qtconcurrent-${PV}
+"
+
+QT5_TARGET_SUBDIRS=(
+       src/3rdparty/clipper
+       src/3rdparty/poly2tri
+       src/3rdparty/clip2tri
+       src/3rdparty/mapbox-gl-native
+       src/location
+       src/imports/location
+       src/imports/locationlabs
+       src/plugins/geoservices
+)
+
+PATCHES=( "${FILESDIR}"/${P}-qsg-render-thread-crash-{1,2}.patch ) # 
QTBUG-85260
+
+src_configure() {
+       # src/plugins/geoservices requires files that are only generated when
+       # qmake is run in the root directory. Bug 633776.
+       mkdir -p "${QT5_BUILD_DIR}"/src/location || die
+       qt5_qmake "${QT5_BUILD_DIR}"
+       cp "${S}"/src/location/qtlocation-config.pri 
"${QT5_BUILD_DIR}"/src/location || die
+       qt5-build_src_configure
+}

Reply via email to