diff options
Diffstat (limited to 'gfx/thebes')
28 files changed, 706 insertions, 280 deletions
diff --git a/gfx/thebes/CoreTextFontList.cpp b/gfx/thebes/CoreTextFontList.cpp index 0c8c179e8e..e83435b638 100644 --- a/gfx/thebes/CoreTextFontList.cpp +++ b/gfx/thebes/CoreTextFontList.cpp @@ -35,6 +35,15 @@ using namespace mozilla; using namespace mozilla::gfx; +#ifdef MOZ_WIDGET_COCOA +// Building with newer macOS SDKs can cause a bunch of font-family names to be +// hidden from the Core Text API we use to enumerate available fonts. Because +// some content still benefits from having these names recognized, we forcibly +// include them in the list. Some day we might want to drop support for these. +# define USE_DEPRECATED_FONT_FAMILY_NAMES 1 +#endif + +#if USE_DEPRECATED_FONT_FAMILY_NAMES // List generated by diffing the arrays returned by // CTFontManagerCopyAvailableFontFamilyNames() when built with // MACOSX_DEPLOYMENT_TARGET=10.12 vs 11.0, to identify the font family names @@ -198,6 +207,7 @@ constexpr nsLiteralCString kDeprecatedFontFamilies[] = { "Superclarendon"_ns, "Times"_ns, }; +#endif // USE_DEPRECATED_FONT_FAMILY_NAMES static void GetStringForCFString(CFStringRef aSrc, nsAString& aDest) { auto len = CFStringGetLength(aSrc); @@ -497,7 +507,7 @@ CGFontRef CTFontEntry::CreateOrCopyFontRef() { return mFontRef; } - CrashReporter::AutoAnnotateCrashReport autoFontName( + CrashReporter::AutoRecordAnnotation autoFontName( CrashReporter::Annotation::FontName, mName); // Create a new CGFont; caller will own the only reference to it. @@ -666,7 +676,7 @@ bool CTFontEntry::SupportsOpenTypeFeature(Script aScript, return mHasAATSmallCaps; } - CrashReporter::AutoAnnotateCrashReport autoFontName( + CrashReporter::AutoRecordAnnotation autoFontName( CrashReporter::Annotation::FontName, FamilyName()); AutoCFRelease<CTFontRef> ctFont = @@ -907,6 +917,47 @@ void CTFontFamily::FindStyleVariationsLocked(FontInfoData* aFontInfoData) { AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("CTFontFamily::FindStyleVariations", LAYOUT, mName); + if (mForSystemFont) { + MOZ_ASSERT(gfxPlatform::HasVariationFontSupport()); + + auto addToFamily = [&](CTFontRef aFont) MOZ_REQUIRES(mLock) { + AutoCFRelease<CFStringRef> psName = CTFontCopyPostScriptName(aFont); + nsAutoString nameUTF16; + nsAutoCString nameUTF8; + GetStringForCFString(psName, nameUTF16); + CopyUTF16toUTF8(nameUTF16, nameUTF8); + + auto* fe = + new CTFontEntry(nameUTF8, WeightRange(FontWeight::NORMAL), true, 0.0); + + // Set the appropriate style, assuming it may not have a variation range. + CTFontSymbolicTraits traits = CTFontGetSymbolicTraits(aFont); + fe->mStyleRange = SlantStyleRange((traits & kCTFontTraitItalic) + ? FontSlantStyle::ITALIC + : FontSlantStyle::NORMAL); + + // Set up weight (and width, if present) ranges. + fe->SetupVariationRanges(); + AddFontEntryLocked(fe); + }; + + addToFamily(mForSystemFont); + + // See if there is a corresponding italic face, and add it to the family. + AutoCFRelease<CTFontRef> italicFont = CTFontCreateCopyWithSymbolicTraits( + mForSystemFont, 0.0, nullptr, kCTFontTraitItalic, kCTFontTraitItalic); + if (italicFont != mForSystemFont) { + addToFamily(italicFont); + } + + CFRelease(mForSystemFont); + mForSystemFont = nullptr; + + SetHasStyles(true); + + return; + } + struct Context { CTFontFamily* family; const void* prevValue = nullptr; @@ -1134,11 +1185,13 @@ nsresult CoreTextFontList::InitFontListForPlatform() { (CFStringRef)CFArrayGetValueAtIndex(familyNames, i); AddFamily(familyName); } +#if USE_DEPRECATED_FONT_FAMILY_NAMES for (const auto& name : kDeprecatedFontFamilies) { if (DeprecatedFamilyIsAvailable(name)) { AddFamily(name, GetVisibilityForFamily(name)); } } +#endif } else { // Content process: use font list passed from the chrome process via // the GetXPCOMProcessAttributes message, because it's much faster than @@ -1196,8 +1249,11 @@ void CoreTextFontList::InitSharedFontListForPlatform() { AutoCFRelease<CFArrayRef> familyNames = CTFontManagerCopyAvailableFontFamilyNames(); nsTArray<fontlist::Family::InitData> families; - families.SetCapacity(CFArrayGetCount(familyNames) + - ArrayLength(kDeprecatedFontFamilies)); + families.SetCapacity(CFArrayGetCount(familyNames) +#if USE_DEPRECATED_FONT_FAMILY_NAMES + + ArrayLength(kDeprecatedFontFamilies) +#endif + ); for (CFIndex i = 0; i < CFArrayGetCount(familyNames); ++i) { nsAutoString name16; CFStringRef familyName = @@ -1209,6 +1265,7 @@ void CoreTextFontList::InitSharedFontListForPlatform() { families.AppendElement(fontlist::Family::InitData( key, name, fontlist::Family::kNoIndex, GetVisibilityForFamily(name))); } +#if USE_DEPRECATED_FONT_FAMILY_NAMES for (const nsACString& name : kDeprecatedFontFamilies) { if (DeprecatedFamilyIsAvailable(name)) { nsAutoCString key; @@ -1218,6 +1275,7 @@ void CoreTextFontList::InitSharedFontListForPlatform() { GetVisibilityForFamily(name))); } } +#endif SharedFontList()->SetFamilyNames(families); InitAliasesForSingleFaceList(); GetPrefsAndStartLoader(); @@ -1367,7 +1425,7 @@ gfxFontEntry* CoreTextFontList::LookupLocalFont( AutoLock lock(mLock); - CrashReporter::AutoAnnotateCrashReport autoFontName( + CrashReporter::AutoRecordAnnotation autoFontName( CrashReporter::Annotation::FontName, aFontName); AutoCFRelease<CFStringRef> faceName = CreateCFStringForString(aFontName); @@ -1444,7 +1502,7 @@ gfxFontEntry* CoreTextFontList::MakePlatformFont(const nsACString& aFontName, return nullptr; } - CrashReporter::AutoAnnotateCrashReport autoFontName( + CrashReporter::AutoRecordAnnotation autoFontName( CrashReporter::Annotation::FontName, aFontName); AutoCFRelease<CGDataProviderRef> provider = @@ -1504,7 +1562,7 @@ class CTFontInfo final : public FontInfoData { }; void CTFontInfo::LoadFontFamilyData(const nsACString& aFamilyName) { - CrashReporter::AutoAnnotateCrashReport autoFontName( + CrashReporter::AutoRecordAnnotation autoFontName( CrashReporter::Annotation::FontName, aFamilyName); // Prevent this from running concurrently with CGFont operations on the main // thread, because the macOS font cache is fragile with concurrent access. @@ -1726,7 +1784,7 @@ void CoreTextFontList::GetFacesInitDataForFamily( const fontlist::Family* aFamily, nsTArray<fontlist::Face::InitData>& aFaces, bool aLoadCmaps) const { auto name = aFamily->Key().AsString(SharedFontList()); - CrashReporter::AutoAnnotateCrashReport autoFontName( + CrashReporter::AutoRecordAnnotation autoFontName( CrashReporter::Annotation::FontName, name); struct Context { @@ -1805,6 +1863,56 @@ void CoreTextFontList::ReadFaceNamesForFamily( } } +static CFStringRef CopyRealFamilyName(CTFontRef aFont) { + AutoCFRelease<CFStringRef> psName = CTFontCopyPostScriptName(aFont); + AutoCFRelease<CGFontRef> cgFont = + CGFontCreateWithFontName(CFStringRef(psName)); + if (!cgFont) { + return CTFontCopyFamilyName(aFont); + } + AutoCFRelease<CTFontRef> ctFont = + CTFontCreateWithGraphicsFont(cgFont, 0.0, nullptr, nullptr); + if (!ctFont) { + return CTFontCopyFamilyName(aFont); + } + return CTFontCopyFamilyName(ctFont); +} + +void CoreTextFontList::InitSystemFontNames() { + // text font family + AutoCFRelease<CTFontRef> font = CTFontCreateUIFontForLanguage( + kCTFontUIFontSystem, 0.0, nullptr); // TODO: language + AutoCFRelease<CFStringRef> name = CopyRealFamilyName(font); + + nsAutoString familyName; + GetStringForCFString(name, familyName); + CopyUTF16toUTF8(familyName, mSystemFontFamilyName); + + // We store an in-process gfxFontFamily for the system font even if using the + // shared fontlist to manage "normal" fonts, because the hidden system fonts + // may be excluded from the font list altogether. This family will be + // populated based on the given NSFont. + RefPtr<gfxFontFamily> fam = new CTFontFamily(mSystemFontFamilyName, font); + if (fam) { + nsAutoCString key; + GenerateFontListKey(mSystemFontFamilyName, key); + mFontFamilies.InsertOrUpdate(key, std::move(fam)); + } +} + +FontFamily CoreTextFontList::GetDefaultFontForPlatform( + nsPresContext* aPresContext, const gfxFontStyle* aStyle, + nsAtom* aLanguage) { + AutoCFRelease<CTFontRef> font = CTFontCreateUIFontForLanguage( + kCTFontUIFontUser, 0.0, nullptr); // TODO: language + AutoCFRelease<CFStringRef> name = CTFontCopyFamilyName(font); + + nsAutoString familyName; + GetStringForCFString(name, familyName); + + return FindFamily(aPresContext, NS_ConvertUTF16toUTF8(familyName)); +} + #ifdef MOZ_BUNDLED_FONTS void CoreTextFontList::ActivateBundledFonts() { nsCOMPtr<nsIFile> localDir; diff --git a/gfx/thebes/CoreTextFontList.h b/gfx/thebes/CoreTextFontList.h index 3aa7b75247..97052b36f6 100644 --- a/gfx/thebes/CoreTextFontList.h +++ b/gfx/thebes/CoreTextFontList.h @@ -118,6 +118,15 @@ class CTFontFamily : public gfxFontFamily { CTFontFamily(const nsACString& aName, FontVisibility aVisibility) : gfxFontFamily(aName, aVisibility) {} + CTFontFamily(const nsACString& aName, CTFontRef aSystemFont) + : gfxFontFamily(aName, FontVisibility::Unknown), + mForSystemFont(aSystemFont) { + // I don't think the system font instance is at much risk of being deleted, + // but to be on the safe side let's retain a reference until we're finished + // using it for lazy initialization. + CFRetain(mForSystemFont); + } + virtual ~CTFontFamily() = default; void LocalizedName(nsACString& aLocalizedName) override; @@ -127,6 +136,15 @@ class CTFontFamily : public gfxFontFamily { protected: void AddFace(CTFontDescriptorRef aFace) MOZ_REQUIRES(mLock); + + // If non-null, this is a family representing the system UI font, and should + // use the given CTFontRef as the basis for initialization as the normal + // font-manager APIs based on family name won't handle it. + CTFontRef mForSystemFont = nullptr; +}; + +class gfxMacFontFamily final : public CTFontFamily { + public: }; class CoreTextFontList : public gfxPlatformFontList { @@ -179,7 +197,13 @@ class CoreTextFontList : public gfxPlatformFontList { void PreloadNamesList() MOZ_REQUIRES(mLock); // initialize system fonts - virtual void InitSystemFontNames() = 0; + void InitSystemFontNames() MOZ_REQUIRES(mLock); + + // look up a default font to use as fallback + FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext, + const gfxFontStyle* aStyle, + nsAtom* aLanguage = nullptr) + MOZ_REQUIRES(mLock) override; // Hooks for the macOS-specific "single face family" hack (Osaka-mono). virtual void InitSingleFaceList() {} diff --git a/gfx/thebes/DeviceManagerDx.cpp b/gfx/thebes/DeviceManagerDx.cpp index 18c5cea7db..ba473e0d1e 100644 --- a/gfx/thebes/DeviceManagerDx.cpp +++ b/gfx/thebes/DeviceManagerDx.cpp @@ -206,6 +206,129 @@ bool DeviceManagerDx::GetOutputFromMonitor(HMONITOR monitor, return false; } +void DeviceManagerDx::PostUpdateMonitorInfo() { + MOZ_ASSERT(XRE_IsGPUProcess()); + MOZ_ASSERT(NS_IsMainThread()); + + MutexAutoLock lock(mDeviceLock); + // Reduce frequency of UpdateMonitorInfo() call. + if (mUpdateMonitorInfoRunnable) { + return; + } + + auto* holder = CompositorThreadHolder::GetSingleton(); + if (!holder) { + return; + } + + mUpdateMonitorInfoRunnable = NS_NewRunnableFunction( + "DeviceManagerDx::PostUpdateMonitorInfo::Runnable", []() -> void { + auto* dm = gfx::DeviceManagerDx::Get(); + if (dm) { + dm->UpdateMonitorInfo(); + } + }); + + const uint32_t kDelayMS = 100; + RefPtr<Runnable> runnable = mUpdateMonitorInfoRunnable; + holder->GetCompositorThread()->DelayedDispatch(runnable.forget(), kDelayMS); +} + +void DeviceManagerDx::UpdateMonitorInfo() { + bool systemHdrEnabled = false; + + for (const auto& desc : GetOutputDescs()) { + if (desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) { + systemHdrEnabled = true; + } + } + { + MutexAutoLock lock(mDeviceLock); + mSystemHdrEnabled = Some(systemHdrEnabled); + mUpdateMonitorInfoRunnable = nullptr; + } +} + +std::vector<DXGI_OUTPUT_DESC1> DeviceManagerDx::GetOutputDescs() { + std::vector<DXGI_OUTPUT_DESC1> outputDescs; + + nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll")); + decltype(CreateDXGIFactory1)* createDXGIFactory1 = + (decltype(CreateDXGIFactory1)*)GetProcAddress(dxgiModule, + "CreateDXGIFactory1"); + if (!createDXGIFactory1) { + return outputDescs; + } + + RefPtr<IDXGIFactory1> dxgiFactory; + HRESULT hr = + createDXGIFactory1(__uuidof(IDXGIFactory1), getter_AddRefs(dxgiFactory)); + if (FAILED(hr)) { + gfxCriticalNoteOnce << "Failed to create DXGI factory: " << gfx::hexa(hr); + return outputDescs; + } + + for (UINT adapterIndex = 0;; adapterIndex++) { + RefPtr<IDXGIAdapter> adapter; + hr = dxgiFactory->EnumAdapters(adapterIndex, getter_AddRefs(adapter)); + if (hr == DXGI_ERROR_NOT_FOUND) { + break; + } + if (FAILED(hr)) { + MOZ_ASSERT_UNREACHABLE("unexpected to be called"); + gfxCriticalNoteOnce << "Failed to enumerate DXGI adapter: " + << gfx::hexa(hr); + break; + } + + for (UINT outputIndex = 0;; ++outputIndex) { + RefPtr<IDXGIOutput> output; + hr = adapter->EnumOutputs(outputIndex, getter_AddRefs(output)); + if (hr == DXGI_ERROR_NOT_FOUND) { + break; + } + if (FAILED(hr)) { + MOZ_ASSERT_UNREACHABLE("unexpected to be called"); + gfxCriticalNoteOnce << "Failed to enumulate DXGI output: " + << gfx::hexa(hr); + break; + } + + RefPtr<IDXGIOutput6> output6; + hr = output->QueryInterface(__uuidof(IDXGIOutput6), + getter_AddRefs(output6)); + if (FAILED(hr)) { + continue; + } + + DXGI_OUTPUT_DESC1 desc; + if (FAILED(output6->GetDesc1(&desc))) { + MOZ_ASSERT_UNREACHABLE("unexpected to be called"); + gfxCriticalNoteOnce << "Failed to get DXGI output descriptor"; + continue; + } + + outputDescs.push_back(std::move(desc)); + } + } + + return outputDescs; +} + +bool DeviceManagerDx::SystemHDREnabled() { + { + MutexAutoLock lock(mDeviceLock); + if (mSystemHdrEnabled.isSome()) { + return mSystemHdrEnabled.ref(); + } + } + + UpdateMonitorInfo(); + + MutexAutoLock lock(mDeviceLock); + return mSystemHdrEnabled.ref(); +} + void DeviceManagerDx::CheckHardwareStretchingSupport(HwStretchingSupport& aRv) { RefPtr<IDXGIAdapter> adapter = GetDXGIAdapter(); diff --git a/gfx/thebes/DeviceManagerDx.h b/gfx/thebes/DeviceManagerDx.h index 9d127af358..c6860c7ffa 100644 --- a/gfx/thebes/DeviceManagerDx.h +++ b/gfx/thebes/DeviceManagerDx.h @@ -6,6 +6,8 @@ #ifndef mozilla_gfx_thebes_DeviceManagerDx_h #define mozilla_gfx_thebes_DeviceManagerDx_h +#include <vector> + #include "gfxPlatform.h" #include "gfxTelemetry.h" #include "gfxTypes.h" @@ -88,6 +90,9 @@ class DeviceManagerDx final { // 'monitor'; returns false if not found or some error occurred. bool GetOutputFromMonitor(HMONITOR monitor, RefPtr<IDXGIOutput>* aOutOutput); + void PostUpdateMonitorInfo(); + bool SystemHDREnabled(); + // Check if the current adapter supports hardware stretching void CheckHardwareStretchingSupport(HwStretchingSupport& aRv); @@ -172,6 +177,9 @@ class DeviceManagerDx final { bool GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason) MOZ_REQUIRES(mDeviceLock); + void UpdateMonitorInfo(); + std::vector<DXGI_OUTPUT_DESC1> GetOutputDescs(); + private: static StaticAutoPtr<DeviceManagerDx> sInstance; @@ -198,6 +206,8 @@ class DeviceManagerDx final { bool mCompositorDeviceSupportsVideo MOZ_GUARDED_BY(mDeviceLock); Maybe<D3D11DeviceStatus> mDeviceStatus MOZ_GUARDED_BY(mDeviceLock); Maybe<DeviceResetReason> mDeviceResetReason MOZ_GUARDED_BY(mDeviceLock); + RefPtr<Runnable> mUpdateMonitorInfoRunnable MOZ_GUARDED_BY(mDeviceLock); + Maybe<bool> mSystemHdrEnabled MOZ_GUARDED_BY(mDeviceLock); nsModuleHandle mDirectDrawDLL; RefPtr<IDirectDraw7> mDirectDraw; diff --git a/gfx/thebes/IOSPlatformFontList.h b/gfx/thebes/IOSPlatformFontList.h new file mode 100644 index 0000000000..733939b755 --- /dev/null +++ b/gfx/thebes/IOSPlatformFontList.h @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef IOSPlatformFontList_H_ +#define IOSPlatformFontList_H_ + +#include <CoreFoundation/CoreFoundation.h> + +#include "CoreTextFontList.h" + +class IOSPlatformFontList final : public CoreTextFontList { + public: + static IOSPlatformFontList* PlatformFontList() { + return static_cast<IOSPlatformFontList*>( + gfxPlatformFontList::PlatformFontList()); + } + + static void LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID, + nsACString& aSystemFontName, + gfxFontStyle& aFontStyle); + + protected: + nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists() + override; + + private: + friend class gfxPlatformMac; + + // Only the friend class gfxPlatformMac constructs this. + IOSPlatformFontList(); + virtual ~IOSPlatformFontList(); +}; + +#endif /* IOSPlatformFontList_H_ */ diff --git a/gfx/thebes/IOSPlatformFontList.mm b/gfx/thebes/IOSPlatformFontList.mm new file mode 100644 index 0000000000..e42d209fa3 --- /dev/null +++ b/gfx/thebes/IOSPlatformFontList.mm @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#import <UIKit/UIKit.h> +#include "IOSPlatformFontList.h" + +IOSPlatformFontList::IOSPlatformFontList() : CoreTextFontList() {} + +IOSPlatformFontList::~IOSPlatformFontList() {} + +void IOSPlatformFontList::LookupSystemFont( + mozilla::LookAndFeel::FontID aSystemFontID, nsACString& aSystemFontName, + gfxFontStyle& aFontStyle) { + MOZ_CRASH("UNIMPLEMENTED"); +} + +nsTArray<std::pair<const char**, uint32_t>> +IOSPlatformFontList::GetFilteredPlatformFontLists() { + nsTArray<std::pair<const char**, uint32_t>> fontLists; + + return fontLists; +} diff --git a/gfx/thebes/gencjkcisvs.py b/gfx/thebes/gencjkcisvs.py index 6a28e7d492..000b3f5711 100644 --- a/gfx/thebes/gencjkcisvs.py +++ b/gfx/thebes/gencjkcisvs.py @@ -9,7 +9,7 @@ import sys f = open(sys.argv[1] if len(sys.argv) > 1 else "StandardizedVariants.txt") line = f.readline() -m = re.compile("^# (StandardizedVariants(-\d+(\.\d+)*)?\.txt)").search(line) +m = re.compile(r"^# (StandardizedVariants(-\d+(\.\d+)*)?\.txt)").search(line) fileversion = m.group(1) vsdict = {} r = re.compile( diff --git a/gfx/thebes/gfxCoreTextShaper.h b/gfx/thebes/gfxCoreTextShaper.h index 53f24ba3ba..557b6ba247 100644 --- a/gfx/thebes/gfxCoreTextShaper.h +++ b/gfx/thebes/gfxCoreTextShaper.h @@ -8,7 +8,7 @@ #include "gfxFont.h" -#include <ApplicationServices/ApplicationServices.h> +#include <CoreText/CoreText.h> class gfxMacFont; diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp index b77058b359..8595004d21 100644 --- a/gfx/thebes/gfxDWriteFontList.cpp +++ b/gfx/thebes/gfxDWriteFontList.cpp @@ -1159,6 +1159,17 @@ FontVisibility gfxDWriteFontList::GetVisibilityForFamily( return FontVisibility::User; } +nsTArray<std::pair<const char**, uint32_t>> +gfxDWriteFontList::GetFilteredPlatformFontLists() { + nsTArray<std::pair<const char**, uint32_t>> fontLists; + + fontLists.AppendElement(std::make_pair(kBaseFonts, ArrayLength(kBaseFonts))); + fontLists.AppendElement( + std::make_pair(kLangPackFonts, ArrayLength(kLangPackFonts))); + + return fontLists; +} + void gfxDWriteFontList::AppendFamiliesFromCollection( IDWriteFontCollection* aCollection, nsTArray<fontlist::Family::InitData>& aFamilies, diff --git a/gfx/thebes/gfxDWriteFontList.h b/gfx/thebes/gfxDWriteFontList.h index adf8fdfa5a..357336a12c 100644 --- a/gfx/thebes/gfxDWriteFontList.h +++ b/gfx/thebes/gfxDWriteFontList.h @@ -436,6 +436,9 @@ class gfxDWriteFontList final : public gfxPlatformFontList { FontFamily& aMatchedFamily) MOZ_REQUIRES(mLock) override; + nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists() + override; + private: friend class gfxDWriteFontFamily; diff --git a/gfx/thebes/gfxFT2FontList.cpp b/gfx/thebes/gfxFT2FontList.cpp index 6ff9788dc1..66f7655282 100644 --- a/gfx/thebes/gfxFT2FontList.cpp +++ b/gfx/thebes/gfxFT2FontList.cpp @@ -1321,6 +1321,55 @@ FontVisibility gfxFT2FontList::GetVisibilityForFamily( return FontVisibility::User; } +nsTArray<std::pair<const char**, uint32_t>> +gfxFT2FontList::GetFilteredPlatformFontLists() { + static Device fontVisibilityDevice = Device::Unassigned; + if (fontVisibilityDevice == Device::Unassigned) { + nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service(); + Unused << gfxInfo->GetFontVisibilityDetermination(&fontVisibilityDevice); + } + + nsTArray<std::pair<const char**, uint32_t>> fontLists; + + if (fontVisibilityDevice == Device::Android_Unknown_Release_Version || + fontVisibilityDevice == Device::Android_Unknown_Peloton || + fontVisibilityDevice == Device::Android_Unknown_vbox || + fontVisibilityDevice == Device::Android_Unknown_mitv || + fontVisibilityDevice == Device::Android_Chromebook || + fontVisibilityDevice == Device::Android_Amazon) { + return fontLists; + } + + // Sanity Check + if (fontVisibilityDevice != Device::Android_sub_9 && + fontVisibilityDevice != Device::Android_9_11 && + fontVisibilityDevice != Device::Android_12_plus) { + return fontLists; + } + + fontLists.AppendElement( + std::make_pair(kBaseFonts_Android, ArrayLength(kBaseFonts_Android))); + + if (fontVisibilityDevice == Device::Android_sub_9) { + fontLists.AppendElement(std::make_pair(kBaseFonts_Android5_8, + ArrayLength(kBaseFonts_Android5_8))); + } else { + fontLists.AppendElement(std::make_pair( + kBaseFonts_Android9_Higher, ArrayLength(kBaseFonts_Android9_Higher))); + + if (fontVisibilityDevice == Device::Android_9_11) { + fontLists.AppendElement(std::make_pair( + kBaseFonts_Android9_11, ArrayLength(kBaseFonts_Android9_11))); + } else { + fontLists.AppendElement( + std::make_pair(kBaseFonts_Android12_Higher, + ArrayLength(kBaseFonts_Android12_Higher))); + } + } + + return fontLists; +} + static void GetName(hb_face_t* aFace, hb_ot_name_id_t aNameID, nsACString& aName) { unsigned int n = 0; diff --git a/gfx/thebes/gfxFT2FontList.h b/gfx/thebes/gfxFT2FontList.h index 895b1172d4..0e92d31944 100644 --- a/gfx/thebes/gfxFT2FontList.h +++ b/gfx/thebes/gfxFT2FontList.h @@ -210,6 +210,9 @@ class gfxFT2FontList final : public gfxPlatformFontList { void CollectInitData(const FontListEntry& aFLE, const nsCString& aPSName, const nsCString& aFullName, StandardFile aStdFile); + nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists() + override; + /** * Callback passed to AppendFacesFromCachedFaceList to collect family/face * information in either the unshared or shared list we're building. diff --git a/gfx/thebes/gfxFcPlatformFontList.cpp b/gfx/thebes/gfxFcPlatformFontList.cpp index 60a8f9894e..30c202d6ee 100644 --- a/gfx/thebes/gfxFcPlatformFontList.cpp +++ b/gfx/thebes/gfxFcPlatformFontList.cpp @@ -2048,6 +2048,49 @@ FontVisibility gfxFcPlatformFontList::GetVisibilityForFamily( } } +nsTArray<std::pair<const char**, uint32_t>> +gfxFcPlatformFontList::GetFilteredPlatformFontLists() { + AssignFontVisibilityDevice(); + + nsTArray<std::pair<const char**, uint32_t>> fontLists; + + switch (sFontVisibilityDevice) { + case Device::Linux_Ubuntu_any: + case Device::Linux_Ubuntu_22: + fontLists.AppendElement(std::make_pair( + kBaseFonts_Ubuntu_22_04, ArrayLength(kBaseFonts_Ubuntu_22_04))); + fontLists.AppendElement(std::make_pair( + kLangFonts_Ubuntu_22_04, ArrayLength(kLangFonts_Ubuntu_22_04))); + // For Ubuntu_any, we fall through to also check the 20_04 lists. + [[fallthrough]]; + + case Device::Linux_Ubuntu_20: + fontLists.AppendElement(std::make_pair( + kBaseFonts_Ubuntu_20_04, ArrayLength(kBaseFonts_Ubuntu_20_04))); + fontLists.AppendElement(std::make_pair( + kLangFonts_Ubuntu_20_04, ArrayLength(kLangFonts_Ubuntu_20_04))); + break; + + case Device::Linux_Fedora_any: + case Device::Linux_Fedora_39: + fontLists.AppendElement(std::make_pair( + kBaseFonts_Fedora_39, ArrayLength(kBaseFonts_Fedora_39))); + // For Fedora_any, fall through to also check Fedora 38 list. + [[fallthrough]]; + + case Device::Linux_Fedora_38: + fontLists.AppendElement(std::make_pair( + kBaseFonts_Fedora_38, ArrayLength(kBaseFonts_Fedora_38))); + break; + + default: + // We don't know how to categorize fonts on this system + break; + } + + return fontLists; +} + gfxFontEntry* gfxFcPlatformFontList::CreateFontEntry( fontlist::Face* aFace, const fontlist::Family* aFamily) { nsAutoCString desc(aFace->mDescriptor.AsString(SharedFontList())); diff --git a/gfx/thebes/gfxFcPlatformFontList.h b/gfx/thebes/gfxFcPlatformFontList.h index 54070d1410..ebf57fbcaa 100644 --- a/gfx/thebes/gfxFcPlatformFontList.h +++ b/gfx/thebes/gfxFcPlatformFontList.h @@ -317,6 +317,9 @@ class gfxFcPlatformFontList final : public gfxPlatformFontList { protected: virtual ~gfxFcPlatformFontList(); + nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists() + override; + #if defined(MOZ_SANDBOX) && defined(XP_LINUX) typedef mozilla::SandboxBroker::Policy SandboxPolicy; #else diff --git a/gfx/thebes/gfxFontUtils.cpp b/gfx/thebes/gfxFontUtils.cpp index 02543607cd..46f33f4696 100644 --- a/gfx/thebes/gfxFontUtils.cpp +++ b/gfx/thebes/gfxFontUtils.cpp @@ -28,7 +28,7 @@ #include "plbase64.h" #include "mozilla/Logging.h" -#ifdef XP_MACOSX +#ifdef XP_DARWIN # include <CoreFoundation/CoreFoundation.h> #endif @@ -1441,7 +1441,7 @@ bool gfxFontUtils::DecodeFontName(const char* aNameData, int32_t aByteLen, } if (encoding == X_USER_DEFINED_ENCODING) { -#ifdef XP_MACOSX +#ifdef XP_DARWIN // Special case for macOS only: support legacy Mac encodings // that aren't part of the Encoding Standard. if (aPlatformCode == PLATFORM_ID_MAC) { diff --git a/gfx/thebes/gfxGDIFontList.cpp b/gfx/thebes/gfxGDIFontList.cpp index 3c4c7bce07..4dca4506c0 100644 --- a/gfx/thebes/gfxGDIFontList.cpp +++ b/gfx/thebes/gfxGDIFontList.cpp @@ -853,6 +853,13 @@ bool gfxGDIFontList::FindAndAddFamiliesLocked( aDevToCssSize); } +nsTArray<std::pair<const char**, uint32_t>> +gfxGDIFontList::GetFilteredPlatformFontLists() { + nsTArray<std::pair<const char**, uint32_t>> fontLists; + + return fontLists; +} + FontFamily gfxGDIFontList::GetDefaultFontForPlatform( nsPresContext* aPresContext, const gfxFontStyle* aStyle, nsAtom* aLanguage) { diff --git a/gfx/thebes/gfxGDIFontList.h b/gfx/thebes/gfxGDIFontList.h index 708f7fc114..7fc7f7521b 100644 --- a/gfx/thebes/gfxGDIFontList.h +++ b/gfx/thebes/gfxGDIFontList.h @@ -332,6 +332,9 @@ class gfxGDIFontList final : public gfxPlatformFontList { nsAtom* aLanguage = nullptr) MOZ_REQUIRES(mLock) override; + nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists() + override; + private: friend class gfxWindowsPlatform; diff --git a/gfx/thebes/gfxMacFont.h b/gfx/thebes/gfxMacFont.h index f33ad478ec..051c4ea675 100644 --- a/gfx/thebes/gfxMacFont.h +++ b/gfx/thebes/gfxMacFont.h @@ -8,7 +8,7 @@ #include "mozilla/MemoryReporting.h" #include "gfxFont.h" -#include <ApplicationServices/ApplicationServices.h> +#include <CoreText/CoreText.h> #include "mozilla/gfx/UnscaledFontMac.h" diff --git a/gfx/thebes/gfxMacPlatformFontList.h b/gfx/thebes/gfxMacPlatformFontList.h index ac0d8927fe..8bafa1b803 100644 --- a/gfx/thebes/gfxMacPlatformFontList.h +++ b/gfx/thebes/gfxMacPlatformFontList.h @@ -17,6 +17,9 @@ class gfxMacPlatformFontList final : public CoreTextFontList { gfxPlatformFontList::PlatformFontList()); } + nsTArray<std::pair<const char**, uint32_t>> GetFilteredPlatformFontLists() + override; + static void LookupSystemFont(mozilla::LookAndFeel::FontID aSystemFontID, nsACString& aSystemFontName, gfxFontStyle& aFontStyle); @@ -25,11 +28,6 @@ class gfxMacPlatformFontList final : public CoreTextFontList { bool DeprecatedFamilyIsAvailable(const nsACString& aName) override; FontVisibility GetVisibilityForFamily(const nsACString& aName) const override; - FontFamily GetDefaultFontForPlatform(nsPresContext* aPresContext, - const gfxFontStyle* aStyle, - nsAtom* aLanguage = nullptr) - MOZ_REQUIRES(mLock) override; - private: friend class gfxPlatformMac; @@ -40,9 +38,6 @@ class gfxMacPlatformFontList final : public CoreTextFontList { void InitSingleFaceList() MOZ_REQUIRES(mLock) override; void InitAliasesForSingleFaceList() MOZ_REQUIRES(mLock) override; - // initialize system fonts - void InitSystemFontNames() override MOZ_REQUIRES(mLock); - nsTArray<nsCString> mSingleFaceFonts; }; diff --git a/gfx/thebes/gfxMacPlatformFontList.mm b/gfx/thebes/gfxMacPlatformFontList.mm index e36c9c8a25..2b8d1fa16a 100644 --- a/gfx/thebes/gfxMacPlatformFontList.mm +++ b/gfx/thebes/gfxMacPlatformFontList.mm @@ -72,80 +72,6 @@ static NSString* GetNSStringForString(const nsAString& aSrc) { #define LOG_CMAPDATA_ENABLED() \ MOZ_LOG_TEST(gfxPlatform::GetLog(eGfxLog_cmapdata), mozilla::LogLevel::Debug) -class gfxMacFontFamily final : public CTFontFamily { - public: - gfxMacFontFamily(const nsACString& aName, NSFont* aSystemFont) - : CTFontFamily(aName, FontVisibility::Unknown), - mForSystemFont(aSystemFont) { - // I don't think the system font instance is at much risk of being deleted, - // but to be on the safe side let's retain a reference until we're finished - // using it for lazy initialization. - [mForSystemFont retain]; - } - - void FindStyleVariationsLocked(FontInfoData* aFontInfoData = nullptr) - MOZ_REQUIRES(mLock) override; - - protected: - // If non-null, this is a family representing the system UI font, and should - // use the given NSFont as the basis for initialization as the normal - // font-manager APIs based on family name won't handle it. - NSFont* mForSystemFont = nullptr; -}; - -void gfxMacFontFamily::FindStyleVariationsLocked(FontInfoData* aFontInfoData) { - if (mHasStyles) { - return; - } - - AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING("gfxMacFontFamily::FindStyleVariations", - LAYOUT, mName); - - nsAutoreleasePool localPool; - - if (mForSystemFont) { - MOZ_ASSERT(gfxPlatform::HasVariationFontSupport()); - - auto addToFamily = [&](NSFont* aNSFont) MOZ_REQUIRES(mLock) { - NSString* psNameNS = aNSFont.fontDescriptor.postscriptName; - nsAutoString nameUTF16; - nsAutoCString psName; - nsCocoaUtils::GetStringForNSString(psNameNS, nameUTF16); - CopyUTF16toUTF8(nameUTF16, psName); - - auto* fe = - new CTFontEntry(psName, WeightRange(FontWeight::NORMAL), true, 0.0); - - // Set the appropriate style, assuming it may not have a variation range. - fe->mStyleRange = SlantStyleRange( - (aNSFont.fontDescriptor.symbolicTraits & NSFontItalicTrait) - ? FontSlantStyle::ITALIC - : FontSlantStyle::NORMAL); - - // Set up weight (and width, if present) ranges. - fe->SetupVariationRanges(); - AddFontEntryLocked(fe); - }; - - addToFamily(mForSystemFont); - - // See if there is a corresponding italic face, and add it to the family. - NSFont* italicFont = [sFontManager convertFont:mForSystemFont - toHaveTrait:NSItalicFontMask]; - if (italicFont != mForSystemFont) { - addToFamily(italicFont); - } - - [mForSystemFont release]; - mForSystemFont = nullptr; - SetHasStyles(true); - - return; - } - - CTFontFamily::FindStyleVariationsLocked(aFontInfoData); -} - /* gfxSingleFaceMacFontFamily */ class gfxSingleFaceMacFontFamily final : public gfxFontFamily { @@ -252,6 +178,15 @@ FontVisibility gfxMacPlatformFontList::GetVisibilityForFamily( return FontVisibility::User; } +nsTArray<std::pair<const char**, uint32_t>> +gfxMacPlatformFontList::GetFilteredPlatformFontLists() { + nsTArray<std::pair<const char**, uint32_t>> fontLists; + + fontLists.AppendElement(std::make_pair(kBaseFonts, ArrayLength(kBaseFonts))); + + return fontLists; +} + bool gfxMacPlatformFontList::DeprecatedFamilyIsAvailable( const nsACString& aName) { NSString* family = GetNSStringForString(NS_ConvertUTF8toUTF16(aName)); @@ -394,92 +329,6 @@ void gfxMacPlatformFontList::InitSingleFaceList() { } } -// System fonts under OSX may contain weird "meta" names but if we create -// a new font using just the Postscript name, the NSFont api returns an object -// with the actual real family name. For example, under OSX 10.11: -// -// [[NSFont menuFontOfSize:8.0] familyName] ==> .AppleSystemUIFont -// [[NSFont fontWithName:[[[NSFont menuFontOfSize:8.0] fontDescriptor] -// postscriptName] -// size:8.0] familyName] ==> .SF NS Text - -static NSString* GetRealFamilyName(NSFont* aFont) { - NSString* psName = [[aFont fontDescriptor] postscriptName]; - // With newer macOS versions and SDKs (e.g. when compiled against SDK 10.15), - // [NSFont fontWithName:] fails for hidden system fonts, because the - // underlying Core Text functions it uses reject such names and tell us to use - // the special CTFontCreateUIFontForLanguage API instead. To work around this, - // as we don't yet work directly with the CTFontUIFontType identifiers, we - // create a Core Graphics font (as it doesn't reject system font names), and - // use this to create a Core Text font that we can query for the family name. - // Eventually we should move to using CTFontUIFontType constants to identify - // system fonts, and eliminate the need to instantiate them (indirectly) from - // their postscript names. - AutoCFRelease<CGFontRef> cgFont = - CGFontCreateWithFontName(CFStringRef(psName)); - if (!cgFont) { - return [aFont familyName]; - } - - AutoCFRelease<CTFontRef> ctFont = - CTFontCreateWithGraphicsFont(cgFont, 0.0, nullptr, nullptr); - if (!ctFont) { - return [aFont familyName]; - } - NSString* familyName = (NSString*)CTFontCopyFamilyName(ctFont); - - return [familyName autorelease]; -} - -void gfxMacPlatformFontList::InitSystemFontNames() { - // text font family - NSFont* sys = [NSFont systemFontOfSize:0.0]; - NSString* textFamilyName = GetRealFamilyName(sys); - nsAutoString familyName; - nsCocoaUtils::GetStringForNSString(textFamilyName, familyName); - CopyUTF16toUTF8(familyName, mSystemFontFamilyName); - - // We store an in-process gfxFontFamily for the system font even if using the - // shared fontlist to manage "normal" fonts, because the hidden system fonts - // may be excluded from the font list altogether. This family will be - // populated based on the given NSFont. - RefPtr<gfxFontFamily> fam = new gfxMacFontFamily(mSystemFontFamilyName, sys); - if (fam) { - nsAutoCString key; - GenerateFontListKey(mSystemFontFamilyName, key); - mFontFamilies.InsertOrUpdate(key, std::move(fam)); - } - -#ifdef DEBUG - // different system font API's always map to the same family under OSX, so - // just assume that and emit a warning if that ever changes - NSString* sysFamily = GetRealFamilyName([NSFont systemFontOfSize:0.0]); - if ([sysFamily compare:GetRealFamilyName([NSFont - boldSystemFontOfSize:0.0])] != NSOrderedSame || - [sysFamily compare:GetRealFamilyName([NSFont - controlContentFontOfSize:0.0])] != NSOrderedSame || - [sysFamily compare:GetRealFamilyName([NSFont menuBarFontOfSize:0.0])] != - NSOrderedSame || - [sysFamily compare:GetRealFamilyName([NSFont toolTipsFontOfSize:0.0])] != - NSOrderedSame) { - NS_WARNING("system font types map to different font families" - " -- please log a bug!!"); - } -#endif -} - -FontFamily gfxMacPlatformFontList::GetDefaultFontForPlatform( - nsPresContext* aPresContext, const gfxFontStyle* aStyle, - nsAtom* aLanguage) { - nsAutoreleasePool localPool; - - NSString* defaultFamily = [[NSFont userFontOfSize:aStyle->size] familyName]; - nsAutoString familyName; - - GetStringForNSString(defaultFamily, familyName); - return FindFamily(aPresContext, NS_ConvertUTF16toUTF8(familyName)); -} - void gfxMacPlatformFontList::LookupSystemFont(LookAndFeel::FontID aSystemFontID, nsACString& aSystemFontName, gfxFontStyle& aFontStyle) { diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index ccc76def7e..c57564b054 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -21,8 +21,8 @@ #include "mozilla/gfx/gfxVars.h" #include "mozilla/gfx/GPUProcessManager.h" #include "mozilla/gfx/GraphicsMessages.h" -#include "mozilla/gfx/CanvasManagerChild.h" #include "mozilla/gfx/CanvasRenderThread.h" +#include "mozilla/gfx/CanvasShutdownManager.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/DebugOnly.h" #include "mozilla/EnumTypeTraits.h" @@ -79,7 +79,7 @@ #if defined(XP_WIN) # include "gfxWindowsPlatform.h" # include "mozilla/widget/WinWindowOcclusionTracker.h" -#elif defined(XP_MACOSX) +#elif defined(XP_DARWIN) # include "gfxPlatformMac.h" # include "gfxQuartzSurface.h" #elif defined(MOZ_WIDGET_GTK) @@ -289,9 +289,8 @@ void CrashStatsLogForwarder::UpdateCrashReport() { << " (t=" << std::get<2>(it) << ") "; } - nsCString reportString(message.str().c_str()); - nsresult annotated = - CrashReporter::AnnotateCrashReport(mCrashCriticalKey, reportString); + nsresult annotated = CrashReporter::RecordAnnotationCString( + mCrashCriticalKey, message.str().c_str()); if (annotated != NS_OK) { printf("Crash Annotation %s: %s", @@ -409,7 +408,7 @@ void CrashStatsLogForwarder::CrashAction(LogReason aReason) { #define GFX_PREF_WORD_CACHE_MAXENTRIES "gfx.font_rendering.wordcache.maxentries" #define GFX_PREF_GRAPHITE_SHAPING "gfx.font_rendering.graphite.enabled" -#if defined(XP_MACOSX) +#if defined(XP_DARWIN) # define GFX_PREF_CORETEXT_SHAPING "gfx.font_rendering.coretext.enabled" #endif @@ -786,7 +785,7 @@ bool gfxPlatform::HasVariationFontSupport() { // as any thread will set it to the same value. #if defined(XP_WIN) sHasVariationFontSupport = gfxWindowsPlatform::CheckVariationFontSupport(); -#elif defined(XP_MACOSX) +#elif defined(XP_DARWIN) sHasVariationFontSupport = gfxPlatformMac::CheckVariationFontSupport(); #elif defined(MOZ_WIDGET_GTK) sHasVariationFontSupport = gfxPlatformGtk::CheckVariationFontSupport(); @@ -904,7 +903,7 @@ void gfxPlatform::Init() { #if defined(XP_WIN) gPlatform = new gfxWindowsPlatform; -#elif defined(XP_MACOSX) +#elif defined(XP_DARWIN) gPlatform = new gfxPlatformMac; #elif defined(MOZ_WIDGET_GTK) gPlatform = new gfxPlatformGtk; @@ -1069,6 +1068,15 @@ void gfxPlatform::ReportTelemetry() { nsString adapterDesc; gfxInfo->GetAdapterDescription(adapterDesc); + +// Android description is constructed in a way that makes it possible to exceed +// the metric's length limit. +#if defined(ANDROID) + if (!adapterDesc.IsEmpty()) { + adapterDesc.Truncate(99); + } +#endif + mozilla::glean::gfx_adapter_primary::description.Set( NS_ConvertUTF16toUTF8(adapterDesc)); @@ -1335,7 +1343,7 @@ void gfxPlatform::ShutdownLayersIPC() { if (XRE_IsContentProcess()) { gfx::VRManagerChild::ShutDown(); - gfx::CanvasManagerChild::Shutdown(); + gfx::CanvasShutdownManager::Shutdown(); // cf bug 1215265. if (StaticPrefs::layers_child_process_shutdown()) { layers::CompositorManagerChild::Shutdown(); @@ -1346,7 +1354,7 @@ void gfxPlatform::ShutdownLayersIPC() { VideoBridgeParent::Shutdown(); RDDProcessManager::RDDProcessShutdown(); gfx::VRManagerChild::ShutDown(); - gfx::CanvasManagerChild::Shutdown(); + gfx::CanvasShutdownManager::Shutdown(); layers::CompositorManagerChild::Shutdown(); layers::ImageBridgeChild::ShutDown(); // This could be running on either the Compositor thread, the Renderer @@ -2273,7 +2281,7 @@ void gfxPlatform::FontsPrefsChanged(const char* aPref) { !strcmp(GFX_PREF_GRAPHITE_SHAPING, aPref)) { FlushFontAndWordCaches(); } else if ( -#if defined(XP_MACOSX) +#if defined(XP_DARWIN) !strcmp(GFX_PREF_CORETEXT_SHAPING, aPref) || #endif !strcmp("gfx.font_rendering.ahem_antialias_none", aPref)) { @@ -2693,7 +2701,7 @@ void gfxPlatform::InitWebRenderConfig() { StaticPrefs::GetPrefName_gfx_webrender_batched_upload_threshold())); if (WebRenderResourcePathOverride()) { - CrashReporter::AnnotateCrashReport( + CrashReporter::RecordAnnotationBool( CrashReporter::Annotation::IsWebRenderResourcePathOverridden, true); } @@ -2740,7 +2748,7 @@ void gfxPlatform::InitWebRenderConfig() { "FEATURE_FAILURE_WR_NO_GFX_INFO"_ns); useVideoHwOverlay = false; } else { - if (status != nsIGfxInfo::FEATURE_ALLOW_ALWAYS) { + if (status != nsIGfxInfo::FEATURE_STATUS_OK) { FeatureState& feature = gfxConfig::GetFeature(Feature::VIDEO_HARDWARE_OVERLAY); feature.DisableByDefault(FeatureStatus::Blocked, @@ -2897,6 +2905,49 @@ void gfxPlatform::InitWebRenderConfig() { } #endif + bool allowOverlayVpAutoHDR = false; + if (StaticPrefs::gfx_webrender_overlay_vp_auto_hdr_AtStartup()) { + allowOverlayVpAutoHDR = true; + + nsCString failureId; + int32_t status; + const nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service(); + if (NS_FAILED(gfxInfo->GetFeatureStatus( + nsIGfxInfo::FEATURE_OVERLAY_VP_AUTO_HDR, failureId, &status))) { + allowOverlayVpAutoHDR = false; + } else { + if (status != nsIGfxInfo::FEATURE_STATUS_OK) { + allowOverlayVpAutoHDR = false; + } + } + } + + if (allowOverlayVpAutoHDR) { + gfxVars::SetWebRenderOverlayVpAutoHDR(true); + } + + bool allowOverlayVpSuperResolution = false; + if (StaticPrefs::gfx_webrender_overlay_vp_super_resolution_AtStartup()) { + allowOverlayVpSuperResolution = true; + + nsCString failureId; + int32_t status; + const nsCOMPtr<nsIGfxInfo> gfxInfo = components::GfxInfo::Service(); + if (NS_FAILED(gfxInfo->GetFeatureStatus( + nsIGfxInfo::FEATURE_OVERLAY_VP_SUPER_RESOLUTION, failureId, + &status))) { + allowOverlayVpSuperResolution = false; + } else { + if (status != nsIGfxInfo::FEATURE_STATUS_OK) { + allowOverlayVpSuperResolution = false; + } + } + } + + if (allowOverlayVpSuperResolution) { + gfxVars::SetWebRenderOverlayVpSuperResolution(true); + } + if (gfxConfig::IsEnabled(Feature::WEBRENDER_COMPOSITOR)) { gfxVars::SetUseWebRenderCompositor(true); } diff --git a/gfx/thebes/gfxPlatformFontList.cpp b/gfx/thebes/gfxPlatformFontList.cpp index 709a0f3c27..bc0e123f85 100644 --- a/gfx/thebes/gfxPlatformFontList.cpp +++ b/gfx/thebes/gfxPlatformFontList.cpp @@ -378,6 +378,40 @@ gfxPlatformFontList::~gfxPlatformFontList() { NS_RELEASE(gFontListPrefObserver); } +void gfxPlatformFontList::GetMissingFonts(nsCString& aMissingFonts) { + AutoLock lock(mLock); + + auto fontLists = GetFilteredPlatformFontLists(); + + if (!fontLists.Length()) { + aMissingFonts.Append("No font list available for this device."); + } + + for (unsigned int i = 0; i < fontLists.Length(); i++) { + for (unsigned int j = 0; j < fontLists[i].second; j++) { + nsCString key(fontLists[i].first[j]); + GenerateFontListKey(key); + + if (SharedFontList()) { + fontlist::Family* family = SharedFontList()->FindFamily(key); + if (!family) { + aMissingFonts.Append(fontLists[i].first[j]); + aMissingFonts.Append("|"); + } + } else { + gfxFontFamily* familyEntry = mFontFamilies.GetWeak(key); + if (!familyEntry) { + familyEntry = mOtherFamilyNames.GetWeak(key); + } + if (!familyEntry) { + aMissingFonts.Append(fontLists[i].first[j]); + aMissingFonts.Append("|"); + } + } + } + } +} + /* static */ void gfxPlatformFontList::FontWhitelistPrefChanged(const char* aPref, void* aClosure) { @@ -700,6 +734,10 @@ void gfxPlatformFontList::GenerateFontListKey(const nsACString& aKeyName, ToLowerCase(aResult); } +void gfxPlatformFontList::GenerateFontListKey(nsACString& aKeyName) { + ToLowerCase(aKeyName); +} + // Used if a stylo thread wants to trigger InitOtherFamilyNames in the main // process: we can't do IPC from the stylo thread so we post this to the main // thread instead. @@ -755,7 +793,7 @@ bool gfxPlatformFontList::InitOtherFamilyNames( // (This is used so we can reliably run reftests that depend on localized // font-family names being available.) if (aDeferOtherFamilyNamesLoading && - StaticPrefs::gfx_font_loader_delay_AtStartup() > 0) { + StaticPrefs::gfx_font_loader_delay() > 0) { if (!mPendingOtherFamilyNameTask) { RefPtr<mozilla::CancelableRunnable> task = new InitOtherFamilyNamesRunnable(); @@ -2648,7 +2686,7 @@ bool gfxPlatformFontList::LoadFontInfo() { // Limit the time spent reading fonts in one pass, unless the font-loader // delay was set to zero, in which case we run to completion even if it // causes some jank. - if (StaticPrefs::gfx_font_loader_delay_AtStartup() > 0) { + if (StaticPrefs::gfx_font_loader_delay() > 0) { TimeDuration elapsed = TimeStamp::Now() - start; if (elapsed.ToMilliseconds() > FONT_LOADER_MAX_TIMESLICE && i + 1 != endIndex) { @@ -2751,7 +2789,7 @@ void gfxPlatformFontList::GetPrefsAndStartLoader() { if (AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) { return; } - uint32_t delay = std::max(1u, StaticPrefs::gfx_font_loader_delay_AtStartup()); + uint32_t delay = std::max(1u, StaticPrefs::gfx_font_loader_delay()); if (NS_IsMainThread()) { StartLoader(delay); } else { diff --git a/gfx/thebes/gfxPlatformFontList.h b/gfx/thebes/gfxPlatformFontList.h index 4d5b9e4015..3ab74c5f74 100644 --- a/gfx/thebes/gfxPlatformFontList.h +++ b/gfx/thebes/gfxPlatformFontList.h @@ -245,6 +245,8 @@ class gfxPlatformFontList : public gfxFontInfoLoader { return sPlatformFontList; } + void GetMissingFonts(nsCString& aMissingFonts); + static bool Initialize(gfxPlatformFontList* aList); static void Shutdown() { @@ -658,6 +660,9 @@ class gfxPlatformFontList : public gfxFontInfoLoader { mutable mozilla::RecursiveMutex mLock; protected: + virtual nsTArray<std::pair<const char**, uint32_t>> + GetFilteredPlatformFontLists() = 0; + friend class mozilla::fontlist::FontList; friend class InitOtherFamilyNamesForStylo; @@ -867,7 +872,10 @@ class gfxPlatformFontList : public gfxFontInfoLoader { // load the bad underline blocklist from pref. void LoadBadUnderlineList(); + // This version of the function will not modify aKeyName void GenerateFontListKey(const nsACString& aKeyName, nsACString& aResult); + // This version of the function WILL modify aKeyName + void GenerateFontListKey(nsACString& aKeyName); virtual void GetFontFamilyNames(nsTArray<nsCString>& aFontFamilyNames) MOZ_REQUIRES(mLock); @@ -1010,13 +1018,14 @@ class gfxPlatformFontList : public gfxFontInfoLoader { // When system-wide font lookup fails for a character, cache it to skip future // searches. This is an array of bitsets, one for each FontVisibility level. - mozilla::EnumeratedArray<FontVisibility, FontVisibility::Count, - gfxSparseBitSet> + mozilla::EnumeratedArray<FontVisibility, gfxSparseBitSet, + size_t(FontVisibility::Count)> mCodepointsWithNoFonts MOZ_GUARDED_BY(mLock); // the family to use for U+FFFD fallback, to avoid expensive search every time // on pages with lots of problems - mozilla::EnumeratedArray<FontVisibility, FontVisibility::Count, FontFamily> + mozilla::EnumeratedArray<FontVisibility, FontFamily, + size_t(FontVisibility::Count)> mReplacementCharFallbackFamily MOZ_GUARDED_BY(mLock); // Sorted array of lowercased family names; use ContainsSorted to test diff --git a/gfx/thebes/gfxPlatformMac.cpp b/gfx/thebes/gfxPlatformMac.cpp index 02ec1a7b28..091b0dff28 100644 --- a/gfx/thebes/gfxPlatformMac.cpp +++ b/gfx/thebes/gfxPlatformMac.cpp @@ -9,7 +9,6 @@ #include "mozilla/DataMutex.h" #include "mozilla/gfx/2D.h" -#include "gfxMacPlatformFontList.h" #include "gfxMacFont.h" #include "gfxCoreTextShaper.h" #include "gfxTextRun.h" @@ -20,7 +19,9 @@ #include "nsTArray.h" #include "mozilla/Preferences.h" #include "mozilla/VsyncDispatcher.h" -#include "nsCocoaFeatures.h" +#ifdef MOZ_WIDGET_COCOA +# include "nsCocoaFeatures.h" +#endif #include "nsComponentManagerUtils.h" #include "nsIFile.h" #include "nsUnicodeProperties.h" @@ -48,6 +49,14 @@ using namespace mozilla::unicode; using mozilla::dom::SystemFontList; +#ifdef MOZ_WIDGET_COCOA +# include "gfxMacPlatformFontList.h" +using PlatformFontListClass = gfxMacPlatformFontList; +#else +# include "IOSPlatformFontList.h" +using PlatformFontListClass = IOSPlatformFontList; +#endif + // A bunch of fonts for "additional language support" are shipped in a // "Language Support" directory, and don't show up in the standard font // list returned by CTFontManagerCopyAvailableFontFamilyNames unless @@ -62,7 +71,7 @@ void gfxPlatformMac::FontRegistrationCallback(void* aUnused) { PR_SetCurrentThreadName("RegisterFonts"); for (const auto& dir : kLangFontsDirs) { - gfxMacPlatformFontList::ActivateFontsFromDir(dir); + PlatformFontListClass::ActivateFontsFromDir(dir); } } @@ -111,11 +120,11 @@ BackendPrefsData gfxPlatformMac::GetBackendPrefs() const { } bool gfxPlatformMac::CreatePlatformFontList() { - return gfxPlatformFontList::Initialize(new gfxMacPlatformFontList); + return gfxPlatformFontList::Initialize(new PlatformFontListClass); } void gfxPlatformMac::ReadSystemFontList(SystemFontList* aFontList) { - gfxMacPlatformFontList::PlatformFontList()->ReadSystemFontList(aFontList); + PlatformFontListClass::PlatformFontList()->ReadSystemFontList(aFontList); } already_AddRefed<gfxASurface> gfxPlatformMac::CreateOffscreenSurface( @@ -668,8 +677,8 @@ void gfxPlatformMac::GetCommonFallbackFonts(uint32_t aCh, Script aRunScript, void gfxPlatformMac::LookupSystemFont( mozilla::LookAndFeel::FontID aSystemFontID, nsACString& aSystemFontName, gfxFontStyle& aFontStyle) { - return gfxMacPlatformFontList::LookupSystemFont(aSystemFontID, - aSystemFontName, aFontStyle); + return PlatformFontListClass::LookupSystemFont(aSystemFontID, aSystemFontName, + aFontStyle); } uint32_t gfxPlatformMac::ReadAntiAliasingThreshold() { @@ -700,6 +709,7 @@ uint32_t gfxPlatformMac::ReadAntiAliasingThreshold() { bool gfxPlatformMac::AccelerateLayersByDefault() { return true; } +#ifdef MOZ_WIDGET_COCOA // This is the renderer output callback function, called on the vsync thread static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink, const CVTimeStamp* aNow, @@ -934,9 +944,11 @@ static CVReturn VsyncCallback(CVDisplayLinkRef aDisplayLink, vsyncSource->NotifyVsync(previousVsync, outputTime); return kCVReturnSuccess; } +#endif already_AddRefed<mozilla::gfx::VsyncSource> gfxPlatformMac::CreateGlobalHardwareVsyncSource() { +#ifdef MOZ_WIDGET_COCOA RefPtr<VsyncSource> osxVsyncSource = new OSXVsyncSource(); osxVsyncSource->EnableVsync(); if (!osxVsyncSource->IsVsyncEnabled()) { @@ -947,6 +959,10 @@ gfxPlatformMac::CreateGlobalHardwareVsyncSource() { osxVsyncSource->DisableVsync(); return osxVsyncSource.forget(); +#else + // TODO: CADisplayLink + return GetSoftwareVsyncSource(); +#endif } bool gfxPlatformMac::SupportsHDR() { @@ -958,8 +974,10 @@ bool gfxPlatformMac::SupportsHDR() { return false; } +#ifdef MOZ_WIDGET_UIKIT + return false; +#elif defined(EARLY_BETA_OR_EARLIER) // Screen is capable. Is the OS capable? -#ifdef EARLY_BETA_OR_EARLIER // More-or-less supported in Catalina. return true; #else @@ -974,7 +992,10 @@ nsTArray<uint8_t> gfxPlatformMac::GetPlatformCMSOutputProfileData() { return prefProfileData; } - CGColorSpaceRef cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID()); + CGColorSpaceRef cspace = nil; +#ifdef MOZ_WIDGET_COCOA + cspace = ::CGDisplayCopyColorSpace(::CGMainDisplayID()); +#endif if (!cspace) { cspace = ::CGColorSpaceCreateDeviceRGB(); } diff --git a/gfx/thebes/gfxQuartzSurface.h b/gfx/thebes/gfxQuartzSurface.h index fbc081197b..cb5e54c80b 100644 --- a/gfx/thebes/gfxQuartzSurface.h +++ b/gfx/thebes/gfxQuartzSurface.h @@ -10,7 +10,11 @@ #include "nsSize.h" #include "gfxPoint.h" -#include <Carbon/Carbon.h> +#ifdef MOZ_WIDGET_COCOA +# include <Carbon/Carbon.h> +#else +# include <CoreGraphics/CoreGraphics.h> +#endif class gfxContext; class gfxImageSurface; diff --git a/gfx/thebes/gfxUserFontSet.cpp b/gfx/thebes/gfxUserFontSet.cpp index aeaf296200..e9a2f513b3 100644 --- a/gfx/thebes/gfxUserFontSet.cpp +++ b/gfx/thebes/gfxUserFontSet.cpp @@ -492,38 +492,54 @@ void gfxUserFontEntry::DoLoadNextSrc(bool aIsContinue) { else if (currSrc.mSourceType == gfxFontFaceSrc::eSourceType_URL) { if (gfxPlatform::GetPlatform()->IsFontFormatSupported( currSrc.mFormatHint, currSrc.mTechFlags)) { - if (ServoStyleSet* set = gfxFontUtils::CurrentServoStyleSet()) { - // Only support style worker threads synchronously getting - // entries from the font cache when it's not a data: URI - // @font-face that came from UA or user sheets, since we - // were not able to call IsFontLoadAllowed ahead of time - // for these entries. - if (currSrc.mUseOriginPrincipal && IgnorePrincipal(currSrc.mURI)) { - set->AppendTask(PostTraversalTask::LoadFontEntry(this)); - SetLoadState(STATUS_LOAD_PENDING); - return; + // TODO(emilio): Make UserFontCache thread-safe maybe? But we need to + // potentially do CSP checks so maybe not trivial. + const bool canCheckCache = [&] { + if (NS_IsMainThread()) { + return true; } - } + if (gfxFontUtils::CurrentServoStyleSet()) { + // Only support style worker threads synchronously getting entries + // from the font cache when it's not a data: URI @font-face that + // came from UA or user sheets, since we were not able to call + // IsFontLoadAllowed ahead of time for these entries. + return !currSrc.mUseOriginPrincipal || + !IgnorePrincipal(currSrc.mURI); + } + return false; + }(); // see if we have an existing entry for this source - gfxFontEntry* fe = - gfxUserFontSet::UserFontCache::GetFont(currSrc, *this); - if (fe) { - mPlatformFontEntry = fe; - SetLoadState(STATUS_LOADED); - LOG( - ("userfonts (%p) [src %d] " - "loaded uri from cache: (%s) for (%s)\n", - fontSet.get(), mCurrentSrcIndex, - currSrc.mURI->GetSpecOrDefault().get(), mFamilyName.get())); - return; + if (canCheckCache) { + gfxFontEntry* fe = + gfxUserFontSet::UserFontCache::GetFont(currSrc, *this); + if (fe) { + mPlatformFontEntry = fe; + SetLoadState(STATUS_LOADED); + LOG( + ("userfonts (%p) [src %d] " + "loaded uri from cache: (%s) for (%s)\n", + fontSet.get(), mCurrentSrcIndex, + currSrc.mURI->GetSpecOrDefault().get(), mFamilyName.get())); + return; + } } if (ServoStyleSet* set = gfxFontUtils::CurrentServoStyleSet()) { // If we need to start a font load and we're on a style // worker thread, we have to defer it. + SetLoadState(STATUS_LOAD_PENDING); set->AppendTask(PostTraversalTask::LoadFontEntry(this)); + return; + } + + if (dom::IsCurrentThreadRunningWorker()) { + // TODO: Maybe support loading the font entry in workers, at least for + // buffers or other sync sources? SetLoadState(STATUS_LOAD_PENDING); + NS_DispatchToMainThread( + NewRunnableMethod("gfxUserFontEntry::ContinueLoad", this, + &gfxUserFontEntry::ContinueLoad)); return; } @@ -551,9 +567,9 @@ void gfxUserFontEntry::DoLoadNextSrc(bool aIsContinue) { fontSet->LogMessage(this, mCurrentSrcIndex, "font load failed", nsIScriptError::errorFlag, rv); } else if (!aIsContinue) { - RefPtr<nsIRunnable> runnable = NS_NewRunnableFunction( - "gfxUserFontSet::AsyncContinueLoad", - [loader = RefPtr{this}] { loader->ContinueLoad(); }); + RefPtr<nsIRunnable> runnable = + NewRunnableMethod("gfxUserFontEntry::ContinueLoad", this, + &gfxUserFontEntry::ContinueLoad); SetLoadState(STATUS_LOAD_PENDING); // We don't want to trigger the channel open at random points in // time, because it can run privileged JS. @@ -817,13 +833,6 @@ void gfxUserFontEntry::Load() { if (mUserFontLoadState != STATUS_NOT_LOADED) { return; } - if (dom::IsCurrentThreadRunningWorker()) { - // TODO: Maybe support loading the font entry in workers, at least for - // buffers or other sync sources? - NS_DispatchToMainThread(NewRunnableMethod("gfxUserFontEntry::Load", this, - &gfxUserFontEntry::Load)); - return; - } LoadNextSrc(); } diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index e6994f8665..93de20f445 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -540,42 +540,38 @@ void gfxWindowsPlatform::UpdateSupportsHDR() { return; } - // Set mSupportsHDR to true if any of the DeviceManager outputs have both: - // 1) greater than 8-bit color - // 2) a colorspace that uses BT2020 + // Set mSupportsHDR to true if any of the DeviceManager outputs have a BT2020 + // colorspace with EOTF2084 gamma curve, this indicates the system is sending + // an HDR format to at least one monitor. The colorspace returned by DXGI is + // very vague - we only see DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020 for HDR + // and DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709 for SDR modes, even if the + // monitor is using something like YCbCr444 according to Settings + // (System -> Display Settings -> Advanced Display). To get more specific + // info we would need to query the DISPLAYCONFIG values in WinGDI. + // + // Note that the bit depth used to be checked here, but as of Windows 11 22H2, + // HDR is supported with 8bpc for lower bandwidth, where DWM converts to + // dithered RGB8 rather than RGB10, which doesn't really matter here. + // + // This only returns true if there is an HDR display connected at app start, + // if the user switches to HDR to watch a video, we won't know that here, and + // if no displays are connected we return false (e.g. if Windows Update + // restarted a laptop with its lid closed and no external displays, we will + // see zero outputs here when the app is restarted automatically). + // + // It would be better to track if HDR is ever used and report that telemetry + // so we know if HDR matters, not just when it is detected at app start. + // + // Further reading: + // https://learn.microsoft.com/en-us/windows/win32/direct3darticles/high-dynamic-range + // https://learn.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-displayconfig_sdr_white_level DeviceManagerDx* dx = DeviceManagerDx::Get(); nsTArray<DXGI_OUTPUT_DESC1> outputs = dx->EnumerateOutputs(); for (auto& output : outputs) { - if (output.BitsPerColor <= 8) { - continue; - } - - switch (output.ColorSpace) { - case DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P2020: - case DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P2020: - case DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P2020: - case DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020: - case DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_LEFT_P2020: - case DXGI_COLOR_SPACE_RGB_STUDIO_G2084_NONE_P2020: - case DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_TOPLEFT_P2020: - case DXGI_COLOR_SPACE_YCBCR_STUDIO_G2084_TOPLEFT_P2020: - case DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P2020: - case DXGI_COLOR_SPACE_YCBCR_STUDIO_GHLG_TOPLEFT_P2020: - case DXGI_COLOR_SPACE_YCBCR_FULL_GHLG_TOPLEFT_P2020: -#ifndef __MINGW32__ - // Windows MinGW has an older dxgicommon.h that doesn't define - // these enums. We'd like to define them ourselves in that case, - // but there's no compilable way to add new enums to an existing - // enum type. So instead we just don't check for these values. - case DXGI_COLOR_SPACE_RGB_STUDIO_G24_NONE_P2020: - case DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_LEFT_P2020: - case DXGI_COLOR_SPACE_YCBCR_STUDIO_G24_TOPLEFT_P2020: -#endif - mSupportsHDR = true; - return; - default: - break; + if (output.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) { + mSupportsHDR = true; + return; } } diff --git a/gfx/thebes/moz.build b/gfx/thebes/moz.build index fd1fcf236d..3d99906827 100644 --- a/gfx/thebes/moz.build +++ b/gfx/thebes/moz.build @@ -96,16 +96,13 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "android": "gfxFT2Utils.cpp", "PrintTargetPDF.cpp", ] -elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": +elif CONFIG["MOZ_WIDGET_TOOLKIT"] in ("cocoa", "uikit"): EXPORTS += [ "gfxMacUtils.h", "gfxPlatformMac.h", "gfxQuartzNativeDrawing.h", "gfxQuartzSurface.h", ] - EXPORTS.mozilla.gfx += [ - "PrintTargetCG.h", - ] SOURCES += [ "CoreTextFontList.cpp", "gfxCoreTextShaper.cpp", @@ -114,8 +111,14 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": "gfxPlatformMac.cpp", "gfxQuartzNativeDrawing.cpp", "gfxQuartzSurface.cpp", - "PrintTargetCG.mm", ] + if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": + EXPORTS.mozilla.gfx += [ + "PrintTargetCG.h", + ] + SOURCES += [ + "PrintTargetCG.mm", + ] elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": EXPORTS += [ "gfxFT2FontBase.h", @@ -239,6 +242,10 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa": UNIFIED_SOURCES += [ "gfxMacPlatformFontList.mm", ] +elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "uikit": + UNIFIED_SOURCES += [ + "IOSPlatformFontList.mm", + ] elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows": UNIFIED_SOURCES += [ "D3D11Checks.cpp", |