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); ToLowerCase(aResult);
} }
struct InitOtherNamesData {
InitOtherNamesData(gfxPlatformFontList *aFontList,
TimeStamp aStartTime)
: mFontList(aFontList), mStartTime(aStartTime), mTimedOut(false)
{}
gfxPlatformFontList *mFontList;
TimeStamp mStartTime;
bool mTimedOut;
};
void void
gfxPlatformFontList::InitOtherFamilyNames() gfxPlatformFontList::InitOtherFamilyNames()
{ {
mOtherFamilyNamesInitialized = true; if (mOtherFamilyNamesInitialized) {
return;
}
TimeStamp start = TimeStamp::Now(); TimeStamp start = TimeStamp::Now();
// iterate over all font families and read in other family names // 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(); TimeStamp end = TimeStamp::Now();
Telemetry::AccumulateTimeDelta(Telemetry::FONTLIST_INITOTHERFAMILYNAMES, Telemetry::AccumulateTimeDelta(Telemetry::FONTLIST_INITOTHERFAMILYNAMES,
start, end); start, end);
#ifdef PR_LOGGING #ifdef PR_LOGGING
if (LOG_FONTINIT_ENABLED()) { if (LOG_FONTINIT_ENABLED()) {
TimeDuration elapsed = end - start; TimeDuration elapsed = end - start;
LOG_FONTINIT(("(fontinit) InitOtherFamilyNames took %8.2f ms", LOG_FONTINIT(("(fontinit) InitOtherFamilyNames took %8.2f ms %s",
elapsed.ToMilliseconds())); elapsed.ToMilliseconds(),
(otherNamesData.mTimedOut ? "timeout" : "")));
} }
#endif #endif
} }
#define OTHERNAMES_TIMEOUT 200
PLDHashOperator PLDHashOperator
gfxPlatformFontList::InitOtherFamilyNamesProc(nsStringHashKey::KeyType aKey, gfxPlatformFontList::InitOtherFamilyNamesProc(nsStringHashKey::KeyType aKey,
nsRefPtr<gfxFontFamily>& aFamilyEntry, nsRefPtr<gfxFontFamily>& aFamilyEntry,
void* userArg) void* userArg)
{ {
gfxPlatformFontList *fc = static_cast<gfxPlatformFontList*>(userArg); InitOtherNamesData *data = static_cast<InitOtherNamesData*>(userArg);
aFamilyEntry->ReadOtherFamilyNames(fc);
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; return PL_DHASH_NEXT;
} }
struct ReadFaceNamesData { struct ReadFaceNamesData {
ReadFaceNamesData(gfxPlatformFontList *aFontList, TimeStamp aStartTime) ReadFaceNamesData(gfxPlatformFontList *aFontList, TimeStamp aStartTime)
: mFontList(aFontList), mStartTime(aStartTime), mTimedOut(false) : mFontList(aFontList), mStartTime(aStartTime), mTimedOut(false)
@ -708,6 +738,13 @@ gfxPlatformFontList::FindFamily(const nsAString& aFamily)
InitOtherFamilyNames(); InitOtherFamilyNames();
if ((familyEntry = mOtherFamilyNames.GetWeak(key)) != nullptr) { if ((familyEntry = mOtherFamilyNames.GetWeak(key)) != nullptr) {
return CheckFamily(familyEntry); 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; 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 void
gfxPlatformFontList::CleanupLoader() gfxPlatformFontList::CleanupLoader()
{ {
mFontFamiliesToLoad.Clear(); mFontFamiliesToLoad.Clear();
mNumFamilies = 0; mNumFamilies = 0;
bool rebuilt = false; bool rebuilt = false, forceReflow = false;
// if had missed face names that are now available, force reflow all // if had missed face names that are now available, force reflow all
if (mFaceNamesMissed && if (mFaceNamesMissed &&
@ -949,18 +1008,30 @@ gfxPlatformFontList::CleanupLoader()
mFaceNamesMissed = nullptr; mFaceNamesMissed = nullptr;
} }
if (mOtherNamesMissed) {
LookupMissedOtherNamesData othernamesdata(this);
mOtherNamesMissed->EnumerateEntries(LookupMissedOtherNamesProc,
&othernamesdata);
mOtherNamesMissed = nullptr;
if (othernamesdata.mFoundName) {
forceReflow = true;
ForceGlobalReflow();
}
}
#ifdef PR_LOGGING #ifdef PR_LOGGING
if (LOG_FONTINIT_ENABLED() && mFontInfo) { if (LOG_FONTINIT_ENABLED() && mFontInfo) {
LOG_FONTINIT(("(fontinit) fontloader load thread took %8.2f ms " LOG_FONTINIT(("(fontinit) fontloader load thread took %8.2f ms "
"%d families %d fonts %d cmaps " "%d families %d fonts %d cmaps "
"%d facenames %d othernames %s", "%d facenames %d othernames %s %s",
mLoadTime.ToMilliseconds(), mLoadTime.ToMilliseconds(),
mFontInfo->mLoadStats.families, mFontInfo->mLoadStats.families,
mFontInfo->mLoadStats.fonts, mFontInfo->mLoadStats.fonts,
mFontInfo->mLoadStats.cmaps, mFontInfo->mLoadStats.cmaps,
mFontInfo->mLoadStats.facenames, mFontInfo->mLoadStats.facenames,
mFontInfo->mLoadStats.othernames, mFontInfo->mLoadStats.othernames,
(rebuilt ? "(userfont sets rebuilt)" : ""))); (rebuilt ? "(userfont sets rebuilt)" : ""),
(forceReflow ? "(global reflow)" : "")));
} }
#endif #endif

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

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