diff options
author | Laszlo Agocs <laszlo.agocs@qt.io> | 2024-04-11 13:47:28 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2024-04-13 15:18:03 +0000 |
commit | 269a6cb2d574a31d53371c1991de42e7a6cf5582 (patch) | |
tree | b8a5e8a98367d9c3f75c41139ef5be0165a4c77e | |
parent | d34f33c3fd48850a11dbdc33a9ced030faea69ba (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.6 6.5
Fixes: QTBUG-124281
Change-Id: I01dabc8cc361036ccd735099d42ae321d267ab26
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
(cherry picked from commit a4e0d39a535cb2ca4625eb84bc352b3526d09d66)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/quick/scenegraph/qsgrhishadereffectnode.cpp | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/src/quick/scenegraph/qsgrhishadereffectnode.cpp b/src/quick/scenegraph/qsgrhishadereffectnode.cpp index 8e57236671..f766e74da2 100644 --- a/src/quick/scenegraph/qsgrhishadereffectnode.cpp +++ b/src/quick/scenegraph/qsgrhishadereffectnode.cpp @@ -188,7 +188,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) @@ -208,6 +208,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; @@ -220,7 +228,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); } } |