aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp3
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp8
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h5
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p.cpp8
-rw-r--r--src/quick/scenegraph/qsgdefaultglyphnode_p_p.h1
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp39
6 files changed, 48 insertions, 16 deletions
diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
index 0c0ee5e579..4fd0003e54 100644
--- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
+++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp
@@ -113,8 +113,7 @@ void QSGSoftwareRenderContext::invalidate()
qDeleteAll(m_textures);
m_textures.clear();
- qDeleteAll(m_fontEnginesToClean);
- m_fontEnginesToClean.clear();
+ Q_ASSERT(m_fontEnginesToClean.isEmpty());
qDeleteAll(m_glyphCaches);
m_glyphCaches.clear();
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index be7c934fd7..7668db7a69 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -475,7 +475,13 @@ void QSGRenderContext::invalidateGlyphCaches()
void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine)
{
engine->ref.ref();
- m_fontEnginesToClean << engine;
+ m_fontEnginesToClean[engine]++;
+}
+
+void QSGRenderContext::unregisterFontengineForCleanup(QFontEngine *engine)
+{
+ m_fontEnginesToClean[engine]--;
+ Q_ASSERT(m_fontEnginesToClean.value(engine) >= 0);
}
QRhi *QSGRenderContext::rhi() const
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 299b003716..19585c6f4b 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -166,6 +166,7 @@ public:
virtual int maxTextureSize() const = 0;
+ void unregisterFontengineForCleanup(QFontEngine *engine);
void registerFontengineForCleanup(QFontEngine *engine);
virtual QRhi *rhi() const;
@@ -187,7 +188,9 @@ protected:
QSet<QSGTexture *> m_texturesToDelete;
QHash<QString, QSGDistanceFieldGlyphCache *> m_glyphCaches;
- QSet<QFontEngine *> m_fontEnginesToClean;
+ // References to font engines that are currently in use by native rendering glyph nodes
+ // and which must be kept alive as long as they are used in the render thread.
+ QHash<QFontEngine *, int> m_fontEnginesToClean;
};
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
index e9e6c26d88..f10dbd4bc6 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p.cpp
@@ -322,6 +322,8 @@ QSGTextMaskMaterial::QSGTextMaskMaterial(QSGRenderContext *rc, const QVector4D &
QSGTextMaskMaterial::~QSGTextMaskMaterial()
{
+ if (m_retainedFontEngine != nullptr)
+ m_rc->unregisterFontengineForCleanup(m_retainedFontEngine);
delete m_texture;
}
@@ -385,6 +387,12 @@ void QSGTextMaskMaterial::updateCache(QFontEngine::GlyphFormat glyphFormat)
if (!m_glyphCache || int(m_glyphCache->glyphFormat()) != glyphFormat) {
m_glyphCache = new QSGRhiTextureGlyphCache(m_rc, glyphFormat, glyphCacheTransform, color);
fontEngine->setGlyphCache(cacheKey, m_glyphCache.data());
+ if (m_retainedFontEngine != nullptr)
+ m_rc->unregisterFontengineForCleanup(m_retainedFontEngine);
+
+ // Note: This is reference counted by the render context, so it will stay alive until
+ // we release that reference
+ m_retainedFontEngine = fontEngine;
m_rc->registerFontengineForCleanup(fontEngine);
}
}
diff --git a/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h b/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h
index e77e2715cd..d3b919c275 100644
--- a/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h
+++ b/src/quick/scenegraph/qsgdefaultglyphnode_p_p.h
@@ -69,6 +69,7 @@ private:
QSGPlainTexture *m_texture;
QExplicitlySharedDataPointer<QFontEngineGlyphCache> m_glyphCache;
QRawFont m_font;
+ QFontEngine *m_retainedFontEngine = nullptr;
QRhi *m_rhi;
QVector4D m_color;
QSize m_size;
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index 462196927b..73f4bec27f 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -59,13 +59,29 @@ void QSGDefaultRenderContext::initialize(const QSGRenderContext::InitParams *par
void QSGDefaultRenderContext::invalidateGlyphCaches()
{
- auto it = m_glyphCaches.begin();
- while (it != m_glyphCaches.end()) {
- if (!(*it)->isActive()) {
- delete *it;
- it = m_glyphCaches.erase(it);
- } else {
- ++it;
+ {
+ auto it = m_glyphCaches.begin();
+ while (it != m_glyphCaches.end()) {
+ if (!(*it)->isActive()) {
+ delete *it;
+ it = m_glyphCaches.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
+
+ {
+ auto it = m_fontEnginesToClean.begin();
+ while (it != m_fontEnginesToClean.end()) {
+ if (it.value() == 0) {
+ it.key()->clearGlyphCache(this);
+ if (!it.key()->ref.deref())
+ delete it.key();
+ it = m_fontEnginesToClean.erase(it);
+ } else {
+ ++it;
+ }
}
}
}
@@ -108,11 +124,10 @@ void QSGDefaultRenderContext::invalidate()
// code is only called from QQuickWindow's shutdown which is called
// only when the GUI is blocked, and multiple threads will call it in
// sequence. (see qsgdefaultglyphnode_p.cpp's init())
- for (QSet<QFontEngine *>::const_iterator it = m_fontEnginesToClean.constBegin(),
- end = m_fontEnginesToClean.constEnd(); it != end; ++it) {
- (*it)->clearGlyphCache(this);
- if (!(*it)->ref.deref())
- delete *it;
+ for (auto it = m_fontEnginesToClean.constBegin(); it != m_fontEnginesToClean.constEnd(); ++it) {
+ it.key()->clearGlyphCache(this);
+ if (!it.key()->ref.deref())
+ delete it.key();
}
m_fontEnginesToClean.clear();