author | Jonathan Kew <jkew@mozilla.com> |
Tue, 15 Nov 2016 13:58:29 +0000 | |
changeset 322804 | efe1e3b8cc1714dbdc456b80dfa4578a5192f5b7 |
parent 322803 | 55fe392732ac5758b488728db4c854b1488a2445 |
child 322805 | 0f8126c38179a6475b550ed97f0dfac42c4899b6 |
push id | 83973 |
push user | jkew@mozilla.com |
push date | Wed, 16 Nov 2016 15:38:06 +0000 |
treeherder | mozilla-inbound@efe1e3b8cc17 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mstange |
bugs | 1314932 |
milestone | 53.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -913,17 +913,18 @@ ContentChild::InitXPCOM() bool isConnected; ClipboardCapabilities clipboardCaps; DomainPolicyClone domainPolicy; StructuredCloneData initialData; SendGetXPCOMProcessAttributes(&isOffline, &isConnected, &isLangRTL, &haveBidiKeyboards, &mAvailableDictionaries, - &clipboardCaps, &domainPolicy, &initialData); + &clipboardCaps, &domainPolicy, &initialData, + &mFontFamilies); RecvSetOffline(isOffline); RecvSetConnectivity(isConnected); RecvBidiKeyboardNotify(isLangRTL, haveBidiKeyboards); // Create the CPOW manager as soon as possible. SendPJavaScriptConstructor(); if (domainPolicy.active()) {
--- a/dom/ipc/ContentChild.h +++ b/dom/ipc/ContentChild.h @@ -620,16 +620,23 @@ public: virtual mozilla::ipc::IPCResult RecvBlobURLUnregistration(const nsCString& aURI) override; #if defined(XP_WIN) && defined(ACCESSIBILITY) bool SendGetA11yContentId(); #endif // defined(XP_WIN) && defined(ACCESSIBILITY) + // Get a reference to the font family list passed from the chrome process, + // for use during gfx initialization. + InfallibleTArray<mozilla::dom::FontFamilyListEntry>& + SystemFontFamilyList() { + return mFontFamilies; + } + /** * Helper function for protocols that use the GPU process when available. * Overrides FatalError to just be a warning when communicating with the * GPU process since we don't want to crash the content process when the * GPU process crashes. */ static void FatalErrorIfNotUsingGPUProcess(const char* const aProtocolName, const char* const aErrorMsg, @@ -645,16 +652,21 @@ private: InfallibleTArray<nsAutoPtr<AlertObserver> > mAlertObservers; RefPtr<ConsoleListener> mConsoleListener; nsTHashtable<nsPtrHashKey<nsIObserver>> mIdleObservers; InfallibleTArray<nsString> mAvailableDictionaries; + // Temporary storage for a list of available font families, passed from the + // parent process and used to initialize gfx in the child. Currently used + // only on MacOSX. + InfallibleTArray<mozilla::dom::FontFamilyListEntry> mFontFamilies; + /** * An ID unique to the process containing our corresponding * content parent. * * We expect our content parent to set this ID immediately after opening a * channel to us. */ ContentParentId mID;
--- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -2536,17 +2536,18 @@ ContentParent::RecvGetProcessAttributes( mozilla::ipc::IPCResult ContentParent::RecvGetXPCOMProcessAttributes(bool* aIsOffline, bool* aIsConnected, bool* aIsLangRTL, bool* aHaveBidiKeyboards, InfallibleTArray<nsString>* dictionaries, ClipboardCapabilities* clipboardCaps, DomainPolicyClone* domainPolicy, - StructuredCloneData* aInitialData) + StructuredCloneData* aInitialData, + InfallibleTArray<FontFamilyListEntry>* fontFamilies) { nsCOMPtr<nsIIOService> io(do_GetIOService()); MOZ_ASSERT(io, "No IO service?"); DebugOnly<nsresult> rv = io->GetOffline(aIsOffline); MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting offline?"); rv = io->GetConnectivity(aIsConnected); MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed getting connectivity?"); @@ -2593,16 +2594,19 @@ ContentParent::RecvGetXPCOMProcessAttrib ErrorResult rv; aInitialData->Write(jsapi.cx(), init, rv); if (NS_WARN_IF(rv.Failed())) { rv.SuppressException(); return IPC_FAIL_NO_REASON(this); } } + // This is only implemented (returns a non-empty list) by MacOSX at present. + gfxPlatform::GetPlatform()->GetSystemFontFamilyList(fontFamilies); + return IPC_OK(); } mozilla::jsipc::PJavaScriptParent * ContentParent::AllocPJavaScriptParent() { MOZ_ASSERT(ManagedPJavaScriptParent().IsEmpty()); return nsIContentParent::AllocPJavaScriptParent();
--- a/dom/ipc/ContentParent.h +++ b/dom/ipc/ContentParent.h @@ -667,17 +667,19 @@ private: virtual mozilla::ipc::IPCResult RecvGetXPCOMProcessAttributes(bool* aIsOffline, bool* aIsConnected, bool* aIsLangRTL, bool* aHaveBidiKeyboards, InfallibleTArray<nsString>* dictionaries, ClipboardCapabilities* clipboardCaps, DomainPolicyClone* domainPolicy, - StructuredCloneData* initialData) override; + StructuredCloneData* initialData, + InfallibleTArray<FontFamilyListEntry>* fontFamilies) + override; virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*) override; virtual bool DeallocPRemoteSpellcheckEngineParent(PRemoteSpellcheckEngineParent*) override; virtual PBrowserParent* AllocPBrowserParent(const TabId& aTabId,
--- a/dom/ipc/PContent.ipdl +++ b/dom/ipc/PContent.ipdl @@ -100,27 +100,38 @@ union ChromeRegistryItem ChromePackage; OverrideMapping; SubstitutionMapping; }; namespace mozilla { namespace dom { +// Used on Android/B2G to pass the list of fonts on the device +// to the child process struct FontListEntry { nsString familyName; nsString faceName; nsCString filepath; uint16_t weight; int16_t stretch; uint8_t italic; uint8_t index; bool isHidden; }; +// Used on Mac OS X to pass the list of font families (not faces) +// from chrome to content processes. +// The entryType field distinguishes several types of font family +// record; see gfxMacPlatformFontList.h for values and meaning. +struct FontFamilyListEntry { + nsString familyName; + uint8_t entryType; +}; + struct DeviceStorageFreeSpaceParams { nsString type; nsString storageName; }; struct DeviceStorageUsedSpaceParams { @@ -677,17 +688,18 @@ parent: */ sync GetProcessAttributes() returns (ContentParentId cpId, bool isForBrowser); sync GetXPCOMProcessAttributes() returns (bool isOffline, bool isConnected, bool isLangRTL, bool haveBidiKeyboards, nsString[] dictionaries, ClipboardCapabilities clipboardCaps, DomainPolicyClone domainPolicy, - StructuredCloneData initialData); + StructuredCloneData initialData, + FontFamilyListEntry[] fontFamilies /* used on MacOSX only */); sync CreateChildProcess(IPCTabContext context, ProcessPriority priority, TabId openerTabId) returns (ContentParentId cpId, bool isForBrowser, TabId tabId); sync BridgeToChildProcess(ContentParentId cpId); async CreateGMPService();
--- a/gfx/thebes/gfxMacPlatformFontList.h +++ b/gfx/thebes/gfxMacPlatformFontList.h @@ -103,16 +103,27 @@ public: // lookup the system font for a particular system font type and set // the name and style characteristics void LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID, nsAString& aSystemFontName, gfxFontStyle &aFontStyle, float aDevPixPerCSSPixel); + // Values for the entryType field in FontFamilyListEntry records passed + // from chrome to content process. + enum FontFamilyEntryType { + kStandardFontFamily = 0, // a standard installed font family + kHiddenSystemFontFamily = 1, // hidden system family, not exposed to UI + kTextSizeSystemFontFamily = 2, // name of 'system' font at text sizes + kDisplaySizeSystemFontFamily = 3 // 'system' font at display sizes + }; + void GetSystemFontFamilyList( + InfallibleTArray<mozilla::dom::FontFamilyListEntry>* aList); + protected: virtual gfxFontFamily* GetDefaultFontForPlatform(const gfxFontStyle* aStyle) override; private: friend class gfxPlatformMac; gfxMacPlatformFontList(); @@ -149,16 +160,18 @@ private: // Add the specified family to mSystemFontFamilies or mFontFamilies. // Ideally we'd use NSString* instead of CFStringRef here, but this header // file is included in .cpp files, so we can't use objective C classes here. // But CFStringRef and NSString* are the same thing anyway (they're // toll-free bridged). void AddFamily(CFStringRef aFamily); + void AddFamily(const nsAString& aFamilyName, bool aSystemFont); + #ifdef MOZ_BUNDLED_FONTS void ActivateBundledFonts(); #endif enum { kATSGenerationInitial = -1 };
--- a/gfx/thebes/gfxMacPlatformFontList.mm +++ b/gfx/thebes/gfxMacPlatformFontList.mm @@ -57,28 +57,31 @@ #include "nsDirectoryServiceDefs.h" #include "nsAppDirectoryServiceDefs.h" #include "nsISimpleEnumerator.h" #include "nsCharTraits.h" #include "nsCocoaFeatures.h" #include "nsCocoaUtils.h" #include "gfxFontConstants.h" +#include "mozilla/dom/ContentChild.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Preferences.h" #include "mozilla/Sprintf.h" #include "mozilla/Telemetry.h" #include "mozilla/gfx/2D.h" #include <unistd.h> #include <time.h> #include <dlfcn.h> using namespace mozilla; +using mozilla::dom::FontFamilyListEntry; + // indexes into the NSArray objects that the Cocoa font manager returns // as the available members of a family #define INDEX_FONT_POSTSCRIPT_NAME 0 #define INDEX_FONT_FACE_NAME 1 #define INDEX_FONT_WEIGHT 2 #define INDEX_FONT_TRAITS 3 static const int kAppleMaxWeight = 14; @@ -411,27 +414,32 @@ MacOSFontEntry::AddSizeOfIncludingThis(M } /* gfxMacFontFamily */ #pragma mark- class gfxMacFontFamily : public gfxFontFamily { public: - explicit gfxMacFontFamily(nsAString& aName, double aSizeHint) : + explicit gfxMacFontFamily(const nsAString& aName, double aSizeHint) : gfxFontFamily(aName), mSizeHint(aSizeHint) {} virtual ~gfxMacFontFamily() {} virtual void LocalizedName(nsAString& aLocalizedName); virtual void FindStyleVariations(FontInfoData *aFontInfoData = nullptr); + virtual bool IsSingleFaceFamily() const + { + return false; + } + protected: double mSizeHint; }; void gfxMacFontFamily::LocalizedName(nsAString& aLocalizedName) { nsAutoreleasePool localPool; @@ -575,27 +583,32 @@ gfxMacFontFamily::FindStyleVariations(Fo } /* gfxSingleFaceMacFontFamily */ #pragma mark- class gfxSingleFaceMacFontFamily : public gfxFontFamily { public: - explicit gfxSingleFaceMacFontFamily(nsAString& aName) : + explicit gfxSingleFaceMacFontFamily(const nsAString& aName) : gfxFontFamily(aName) { mFaceNamesInitialized = true; // omit from face name lists } virtual ~gfxSingleFaceMacFontFamily() {} virtual void LocalizedName(nsAString& aLocalizedName); virtual void ReadOtherFamilyNames(gfxPlatformFontList *aPlatformFontList); + + virtual bool IsSingleFaceFamily() const + { + return true; + } }; void gfxSingleFaceMacFontFamily::LocalizedName(nsAString& aLocalizedName) { nsAutoreleasePool localPool; if (!HasOtherFamilyNames()) { @@ -671,73 +684,136 @@ gfxMacPlatformFontList::gfxMacPlatformFo gfxMacPlatformFontList::~gfxMacPlatformFontList() { if (mDefaultFont) { ::CFRelease(mDefaultFont); } } void +gfxMacPlatformFontList::AddFamily(const nsAString& aFamilyName, + bool aSystemFont) +{ + FontFamilyTable& table = + aSystemFont ? mSystemFontFamilies : mFontFamilies; + + double sizeHint = 0.0; + if (aSystemFont && mUseSizeSensitiveSystemFont && + mSystemDisplayFontFamilyName.Equals(aFamilyName)) { + sizeHint = 128.0; + } + + nsAutoString key; + ToLowerCase(aFamilyName, key); + + RefPtr<gfxFontFamily> familyEntry = + new gfxMacFontFamily(aFamilyName, sizeHint); + table.Put(key, familyEntry); + + // check the bad underline blacklist + if (mBadUnderlineFamilyNames.Contains(key)) { + familyEntry->SetBadUnderlineFamily(); + } +} + +void gfxMacPlatformFontList::AddFamily(CFStringRef aFamily) { NSString* family = (NSString*)aFamily; // CTFontManager includes weird internal family names and // LastResort, skip over those if (!family || [family caseInsensitiveCompare:@"LastResort"] == NSOrderedSame) { return; } - bool hiddenSystemFont = [family hasPrefix:@"."]; - - FontFamilyTable& table = - hiddenSystemFont ? mSystemFontFamilies : mFontFamilies; - nsAutoString familyName; nsCocoaUtils::GetStringForNSString(family, familyName); - double sizeHint = 0.0; - if (hiddenSystemFont && mUseSizeSensitiveSystemFont && - mSystemDisplayFontFamilyName.Equals(familyName)) { - sizeHint = 128.0; + bool isHiddenSystemFont = familyName[0] == '.'; + AddFamily(familyName, isHiddenSystemFont); +} + +void +gfxMacPlatformFontList::GetSystemFontFamilyList( + InfallibleTArray<FontFamilyListEntry>* aList) +{ + // Note: We rely on the records for mSystemTextFontFamilyName and + // mSystemDisplayFontFamilyName (if present) being *before* the main + // font list, so that those names are known in the content process + // by the time we add the actual family records to the font list. + aList->AppendElement(FontFamilyListEntry(mSystemTextFontFamilyName, + kTextSizeSystemFontFamily)); + if (mUseSizeSensitiveSystemFont) { + aList->AppendElement(FontFamilyListEntry(mSystemDisplayFontFamilyName, + kDisplaySizeSystemFontFamily)); } - nsAutoString key; - ToLowerCase(familyName, key); - - RefPtr<gfxFontFamily> familyEntry = new gfxMacFontFamily(familyName, sizeHint); - table.Put(key, familyEntry); - - // check the bad underline blacklist - if (mBadUnderlineFamilyNames.Contains(key)) { - familyEntry->SetBadUnderlineFamily(); + // Now collect the lists of available families, both hidden and visible. + for (auto f = mSystemFontFamilies.Iter(); !f.Done(); f.Next()) { + aList->AppendElement(FontFamilyListEntry(f.Data()->Name(), + kHiddenSystemFontFamily)); + } + for (auto f = mFontFamilies.Iter(); !f.Done(); f.Next()) { + auto macFamily = static_cast<gfxMacFontFamily*>(f.Data().get()); + if (macFamily->IsSingleFaceFamily()) { + continue; // skip, this will be recreated separately in the child + } + aList->AppendElement(FontFamilyListEntry(macFamily->Name(), + kStandardFontFamily)); } } nsresult gfxMacPlatformFontList::InitFontListForPlatform() { nsAutoreleasePool localPool; Telemetry::AutoTimer<Telemetry::MAC_INITFONTLIST_TOTAL> timer; // reset system font list mSystemFontFamilies.Clear(); - - // iterate over available families - InitSystemFontNames(); - - CFArrayRef familyNames = CTFontManagerCopyAvailableFontFamilyNames(); - - for (NSString* familyName in (NSArray*)familyNames) { - AddFamily((CFStringRef)familyName); + if (XRE_IsContentProcess()) { + // Content process: use font list passed from the chrome process via + // the GetXPCOMProcessAttributes message, because it's much faster than + // querying Core Text again in the child. + mozilla::dom::ContentChild* cc = + mozilla::dom::ContentChild::GetSingleton(); + for (auto f : cc->SystemFontFamilyList()) { + switch (f.entryType()) { + case kStandardFontFamily: + AddFamily(f.familyName(), false); + break; + case kHiddenSystemFontFamily: + AddFamily(f.familyName(), true); + break; + case kTextSizeSystemFontFamily: + mSystemTextFontFamilyName = f.familyName(); + break; + case kDisplaySizeSystemFontFamily: + mSystemDisplayFontFamilyName = f.familyName(); + mUseSizeSensitiveSystemFont = true; + break; + } + } + // The ContentChild doesn't need the font list any longer. + cc->SystemFontFamilyList().Clear(); } - CFRelease(familyNames); + // If this is the chrome process, or if for some reason we failed to get + // a usable list above, get the available fonts from Core Text. + if (!mFontFamilies.Count()) { + InitSystemFontNames(); + CFArrayRef familyNames = CTFontManagerCopyAvailableFontFamilyNames(); + for (NSString* familyName in (NSArray*)familyNames) { + AddFamily((CFStringRef)familyName); + } + CFRelease(familyNames); + } InitSingleFaceList(); // to avoid full search of font name tables, seed the other names table with localized names from // some of the prefs fonts which are accessed via their localized names. changes in the pref fonts will only cause // a font lookup miss earlier. this is a simple optimization, it's not required for correctness PreloadNamesList();
--- a/gfx/thebes/gfxPlatform.h +++ b/gfx/thebes/gfxPlatform.h @@ -57,16 +57,19 @@ class FeatureState; inline uint32_t BackendTypeBit(BackendType b) { return 1 << uint8_t(b); } } // namespace gfx +namespace dom { +class FontFamilyListEntry; +} } // namespace mozilla #define MOZ_PERFORMANCE_WARNING(module, ...) \ do { \ if (gfxPlatform::PerfWarnings()) { \ printf_stderr("[" module "] " __VA_ARGS__); \ } \ } while (0) @@ -314,16 +317,25 @@ public: * that correspond to the given language group or generic font family * (or both, or neither). */ virtual nsresult GetFontList(nsIAtom *aLangGroup, const nsACString& aGenericFamily, nsTArray<nsString>& aListOfFonts); /** + * Fill aFontFamilies with a list of FontFamilyListEntry records for the + * available fonts on the platform; used to pass the list from chrome to + * content process. Currently implemented only on MacOSX. + */ + virtual void GetSystemFontFamilyList( + InfallibleTArray<mozilla::dom::FontFamilyListEntry>* aFontFamilies) + { } + + /** * Rebuilds the any cached system font lists */ virtual nsresult UpdateFontList(); /** * Create the platform font-list object (gfxPlatformFontList concrete subclass). * This function is responsible to create the appropriate subclass of * gfxPlatformFontList *and* to call its InitFontList() method.
--- a/gfx/thebes/gfxPlatformMac.cpp +++ b/gfx/thebes/gfxPlatformMac.cpp @@ -25,16 +25,18 @@ #include <CoreVideo/CoreVideo.h> #include "mozilla/layers/CompositorBridgeParent.h" #include "VsyncSource.h" using namespace mozilla; using namespace mozilla::gfx; +using mozilla::dom::FontFamilyListEntry; + // cribbed from CTFontManager.h enum { kAutoActivationDisabled = 1 }; typedef uint32_t AutoActivationSetting; // bug 567552 - disable auto-activation of fonts @@ -105,16 +107,24 @@ gfxPlatformMac::CreatePlatformFontList() gfxPlatformFontList* list = new gfxMacPlatformFontList(); if (NS_SUCCEEDED(list->InitFontList())) { return list; } gfxPlatformFontList::Shutdown(); return nullptr; } +void +gfxPlatformMac::GetSystemFontFamilyList( + InfallibleTArray<FontFamilyListEntry>* aFontFamilies) +{ + gfxMacPlatformFontList::PlatformFontList()-> + GetSystemFontFamilyList(aFontFamilies); +} + already_AddRefed<gfxASurface> gfxPlatformMac::CreateOffscreenSurface(const IntSize& aSize, gfxImageFormat aFormat) { if (!Factory::AllowedSurfaceSize(aSize)) { return nullptr; }
--- a/gfx/thebes/gfxPlatformMac.h +++ b/gfx/thebes/gfxPlatformMac.h @@ -37,16 +37,20 @@ public: CreateFontGroup(const mozilla::FontFamilyList& aFontFamilyList, const gfxFontStyle *aStyle, gfxTextPerfMetrics* aTextPerf, gfxUserFontSet *aUserFontSet, gfxFloat aDevToCssSize) override; virtual gfxPlatformFontList* CreatePlatformFontList() override; + void + GetSystemFontFamilyList(InfallibleTArray<mozilla::dom::FontFamilyListEntry>* + aFontFamilies) override; + bool IsFontFormatSupported(nsIURI *aFontURI, uint32_t aFormatFlags) override; virtual void GetCommonFallbackFonts(uint32_t aCh, uint32_t aNextCh, Script aRunScript, nsTArray<const char*>& aFontList) override; // lookup the system font for a particular system font type and set // the name and style characteristics