summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2018-09-24 09:29:10 +0200
committerPaul Lemire <paul.lemire@kdab.com>2018-09-24 11:54:02 +0000
commite879254613469b1b5290fca31ea69cb6ea407c06 (patch)
tree398b6b8bd1c0fc399051daa9b638b09b406490a8
parente22971073ee10ee891c61a94f934b0b3403cc5a7 (diff)
QText2DEntity: clear glyphrun when scene changes
GlyphRun stores a reference to glyphs and indirectly to a suitable TextureAtlas based on the font needed by the glyphs. Whenever we recompute the glyph because some property has changed we: 1) Store information about the glyph we need 2) Generate a Rendering Entity for the glyph we need 3) Dereference the glyphs we don't need anymore (the old glyph run) Step 3) is performed last as whenever no more glyph reference a TextureAtlas, it gets deleted. If we were to do that first, we could end up in cases where we destroy the atlas and recreate it just after because the new GlyphRun actually uses the same font. TextureAtlases are tied to the lifetime of the scene's root node. However if the scene changes, the previous glyph run wouldn't be released. Since we don't keep a direct relationship between Glyphs and TextureAtlas (we basically do a getOrCreateTextureAtlasForFont and lookup available atlases in the scene), we could actually end up destroying a texture atlas we still need the next time we update our glyph run: When deferencing the old glyphs (whose texture atlas has been destroyed when the scene has changed), we would instead be removing references to the new atlas required by the new nodes (if they share the same font). To fix that, whenever the scene changes, we now clear the glyph run as well. Change-Id: Ibe62e2f6438c6655d2997681117c341302d64799 Task-number: QTBUG-70551 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/extras/text/qtext2dentity.cpp15
-rw-r--r--src/extras/text/qtext2dentity_p.h1
2 files changed, 15 insertions, 1 deletions
diff --git a/src/extras/text/qtext2dentity.cpp b/src/extras/text/qtext2dentity.cpp
index 10939a1e2..ae25e8ecc 100644
--- a/src/extras/text/qtext2dentity.cpp
+++ b/src/extras/text/qtext2dentity.cpp
@@ -92,10 +92,17 @@ void QText2DEntityPrivate::setScene(Qt3DCore::QScene *scene)
// Unref old glyph cache if it exists
if (m_scene != nullptr) {
+ // Ensure we don't keep reference to glyphs
+ // if we are changing the cache
+ if (m_glyphCache != nullptr)
+ clearCurrentGlyphRuns();
+
m_glyphCache = nullptr;
+
QText2DEntityPrivate::CacheEntry &entry = QText2DEntityPrivate::m_glyphCacheInstances[m_scene];
--entry.count;
if (entry.count == 0 && entry.glyphCache != nullptr) {
+
delete entry.glyphCache;
entry.glyphCache = nullptr;
}
@@ -149,7 +156,6 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
// For each distinct texture, we need a separate DistanceFieldTextRenderer,
// for which we need vertex and index data
QHash<Qt3DRender::QAbstractTexture*, RenderData> renderData;
-
const float scale = computeActualScale();
// process glyph runs
@@ -248,6 +254,13 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QVector<QGlyphRun> &runs)
m_currentGlyphRuns = runs;
}
+void QText2DEntityPrivate::clearCurrentGlyphRuns()
+{
+ for (int i = 0; i < m_currentGlyphRuns.size(); i++)
+ m_glyphCache->derefGlyphs(m_currentGlyphRuns[i]);
+ m_currentGlyphRuns.clear();
+}
+
void QText2DEntityPrivate::update()
{
if (m_glyphCache == nullptr)
diff --git a/src/extras/text/qtext2dentity_p.h b/src/extras/text/qtext2dentity_p.h
index 934e2087f..b98c62ce3 100644
--- a/src/extras/text/qtext2dentity_p.h
+++ b/src/extras/text/qtext2dentity_p.h
@@ -104,6 +104,7 @@ public:
float computeActualScale() const;
void setCurrentGlyphRuns(const QVector<QGlyphRun> &runs);
+ void clearCurrentGlyphRuns();
void update();
struct CacheEntry