diff options
author | Eskil Abrahamsen Blomfeldt <[email protected]> | 2023-12-04 15:20:53 +0100 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <[email protected]> | 2023-12-05 12:50:59 +0100 |
commit | 759ed5de5fa8f764108a7aa6c39cb79f5f3fe4e3 (patch) | |
tree | 7158ca18295805b1f31d024da721cd0b2615e18b | |
parent | 4834aac7c9ae96e67254330dc054beb649785e63 (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.cpp | 14 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgcontext_p.h | 32 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultrendercontext.cpp | 25 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgdefaultrendercontext_p.h | 4 |
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 |