From f5e02d4128bdd9fef5b0073097050cd20a90bf57 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 10 Dec 2015 14:26:05 +0400 Subject: Avoid needless string comparison by inlining and reordering the condition. Change-Id: I68a91e75071975a4cc26333094db3433afbaeb72 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/gui/text') diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index aae84dc988..f20f574bc6 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -945,9 +945,10 @@ QFontEngine *loadSingleEngine(int script, // If the font data's native stretch matches the requested stretch we need to set stretch to 100 // to avoid the fontengine synthesizing stretch. If they didn't match exactly we need to calculate // the new stretch factor. This only done if not matched by styleName. - bool styleNameMatch = !request.styleName.isEmpty() && request.styleName == style->styleName; - if (!styleNameMatch && style->key.stretch != 0 && request.stretch != 0) + if (style->key.stretch != 0 && request.stretch != 0 + && (request.styleName.isEmpty() || request.styleName != style->styleName)) { def.stretch = (request.stretch * 100 + 50) / style->key.stretch; + } engine = pfdb->fontEngine(def, size->handle); if (engine) { -- cgit v1.2.3 From c3b261f3f0df0795053ecf23b401d06c0cb6d075 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Thu, 10 Dec 2015 14:28:13 +0400 Subject: Deduplicate and clarify the code a bit Makes it clear that the engine for font with no Latin WS support won't be cached as "shared" engine and thus shouldn't be normally expected in the cache, so don't even try to find it there. Change-Id: I9e6275b4919607f4057a193b446825c98932bd23 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/gui/text') diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index f20f574bc6..15882679cc 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -924,7 +924,10 @@ QFontEngine *loadSingleEngine(int script, QFontCache::Key key(def,script); QFontEngine *engine = QFontCache::instance()->findEngine(key); if (!engine) { - if (script != QChar::Script_Common) { + const bool cacheForCommonScript = script != QChar::Script_Common + && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0; + + if (Q_LIKELY(cacheForCommonScript)) { // fast path: check if engine was loaded for another script key.script = QChar::Script_Common; engine = QFontCache::instance()->findEngine(key); @@ -963,7 +966,7 @@ QFontEngine *loadSingleEngine(int script, QFontCache::instance()->insertEngine(key, engine); - if (!engine->symbol && script != QChar::Script_Common && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0) { + if (Q_LIKELY(cacheForCommonScript && !engine->symbol)) { // cache engine for Common script as well key.script = QChar::Script_Common; if (!QFontCache::instance()->findEngine(key)) -- cgit v1.2.3 From c195fde37a533956073000590b3bf66cb91e6bc3 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Mon, 25 Jan 2016 09:50:34 +0400 Subject: QFont*: Optimize by caching the QFontCache::instance() result The QFontCache instance is stored in QThreadStorage and thus calling QFontCache::instance() isn't really cheap; avoid calling it multiple times where possible. Change-Id: I1b7a83089698a06c49dac08b2a3a8e9c3c75a500 Reviewed-by: Friedemann Kleint Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 26 ++++++++++++++++---------- src/gui/text/qfontengine.cpp | 2 +- 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'src/gui/text') diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 15882679cc..c41b3d2c18 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -921,8 +921,10 @@ QFontEngine *loadSingleEngine(int script, QFontDef def = request; def.pixelSize = pixelSize; + QFontCache *fontCache = QFontCache::instance(); + QFontCache::Key key(def,script); - QFontEngine *engine = QFontCache::instance()->findEngine(key); + QFontEngine *engine = fontCache->findEngine(key); if (!engine) { const bool cacheForCommonScript = script != QChar::Script_Common && (family->writingSystems[QFontDatabase::Latin] & QtFontFamily::Supported) != 0; @@ -930,7 +932,7 @@ QFontEngine *loadSingleEngine(int script, if (Q_LIKELY(cacheForCommonScript)) { // fast path: check if engine was loaded for another script key.script = QChar::Script_Common; - engine = QFontCache::instance()->findEngine(key); + engine = fontCache->findEngine(key); key.script = script; if (engine) { Q_ASSERT(engine->type() != QFontEngine::Multi); @@ -940,7 +942,8 @@ QFontEngine *loadSingleEngine(int script, return 0; } - QFontCache::instance()->insertEngine(key, engine); + fontCache->insertEngine(key, engine); + return engine; } } @@ -964,13 +967,13 @@ QFontEngine *loadSingleEngine(int script, return 0; } - QFontCache::instance()->insertEngine(key, engine); + fontCache->insertEngine(key, engine); if (Q_LIKELY(cacheForCommonScript && !engine->symbol)) { // cache engine for Common script as well key.script = QChar::Script_Common; - if (!QFontCache::instance()->findEngine(key)) - QFontCache::instance()->insertEngine(key, engine); + if (!fontCache->findEngine(key)) + fontCache->insertEngine(key, engine); } } } @@ -2639,12 +2642,14 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) } #endif + QFontCache *fontCache = QFontCache::instance(); + // Until we specifically asked not to, try looking for Multi font engine // first, the last '1' indicates that we want Multi font engine instead // of single ones bool multi = !(request.styleStrategy & QFont::NoFontMerging); QFontCache::Key key(request, script, multi ? 1 : 0); - engine = QFontCache::instance()->findEngine(key); + engine = fontCache->findEngine(key); if (engine) { FM_DEBUG("Cache hit level 1"); return engine; @@ -2685,7 +2690,7 @@ QFontEngine *QFontDatabase::findFont(const QFontDef &request, int script) QFontDef def = request; def.family = fallbacks.at(i); QFontCache::Key key(def, script, multi ? 1 : 0); - engine = QFontCache::instance()->findEngine(key); + engine = fontCache->findEngine(key); if (!engine) { QtFontDesc desc; do { @@ -2730,12 +2735,13 @@ void QFontDatabase::load(const QFontPrivate *d, int script) req.stretch = 100; if (!d->engineData) { + QFontCache *fontCache = QFontCache::instance(); // look for the requested font in the engine data cache - d->engineData = QFontCache::instance()->findEngineData(req); + d->engineData = fontCache->findEngineData(req); if (!d->engineData) { // create a new one d->engineData = new QFontEngineData; - QFontCache::instance()->insertEngineData(req, d->engineData); + fontCache->insertEngineData(req, d->engineData); } d->engineData->ref.ref(); } diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index f267b2d147..fc66c4ec4c 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -2290,7 +2290,7 @@ QFontEngine *QFontEngineMulti::createMultiFontEngine(QFontEngine *fe, int script } if (!engine) { engine = QGuiApplicationPrivate::instance()->platformIntegration()->fontDatabase()->fontEngineMulti(fe, QChar::Script(script)); - QFontCache::instance()->insertEngine(key, engine, /* insertMulti */ !faceIsLocal); + fc->insertEngine(key, engine, /* insertMulti */ !faceIsLocal); } Q_ASSERT(engine); return engine; -- cgit v1.2.3 From 5f472cae71e3f1451d4b78fa9b65f7b15b9a1be1 Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Mon, 25 Jan 2016 09:46:55 +0400 Subject: QFontCache: Centralize the engine type safety check We depend on the assumption QFontCache::findEngine(key) for key.multi=1 returns a font engine of type QFontEngine::Multi; guarantee that by checking it in a single place. Change-Id: I287da4fd62deb22fc5520cde5b0505bc44547609 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfont.cpp | 7 +++++++ src/gui/text/qfontdatabase.cpp | 4 +--- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/gui/text') diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index bc9da5b564..2c5a0c74fc 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -2809,6 +2809,10 @@ QFontEngine *QFontCache::findEngine(const Key &key) EngineCache::Iterator it = engineCache.find(key), end = engineCache.end(); if (it == end) return 0; + + Q_ASSERT(it.value().data != Q_NULLPTR); + Q_ASSERT(key.multi == (it.value().data->type() == QFontEngine::Multi)); + // found... update the hitcount and timestamp updateHitCountAndTimeStamp(it.value()); @@ -2829,6 +2833,9 @@ void QFontCache::updateHitCountAndTimeStamp(Engine &value) void QFontCache::insertEngine(const Key &key, QFontEngine *engine, bool insertMulti) { + Q_ASSERT(engine != Q_NULLPTR); + Q_ASSERT(key.multi == (engine->type() == QFontEngine::Multi)); + #ifdef QFONTCACHE_DEBUG FC_DEBUG("QFontCache: inserting new engine %p, refcount %d", engine, engine->ref.load()); if (!insertMulti && engineCache.contains(key)) { diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index c41b3d2c18..333f1d2bb0 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -935,7 +935,6 @@ QFontEngine *loadSingleEngine(int script, engine = fontCache->findEngine(key); key.script = script; if (engine) { - Q_ASSERT(engine->type() != QFontEngine::Multi); // Also check for OpenType tables when using complex scripts if (Q_UNLIKELY(!engine->supportsScript(QChar::Script(script)))) { qWarning(" OpenType support missing for script %d", script); @@ -958,7 +957,6 @@ QFontEngine *loadSingleEngine(int script, engine = pfdb->fontEngine(def, size->handle); if (engine) { - Q_ASSERT(engine->type() != QFontEngine::Multi); // Also check for OpenType tables when using complex scripts if (!engine->supportsScript(QChar::Script(script))) { qWarning(" OpenType support missing for script %d", script); @@ -986,7 +984,7 @@ QFontEngine *loadEngine(int script, const QFontDef &request, QtFontStyle *style, QtFontSize *size) { QFontEngine *engine = loadSingleEngine(script, request, family, foundry, style, size); - Q_ASSERT(!engine || engine->type() != QFontEngine::Multi); + if (engine && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) { QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); QFontEngineMulti *pfMultiEngine = pfdb->fontEngineMulti(engine, QChar::Script(script)); -- cgit v1.2.3 From 3e5719ae7b8f4ff2b1aff6d9134386bcc64e5b4b Mon Sep 17 00:00:00 2001 From: Konstantin Ritt Date: Wed, 27 Jan 2016 04:35:05 +0400 Subject: QFont: Fix possible cache misses due to misprepared cache key Parse the requested family before we're looking/saving into the cache, thus hitting the cached EngineData for: * quoted family names (eg. QFont("'Arial'")) * non-simplified family names (eg. QFont(" Arial ")) * substituted family names (\sa QFont::insertSubstitution()) * explicit fallback list, where possible (eg. QFont("Tahoma, Arial")) This also improves the cache hitting for the font engines in some cases. Change-Id: I18cdc3e8d669cccec961f84e9b27329402e2b7ed Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontdatabase.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/gui/text') diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 333f1d2bb0..d606681e52 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2732,9 +2732,16 @@ void QFontDatabase::load(const QFontPrivate *d, int script) if (req.stretch == 0) req.stretch = 100; + // respect the fallback families that might be passed through the request + const QStringList fallBackFamilies = familyList(req); + if (!d->engineData) { QFontCache *fontCache = QFontCache::instance(); // look for the requested font in the engine data cache + // note: fallBackFamilies are not respected in the EngineData cache key; + // join them with the primary selection family to avoid cache misses + req.family = fallBackFamilies.join(QLatin1Char(',')); + d->engineData = fontCache->findEngineData(req); if (!d->engineData) { // create a new one @@ -2748,25 +2755,18 @@ void QFontDatabase::load(const QFontPrivate *d, int script) if (d->engineData->engines[script]) return; - // Until we specifically asked not to, try looking for Multi font engine - // first, the last '1' indicates that we want Multi font engine instead - // of single ones - bool multi = !(req.styleStrategy & QFont::NoFontMerging); - QFontCache::Key key(req, script, multi ? 1 : 0); + QFontEngine *fe = Q_NULLPTR; - QFontEngine *fe = QFontCache::instance()->findEngine(key); + req.fallBackFamilies = fallBackFamilies; + if (!req.fallBackFamilies.isEmpty()) + req.family = req.fallBackFamilies.takeFirst(); // list of families to try QStringList family_list; if (!req.family.isEmpty()) { - QStringList familiesForRequest = familyList(req); - // Add primary selection - family_list << familiesForRequest.takeFirst(); - - // Fallbacks requested in font request - req.fallBackFamilies = familiesForRequest; + family_list << req.family; // add the default family QString defaultFamily = QGuiApplication::font().family(); -- cgit v1.2.3