Bug 1803162 - Avoid repeatedly parsing/expanding the same locale code. r=emilio

No change in behavior; this just makes successive calls to
FindAndAddFamiliesLocked slightly cheaper when the same lang
atom is used repeatedly (which is overwhelmingly the usual
case).

Differential Revision: https://phabricator.services.mozilla.com/D163467
This commit is contained in:
Jonathan Kew 2022-11-30 22:34:39 +00:00
parent 37f5b2a2a7
commit 213fbebd16
2 changed files with 25 additions and 14 deletions

View File

@ -2145,9 +2145,6 @@ bool gfxFcPlatformFontList::FindAndAddFamiliesLocked(
// Because the FcConfigSubstitute call is quite expensive, we cache the
// actual font families found via this process.
nsAutoCString lang;
GetSampleLangForGroup(aLanguage, lang);
ToLowerCase(lang);
nsAutoCString cacheKey;
// For languages that use CJK or Arabic script, we include the language as
@ -2157,13 +2154,21 @@ bool gfxFcPlatformFontList::FindAndAddFamiliesLocked(
// and it gets really expensive to do separate lookups for 300+ distinct lang
// tags e.g. on wikipedia.org, when they all end up mapping to the same font
// list.)
Locale locale;
if (LocaleParser::TryParse(lang, locale).isOk() &&
locale.AddLikelySubtags().isOk()) {
if (UseCustomFontconfigLookupsForLocale(locale)) {
cacheKey = lang;
cacheKey.Append(':');
}
// We remember the most recently checked aLanguage atom so that when the same
// language is used in many successive calls, we can avoid repeating the
// locale code processing every time.
if (aLanguage != mPrevLanguage) {
GetSampleLangForGroup(aLanguage, mSampleLang);
ToLowerCase(mSampleLang);
Locale locale;
mUseCustomLookups = LocaleParser::TryParse(mSampleLang, locale).isOk() &&
locale.AddLikelySubtags().isOk() &&
UseCustomFontconfigLookupsForLocale(locale);
mPrevLanguage = aLanguage;
}
if (mUseCustomLookups) {
cacheKey = mSampleLang;
cacheKey.Append(':');
}
cacheKey.Append(familyName);
@ -2180,8 +2185,8 @@ bool gfxFcPlatformFontList::FindAndAddFamiliesLocked(
const FcChar8* terminator = nullptr;
RefPtr<FcPattern> sentinelSubst = dont_AddRef(FcPatternCreate());
FcPatternAddString(sentinelSubst, FC_FAMILY, kSentinelName);
if (!lang.IsEmpty()) {
FcPatternAddString(sentinelSubst, FC_LANG, ToFcChar8Ptr(lang.get()));
if (!mSampleLang.IsEmpty()) {
FcPatternAddString(sentinelSubst, FC_LANG, ToFcChar8Ptr(mSampleLang.get()));
}
FcConfigSubstitute(nullptr, sentinelSubst, FcMatchPattern);
@ -2209,8 +2214,8 @@ bool gfxFcPlatformFontList::FindAndAddFamiliesLocked(
FcPatternAddString(fontWithSentinel, FC_FAMILY,
ToFcChar8Ptr(familyName.get()));
FcPatternAddString(fontWithSentinel, FC_FAMILY, kSentinelName);
if (!lang.IsEmpty()) {
FcPatternAddString(sentinelSubst, FC_LANG, ToFcChar8Ptr(lang.get()));
if (!mSampleLang.IsEmpty()) {
FcPatternAddString(sentinelSubst, FC_LANG, ToFcChar8Ptr(mSampleLang.get()));
}
FcConfigSubstitute(nullptr, fontWithSentinel, FcMatchPattern);

View File

@ -409,6 +409,12 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList {
private:
#endif
// Cache for most recently used language code in FindAndAddFamiliesLocked,
// and the result of checking whether to use lang-specific lookups.
RefPtr<nsAtom> mPrevLanguage;
nsCString mSampleLang;
bool mUseCustomLookups = false;
// By default, font prefs under Linux are set to simply lookup
// via fontconfig the appropriate font for serif/sans-serif/monospace.
// Rather than check each time a font pref is used, check them all at startup