Bug 1584143 - Don't try to reinitialize platform font list from GetDefaultFont() if we're not on the main thread. r=jwatt

This can happen if we need to use gfxFontGroup::GetDefaultFont() during stylo traversal,
but we initially failed to create the required font because the font list is stale.
In this case, use a "last-resort" default font entry as a stopgap until the font list
update is completed.

Differential Revision: https://phabricator.services.mozilla.com/D47637

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jonathan Kew 2019-10-03 09:49:04 +00:00
parent e670b51391
commit 02d0612b29
3 changed files with 37 additions and 4 deletions

View File

@ -386,6 +386,9 @@ bool gfxPlatformFontList::AddWithLegacyFamilyName(const nsACString& aLegacyName,
}
nsresult gfxPlatformFontList::InitFontList() {
// This shouldn't be called from stylo threads!
MOZ_ASSERT(NS_IsMainThread());
mFontlistInitCount++;
if (LOG_FONTINIT_ENABLED()) {
@ -483,6 +486,21 @@ nsresult gfxPlatformFontList::InitFontList() {
ApplyWhitelist();
}
// Set up mDefaultFontEntry as a "last resort" default that we can use
// to avoid crashing if the font list is otherwise unusable.
gfxFontStyle defStyle;
FontFamily fam = GetDefaultFont(&defStyle);
if (fam.mIsShared) {
auto face = fam.mShared->FindFaceForStyle(SharedFontList(), defStyle);
if (!face) {
mDefaultFontEntry = nullptr;
} else {
mDefaultFontEntry = GetOrCreateFontEntry(face, fam.mShared);
}
} else {
mDefaultFontEntry = fam.mUnshared->FindFontForStyle(defStyle);
}
return NS_OK;
}

View File

@ -303,6 +303,10 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
// get the system default font family
FontFamily GetDefaultFont(const gfxFontStyle* aStyle);
// get the "ultimate" default font, for use if the font list is otherwise
// unusable (e.g. in the middle of being updated)
gfxFontEntry* GetDefaultFontEntry() { return mDefaultFontEntry.get(); }
/**
* Look up a font by name on the host platform.
*
@ -797,6 +801,8 @@ class gfxPlatformFontList : public gfxFontInfoLoader {
nsRefPtrHashtable<nsPtrHashKey<mozilla::fontlist::Face>, gfxFontEntry>
mFontEntries;
RefPtr<gfxFontEntry> mDefaultFontEntry;
bool mFontFamilyWhitelistActive;
};

View File

@ -1992,10 +1992,19 @@ gfxFont* gfxFontGroup::GetDefaultFont() {
// If we're a content process, it's possible this is failing because the
// chrome process has just updated the shared font list and we haven't yet
// refreshed our reference to it. If that's the case, update and retry.
uint32_t oldGeneration = pfl->SharedFontList()->GetGeneration();
pfl->UpdateFontList();
if (pfl->SharedFontList()->GetGeneration() != oldGeneration) {
return GetDefaultFont();
// But if we're not on the main thread, we can't do this, so just use
// the platform default font directly.
if (NS_IsMainThread()) {
uint32_t oldGeneration = pfl->SharedFontList()->GetGeneration();
pfl->UpdateFontList();
if (pfl->SharedFontList()->GetGeneration() != oldGeneration) {
return GetDefaultFont();
}
} else {
gfxFontEntry* fe = pfl->GetDefaultFontEntry();
if (fe) {
return fe->FindOrMakeFont(&mStyle);
}
}
}