summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Lemire <paul.lemire@kdab.com>2023-02-10 09:47:50 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-02-10 17:56:02 +0000
commit4b8b02c20c56f8a0684c056148353e91d9df568a (patch)
treec54479d640d68c64fe7b3fc2b500be20a93d3bc7
parente67866a80c3cab9cf35ec8584671f70308a91b93 (diff)
downloadqt3d-4b8b02c20c56f8a0684c056148353e91d9df568a.tar.gz
QText2DEntity: fix QTextureAtlas parenting that could lead to crashes
We rely on a DistanceFieldFont object to manage QTextureAtlas that hold the glyphs. The DistanceFieldFont/QTextureAtlas are supposed to be parented by the scene root to ensure that a QTextureAtlas lives as long as possible. DistanceFieldFont/QTextureAtlas are stored in a cache global to the scene to minimize the use of resources. When adding text elements, we can reuse atlases since the cache is global to the scene and only destroy an atlas (and remove it from the cache) when we know no more glyphs are referencing it. However we were mistakenly passing a null parenty to DistanceFieldFont instace of the scene root. This resulted on the QTextureAtlas not being parented by the scene root but rather by the first DistanceFieldRenderer to use the atlas. This meants that if the DistanceFieldRenderer were to be destroyed, so would the atlas (yet it would still be referenced by the glyph cache leading to crashes). Change-Id: Id84f6a651b162a4bb3c571b11388fd2429b231de Reviewed-by: Mike Krus <mike.krus@kdab.com> (cherry picked from commit b1a135c547f38db0b2ce6b7bc4c4cccc43ef87d3) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/extras/text/qdistancefieldglyphcache.cpp13
-rw-r--r--src/extras/text/qtext2dentity.cpp3
2 files changed, 9 insertions, 7 deletions
diff --git a/src/extras/text/qdistancefieldglyphcache.cpp b/src/extras/text/qdistancefieldglyphcache.cpp
index dd6640354..3c0ab4d16 100644
--- a/src/extras/text/qdistancefieldglyphcache.cpp
+++ b/src/extras/text/qdistancefieldglyphcache.cpp
@@ -125,6 +125,7 @@ DistanceFieldFont::DistanceFieldFont(const QRawFont &font, bool doubleRes, Qt3DC
, m_doubleGlyphResolution(doubleRes)
, m_parentNode(parent)
{
+ Q_ASSERT(m_parentNode);
}
DistanceFieldFont::~DistanceFieldFont()
@@ -251,7 +252,8 @@ DistanceFieldFont* QDistanceFieldGlyphCache::getOrCreateDistanceFieldFont(const
// create new font cache
// we set the parent node to nullptr, since the parent node of QTextureAtlasses
// will be set when we pass them to QText2DMaterial later
- DistanceFieldFont *dff = new DistanceFieldFont(actualFont, useDoubleRes, nullptr);
+ Q_ASSERT(m_rootNode);
+ DistanceFieldFont *dff = new DistanceFieldFont(actualFont, useDoubleRes, m_rootNode);
m_fonts.insert(key, dff);
return dff;
}
@@ -288,11 +290,10 @@ QDistanceFieldGlyphCache::Glyph refAndGetGlyph(DistanceFieldFont *dff, quint32 g
if (dff) {
const auto entry = dff->refGlyph(glyph);
- if (entry.atlas()) {
- ret.glyphPathBoundingRect = entry.glyphPathBoundingRect();
- ret.texCoords = entry.texCoords();
- ret.texture = entry.atlas();
- }
+ Q_ASSERT(entry.atlas());
+ ret.glyphPathBoundingRect = entry.glyphPathBoundingRect();
+ ret.texCoords = entry.texCoords();
+ ret.texture = entry.atlas();
}
return ret;
diff --git a/src/extras/text/qtext2dentity.cpp b/src/extras/text/qtext2dentity.cpp
index b0c53cb24..83e405a6b 100644
--- a/src/extras/text/qtext2dentity.cpp
+++ b/src/extras/text/qtext2dentity.cpp
@@ -274,8 +274,9 @@ void QText2DEntityPrivate::setCurrentGlyphRuns(const QList<QGlyphRun> &runs)
delete m_renderers.takeLast();
while (m_renderers.size() < renderData.size()) {
- DistanceFieldTextRenderer *renderer = new DistanceFieldTextRenderer(q_func());
+ DistanceFieldTextRenderer *renderer = new DistanceFieldTextRenderer();
renderer->setColor(m_color);
+ renderer->setParent(q_func());
m_renderers << renderer;
}