aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@qt.io>2024-04-11 13:47:28 +0200
committerLaszlo Agocs <laszlo.agocs@qt.io>2024-04-12 14:31:32 +0200
commita4e0d39a535cb2ca4625eb84bc352b3526d09d66 (patch)
tree048ce0527836431fc0336d6656b7c8ea15048828 /src/quick
parentc8f065e2b100556dad23cb96f8c24c554b11f822 (diff)
Raise the dead in QSGRhiShaderMaterialTypeCache
Amends c204b2205c045c2e7dbab442cca2b9f17f5cc9ae Consider what happens when rapidly creating and destroying MultiEffect { } instances: due to the reference counting, the corresponding QSGMaterialType* is moved to the graveyard (emptied typically only on explicit releaseResources() or when exiting), and never reused. However, that reuse is very much desired, because other components in the system, e.g. the scenegraph renderer, uses that type pointer value as keys in its caches. Ideally a ShaderEffect with the exact same shaders should give the same QSGMaterialType* value. Pick-to: 6.7 6.6 6.5 Fixes: QTBUG-124281 Change-Id: I01dabc8cc361036ccd735099d42ae321d267ab26 Reviewed-by: Christian Strømme <christian.stromme@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r--src/quick/scenegraph/qsgrhishadereffectnode.cpp12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
index 9d75b9b228..8d80b13f56 100644
--- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp
+++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp
@@ -187,7 +187,7 @@ struct QSGRhiShaderMaterialTypeCache
QSGMaterialType *type;
};
QHash<Key, MaterialType> m_types;
- QVector<QSGMaterialType *> m_graveyard;
+ QHash<Key, QSGMaterialType *> m_graveyard;
};
size_t qHash(const QSGRhiShaderMaterialTypeCache::Key &key, size_t seed = 0)
@@ -207,6 +207,14 @@ QSGMaterialType *QSGRhiShaderMaterialTypeCache::ref(const QShader &vs, const QSh
return it->type;
}
+ auto reuseIt = m_graveyard.constFind(k);
+ if (reuseIt != m_graveyard.cend()) {
+ QSGMaterialType *t = reuseIt.value();
+ m_types.insert(k, { 1, t });
+ m_graveyard.erase(reuseIt);
+ return t;
+ }
+
QSGMaterialType *t = new QSGMaterialType;
m_types.insert(k, { 1, t });
return t;
@@ -219,7 +227,7 @@ void QSGRhiShaderMaterialTypeCache::unref(const QShader &vs, const QShader &fs)
auto it = m_types.find(k);
if (it != m_types.end()) {
if (!--it->ref) {
- m_graveyard.append(it->type);
+ m_graveyard.insert(k, it->type);
m_types.erase(it);
}
}