Bug 752394 - time out localized font family name initialization, reflow if needed after font loader thread completes. r=jfkthame

This commit is contained in:
John Daggett 2014-04-23 14:20:21 +09:00
Родитель 284c6bfc7d
Коммит cc5a0b94ac
2 изменённых файлов: 88 добавлений и 11 удалений

Просмотреть файл

@ -181,37 +181,67 @@ gfxPlatformFontList::GenerateFontListKey(const nsAString& aKeyName, nsAString& a
ToLowerCase(aResult);
}
struct InitOtherNamesData {
InitOtherNamesData(gfxPlatformFontList *aFontList,
TimeStamp aStartTime)
: mFontList(aFontList), mStartTime(aStartTime), mTimedOut(false)
{}
gfxPlatformFontList *mFontList;
TimeStamp mStartTime;
bool mTimedOut;
};
void
gfxPlatformFontList::InitOtherFamilyNames()
{
mOtherFamilyNamesInitialized = true;
if (mOtherFamilyNamesInitialized) {
return;
}
TimeStamp start = TimeStamp::Now();
// iterate over all font families and read in other family names
mFontFamilies.Enumerate(gfxPlatformFontList::InitOtherFamilyNamesProc, this);
InitOtherNamesData otherNamesData(this, start);
mFontFamilies.Enumerate(gfxPlatformFontList::InitOtherFamilyNamesProc,
&otherNamesData);
if (!otherNamesData.mTimedOut) {
mOtherFamilyNamesInitialized = true;
}
TimeStamp end = TimeStamp::Now();
Telemetry::AccumulateTimeDelta(Telemetry::FONTLIST_INITOTHERFAMILYNAMES,
start, end);
#ifdef PR_LOGGING
if (LOG_FONTINIT_ENABLED()) {
TimeDuration elapsed = end - start;
LOG_FONTINIT(("(fontinit) InitOtherFamilyNames took %8.2f ms",
elapsed.ToMilliseconds()));
LOG_FONTINIT(("(fontinit) InitOtherFamilyNames took %8.2f ms %s",
elapsed.ToMilliseconds(),
(otherNamesData.mTimedOut ? "timeout" : "")));
}
#endif
}
#define OTHERNAMES_TIMEOUT 200
PLDHashOperator
gfxPlatformFontList::InitOtherFamilyNamesProc(nsStringHashKey::KeyType aKey,
nsRefPtr<gfxFontFamily>& aFamilyEntry,
void* userArg)
{
gfxPlatformFontList *fc = static_cast<gfxPlatformFontList*>(userArg);
aFamilyEntry->ReadOtherFamilyNames(fc);
InitOtherNamesData *data = static_cast<InitOtherNamesData*>(userArg);
aFamilyEntry->ReadOtherFamilyNames(data->mFontList);
TimeDuration elapsed = TimeStamp::Now() - data->mStartTime;
if (elapsed.ToMilliseconds() > OTHERNAMES_TIMEOUT) {
data->mTimedOut = true;
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
struct ReadFaceNamesData {
ReadFaceNamesData(gfxPlatformFontList *aFontList, TimeStamp aStartTime)
: mFontList(aFontList), mStartTime(aStartTime), mTimedOut(false)
@ -708,6 +738,13 @@ gfxPlatformFontList::FindFamily(const nsAString& aFamily)
InitOtherFamilyNames();
if ((familyEntry = mOtherFamilyNames.GetWeak(key)) != nullptr) {
return CheckFamily(familyEntry);
} else if (!mOtherFamilyNamesInitialized) {
// localized family names load timed out, add name to list of
// names to check after localized names are loaded
if (!mOtherNamesMissed) {
mOtherNamesMissed = new nsTHashtable<nsStringHashKey>(4);
}
mOtherNamesMissed->PutEntry(key);
}
}
@ -930,12 +967,34 @@ gfxPlatformFontList::LookupMissedFaceNamesProc(nsStringHashKey *aKey,
return PL_DHASH_NEXT;
}
struct LookupMissedOtherNamesData {
LookupMissedOtherNamesData(gfxPlatformFontList *aFontList)
: mFontList(aFontList), mFoundName(false) {}
gfxPlatformFontList *mFontList;
bool mFoundName;
};
/*static*/ PLDHashOperator
gfxPlatformFontList::LookupMissedOtherNamesProc(nsStringHashKey *aKey,
void *aUserArg)
{
LookupMissedOtherNamesData *data =
reinterpret_cast<LookupMissedOtherNamesData*>(aUserArg);
if (data->mFontList->FindFamily(aKey->GetKey())) {
data->mFoundName = true;
return PL_DHASH_STOP;
}
return PL_DHASH_NEXT;
}
void
gfxPlatformFontList::CleanupLoader()
{
mFontFamiliesToLoad.Clear();
mNumFamilies = 0;
bool rebuilt = false;
bool rebuilt = false, forceReflow = false;
// if had missed face names that are now available, force reflow all
if (mFaceNamesMissed &&
@ -949,18 +1008,30 @@ gfxPlatformFontList::CleanupLoader()
mFaceNamesMissed = nullptr;
}
if (mOtherNamesMissed) {
LookupMissedOtherNamesData othernamesdata(this);
mOtherNamesMissed->EnumerateEntries(LookupMissedOtherNamesProc,
&othernamesdata);
mOtherNamesMissed = nullptr;
if (othernamesdata.mFoundName) {
forceReflow = true;
ForceGlobalReflow();
}
}
#ifdef PR_LOGGING
if (LOG_FONTINIT_ENABLED() && mFontInfo) {
LOG_FONTINIT(("(fontinit) fontloader load thread took %8.2f ms "
"%d families %d fonts %d cmaps "
"%d facenames %d othernames %s",
"%d facenames %d othernames %s %s",
mLoadTime.ToMilliseconds(),
mFontInfo->mLoadStats.families,
mFontInfo->mLoadStats.fonts,
mFontInfo->mLoadStats.cmaps,
mFontInfo->mLoadStats.facenames,
mFontInfo->mLoadStats.othernames,
(rebuilt ? "(userfont sets rebuilt)" : "")));
(rebuilt ? "(userfont sets rebuilt)" : ""),
(forceReflow ? "(global reflow)" : "")));
}
#endif

Просмотреть файл

@ -225,7 +225,7 @@ protected:
// verifies that a family contains a non-zero font count
gfxFontFamily* CheckFamily(gfxFontFamily *aFamily);
// separate initialization for reading in name tables, since this is expensive
// initialize localized family names
void InitOtherFamilyNames();
static PLDHashOperator
@ -253,6 +253,9 @@ protected:
static PLDHashOperator LookupMissedFaceNamesProc(nsStringHashKey *aKey,
void *aUserArg);
static PLDHashOperator LookupMissedOtherNamesProc(nsStringHashKey *aKey,
void *aUserArg);
// commonly used fonts for which the name table should be loaded at startup
virtual void PreloadNamesList();
@ -314,6 +317,9 @@ protected:
// face names missed when face name loading takes a long time
nsAutoPtr<nsTHashtable<nsStringHashKey> > mFaceNamesMissed;
// localized family names missed when face name loading takes a long time
nsAutoPtr<nsTHashtable<nsStringHashKey> > mOtherNamesMissed;
// cached pref font lists
// maps list of family names ==> array of family entries, one per lang group
nsDataHashtable<nsUint32HashKey, nsTArray<nsRefPtr<gfxFontFamily> > > mPrefFonts;