aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2022-12-08 12:35:57 +0200
committerTim Jenssen <tim.jenssen@qt.io>2022-12-09 08:50:01 +0000
commitd43ec85cb8ce45fd55ae667678017c698c574d08 (patch)
tree27a56e24f7f6fe5df19e6f57df24d58a2b16f680
parent7edb0f9fa5a883babc9a42702bdb993bff956e21 (diff)
QmlDesigner: Work around the issue in QtQuick3D 6.4 geometry caching
QQuick3DGeometry::updateSpatialNode can create QSSGRenderGeometry object with exact same address as a previously created and subsequently deleted QSSGRenderGeometry object (i.e. the memory location is reused). If the previous node was not used for the exact same logical geometry, then you get these artifacts, as QSSGBufferManager uses QSSGRenderGeometry object pointers in QSSGBufferManager::loadRenderMesh function to determine if it needs to reload the geometry and what geometry gets used for each model. The cache still contains data for the deleted node, which is then matched for the new node with same address. This workaround ensures that none of our grid geometries will have the same generation id and thus will never get improperly matched in QSSGBufferManager cache. Task-number: QDS-8516 (cherry picked from commit 636c9524f994f32bd20a4683836ad2acd0c6893f) Change-Id: I017a4ae4a59eef2bb26ade5abf13e8f74f57c4af Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
-rw-r--r--src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp32
-rw-r--r--src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.h3
2 files changed, 35 insertions, 0 deletions
diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp
index d2f04ef38f..6bbe236544 100644
--- a/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp
+++ b/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.cpp
@@ -5,6 +5,10 @@
#include "gridgeometry.h"
+#if QT_VERSION_MAJOR == 6 && QT_VERSION_MINOR == 4
+#include <private/qssgrendergeometry_p.h>
+#endif
+
namespace QmlDesigner {
namespace Internal {
@@ -82,6 +86,34 @@ void GridGeometry::doUpdateGeometry()
QVector3D(vertexPtr[lastIndex][0], vertexPtr[lastIndex][1], 0.0));
}
+#if QT_VERSION_MAJOR == 6 && QT_VERSION_MINOR == 4
+QSSGRenderGraphObject *GridGeometry::updateSpatialNode(QSSGRenderGraphObject *node)
+{
+ if (!node) {
+ markAllDirty();
+ auto geometryNode = new QSSGRenderGeometry();
+ node = geometryNode;
+ emit geometryNodeDirty();
+
+ // This is a work around for the issue of incorrect geometry objects getting matched for
+ // cached mesh data in QSSGBufferManager::loadRenderMesh in QtQuick3D in 6.4 (see QDS-8516).
+ // Each setting of stride value increments the generation id of the geometry node.
+ // By incrementing generation id by different amounts for each grid geometry node we have,
+ // we can ensure QSSGBufferManager cache never matches wrong mesh data.
+ // The cache should be cleared of old objects after they are unused for one frame,
+ // and we use 4 grid objects in total, so max of 8 different generation ids should ensure no
+ // invalid cache matches.
+ static int dirtyCount = 0;
+ if (++dirtyCount > 8)
+ dirtyCount = 0;
+ for (int i = 0; i < dirtyCount; ++i)
+ geometryNode->setStride(stride());
+ }
+
+ return QQuick3DGeometry::updateSpatialNode(node);
+}
+#endif
+
void GridGeometry::fillVertexData(QByteArray &vertexData)
{
const int numSubdivs = 1; // number of subdivision lines (i.e. lines between main grid lines)
diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.h b/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.h
index 376c9d3bf4..6df03a38ef 100644
--- a/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.h
+++ b/src/tools/qml2puppet/qml2puppet/editor3d/gridgeometry.h
@@ -39,6 +39,9 @@ signals:
protected:
void doUpdateGeometry() override;
+#if QT_VERSION_MAJOR == 6 && QT_VERSION_MINOR == 4
+ QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override;
+#endif
private:
void fillVertexData(QByteArray &vertexData);