зеркало из https://github.com/mozilla/gecko-dev.git
Bug 752394 - time out localized font family name initialization, reflow if needed after font loader thread completes. r=jfkthame
This commit is contained in:
Родитель
284c6bfc7d
Коммит
cc5a0b94ac
|
@ -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;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче