aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <[email protected]>2023-12-04 15:20:53 +0100
committerEskil Abrahamsen Blomfeldt <[email protected]>2023-12-05 12:50:59 +0100
commit759ed5de5fa8f764108a7aa6c39cb79f5f3fe4e3 (patch)
tree7158ca18295805b1f31d024da721cd0b2615e18b
parent4834aac7c9ae96e67254330dc054beb649785e63 (diff)
Improve hash strategy for font caches
We were using a string key for font lookups instead of creating a proper type for this. This was a quick fix which has grown over time and is inconvenient and slow. Instead we now introduce a FontKey type which uses Qt 6's qHashMulti() for this, also making it automatically adapt to changes in the FaceId as well. Change-Id: I32dfe3b809710e3d76896a5ddef03649bb4da0d5 Reviewed-by: Eskil Abrahamsen Blomfeldt <[email protected]>
-rw-r--r--src/quick/scenegraph/qsgcontext.cpp14
-rw-r--r--src/quick/scenegraph/qsgcontext_p.h32
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext.cpp25
-rw-r--r--src/quick/scenegraph/qsgdefaultrendercontext_p.h4
4 files changed, 48 insertions, 27 deletions
diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp
index 76c521dfd1..01e0707556 100644
--- a/src/quick/scenegraph/qsgcontext.cpp
+++ b/src/quick/scenegraph/qsgcontext.cpp
@@ -292,6 +292,20 @@ private:
QElapsedTimer m_wallTime;
};
+QSGRenderContext::FontKey::FontKey(const QRawFont &font, int quality)
+{
+ QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
+ if (fe != nullptr)
+ faceId = fe->faceId();
+ style = font.style();
+ weight = font.weight();
+ renderTypeQuality = quality;
+ if (faceId.filename.isEmpty()) {
+ familyName = font.familyName();
+ styleName = font.styleName();
+ }
+}
+
/*!
\class QSGContext
diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h
index 6f124c52dd..252dd5f7fd 100644
--- a/src/quick/scenegraph/qsgcontext_p.h
+++ b/src/quick/scenegraph/qsgcontext_p.h
@@ -24,6 +24,7 @@
#include <private/qtquickglobal_p.h>
#include <private/qrawfont_p.h>
+#include <private/qfontengine_p.h>
#include <QtQuick/qsgnode.h>
#include <QtQuick/qsgrendererinterface.h>
@@ -190,19 +191,48 @@ public Q_SLOTS:
void textureFactoryDestroyed(QObject *o);
protected:
+ struct FontKey {
+ FontKey(const QRawFont &font, int renderTypeQuality);
+
+ QFontEngine::FaceId faceId;
+ QFont::Style style;
+ int weight;
+ int renderTypeQuality;
+ QString familyName;
+ QString styleName;
+ };
+ friend bool operator==(const QSGRenderContext::FontKey &f1, const QSGRenderContext::FontKey &f2);
+ friend size_t qHash(const QSGRenderContext::FontKey &f, size_t seed);
+
// Hold m_sg with QPointer in the rare case it gets deleted before us.
QPointer<QSGContext> m_sg;
QMutex m_mutex;
QHash<QObject *, QSGTexture *> m_textures;
QSet<QSGTexture *> m_texturesToDelete;
- QHash<QString, QSGDistanceFieldGlyphCache *> m_glyphCaches;
+ QHash<FontKey, QSGDistanceFieldGlyphCache *> m_glyphCaches;
// 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;
};
+inline bool operator ==(const QSGRenderContext::FontKey &f1, const QSGRenderContext::FontKey &f2)
+{
+ return f1.faceId == f2.faceId
+ && f1.style == f2.style
+ && f1.weight == f2.weight
+ && f1.renderTypeQuality == f2.renderTypeQuality
+ && f1.familyName == f2.familyName
+ && f1.styleName == f2.styleName;
+}
+
+inline size_t qHash(const QSGRenderContext::FontKey &f, size_t seed = 0)
+{
+ return qHashMulti(seed, f.faceId, f.renderTypeQuality, f.familyName, f.styleName, f.style, f.weight);
+}
+
+
QT_END_NAMESPACE
#endif // QSGCONTEXT_H
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
index a81366b401..1b0753e9ae 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp
@@ -227,27 +227,6 @@ QSGTexture *QSGDefaultRenderContext::compressedTextureForFactory(const QSGCompre
return nullptr;
}
-QString QSGDefaultRenderContext::fontKey(const QRawFont &font, int renderTypeQuality)
-{
- QFontEngine *fe = QRawFontPrivate::get(font)->fontEngine;
- if (fe && !fe->faceId().filename.isEmpty()) {
- QByteArray keyName =
- fe->faceId().filename + ' ' + QByteArray::number(fe->faceId().index)
- + (font.style() != QFont::StyleNormal ? QByteArray(" I") : QByteArray())
- + (font.weight() != QFont::Normal ? ' ' + QByteArray::number(font.weight()) : QByteArray())
- + ' ' + QByteArray::number(renderTypeQuality)
- + QByteArray(" DF");
- return QString::fromUtf8(keyName);
- } else {
- return QString::fromLatin1("%1_%2_%3_%4_%5")
- .arg(font.familyName())
- .arg(font.styleName())
- .arg(font.weight())
- .arg(font.style())
- .arg(renderTypeQuality);
- }
-}
-
void QSGDefaultRenderContext::initializeRhiShader(QSGMaterialShader *shader, QShader::Variant shaderVariant)
{
QSGMaterialShaderPrivate::get(shader)->prepare(shaderVariant);
@@ -263,7 +242,7 @@ void QSGDefaultRenderContext::preprocess()
QSGCurveGlyphAtlas *QSGDefaultRenderContext::curveGlyphAtlas(const QRawFont &font)
{
- QString key = fontKey(font, 0);
+ FontKey key = FontKey(font, 0);
QSGCurveGlyphAtlas *atlas = m_curveGlyphAtlases.value(key, nullptr);
if (atlas == nullptr) {
atlas = new QSGCurveGlyphAtlas(font);
@@ -275,7 +254,7 @@ QSGCurveGlyphAtlas *QSGDefaultRenderContext::curveGlyphAtlas(const QRawFont &fon
QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(const QRawFont &font, int renderTypeQuality)
{
- QString key = fontKey(font, renderTypeQuality);
+ FontKey key(font, renderTypeQuality);
QSGDistanceFieldGlyphCache *cache = m_glyphCaches.value(key, 0);
if (!cache && font.isValid()) {
cache = new QSGRhiDistanceFieldGlyphCache(this, font, renderTypeQuality);
diff --git a/src/quick/scenegraph/qsgdefaultrendercontext_p.h b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
index 1743ea35b7..766c628ae0 100644
--- a/src/quick/scenegraph/qsgdefaultrendercontext_p.h
+++ b/src/quick/scenegraph/qsgdefaultrendercontext_p.h
@@ -108,8 +108,6 @@ public:
void resetGlyphCacheResources();
protected:
- static QString fontKey(const QRawFont &font, int renderTypeQuality);
-
InitParams m_initParams;
QRhi *m_rhi;
int m_maxTextureSize;
@@ -120,7 +118,7 @@ protected:
bool m_useDepthBufferFor2D;
QRhiResourceUpdateBatch *m_glyphCacheResourceUpdates;
QSet<QRhiTexture *> m_pendingGlyphCacheTextures;
- QHash<QString, QSGCurveGlyphAtlas *> m_curveGlyphAtlases;
+ QHash<FontKey, QSGCurveGlyphAtlas *> m_curveGlyphAtlases;
};
QT_END_NAMESPACE