diff options
author | Paul Lemire <paul.lemire@kdab.com> | 2018-09-24 09:29:10 +0200 |
---|---|---|
committer | Paul Lemire <paul.lemire@kdab.com> | 2018-09-24 11:54:02 +0000 |
commit | e879254613469b1b5290fca31ea69cb6ea407c06 (patch) | |
tree | 398b6b8bd1c0fc399051daa9b638b09b406490a8 | |
parent | e22971073ee10ee891c61a94f934b0b3403cc5a7 (diff) | |
download | qt3d-e879254613469b1b5290fca31ea69cb6ea407c06.tar.gz |
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.cpp | 15 | ||||
-rw-r--r-- | src/extras/text/qtext2dentity_p.h | 1 |
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 |