- Revision
- 237116
- Author
- an...@apple.com
- Date
- 2018-10-15 09:02:35 -0700 (Mon, 15 Oct 2018)
Log Message
[PSON] Prewarm system fallback fonts
https://bugs.webkit.org/show_bug.cgi?id=190517
Reviewed by Ryosuke Niwa.
This seems to be ~2% progression in PSON PLT4 with large (40ms+) improvements on some pages
after process swaps.
* page/PrewarmInformation.h:
(WebCore::PrewarmInformation::encode const):
(WebCore::PrewarmInformation::decode):
* page/ProcessWarming.cpp:
(WebCore::ProcessWarming::collectPrewarmInformation):
(WebCore::ProcessWarming::prewarmWithInformation):
* platform/graphics/FontCache.cpp:
(WebCore::FontCache::collectPrewarmInformation const):
(WebCore::FontCache::prewarm):
* platform/graphics/FontCache.h:
(WebCore::FontCache::PrewarmInformation::isolatedCopy const):
(WebCore::FontCache::PrewarmInformation::encode const):
(WebCore::FontCache::PrewarmInformation::decode):
Make font cache prewarm information a struct with encode/decode support and move it into FontCache scope.
* platform/graphics/cocoa/FontCacheCoreText.cpp:
(WebCore::FontDatabase::collectionForFamily):
(WebCore::FontCache::systemFallbackForCharacters):
Collect the names of fonts that end up needing character specific system fallbacks.
(WebCore::FontCache::collectPrewarmInformation const):
Include them into prewarm information.
(WebCore::FontCache::prewarm):
Invoking CTFontCreateForCharactersWithLanguage for the correct named font seems sufficient to fully
prewarm it for fallbacks (independent of size, locale or other characteristics).
Any future calls to systemFallbackForCharacters are fast.
Modified Paths
Diff
Modified: trunk/Source/WebCore/ChangeLog (237115 => 237116)
--- trunk/Source/WebCore/ChangeLog 2018-10-15 15:54:50 UTC (rev 237115)
+++ trunk/Source/WebCore/ChangeLog 2018-10-15 16:02:35 UTC (rev 237116)
@@ -1,3 +1,45 @@
+2018-10-15 Antti Koivisto <an...@apple.com>
+
+ [PSON] Prewarm system fallback fonts
+ https://bugs.webkit.org/show_bug.cgi?id=190517
+
+ Reviewed by Ryosuke Niwa.
+
+ This seems to be ~2% progression in PSON PLT4 with large (40ms+) improvements on some pages
+ after process swaps.
+
+ * page/PrewarmInformation.h:
+ (WebCore::PrewarmInformation::encode const):
+ (WebCore::PrewarmInformation::decode):
+ * page/ProcessWarming.cpp:
+ (WebCore::ProcessWarming::collectPrewarmInformation):
+ (WebCore::ProcessWarming::prewarmWithInformation):
+ * platform/graphics/FontCache.cpp:
+ (WebCore::FontCache::collectPrewarmInformation const):
+ (WebCore::FontCache::prewarm):
+ * platform/graphics/FontCache.h:
+ (WebCore::FontCache::PrewarmInformation::isolatedCopy const):
+ (WebCore::FontCache::PrewarmInformation::encode const):
+ (WebCore::FontCache::PrewarmInformation::decode):
+
+ Make font cache prewarm information a struct with encode/decode support and move it into FontCache scope.
+
+ * platform/graphics/cocoa/FontCacheCoreText.cpp:
+ (WebCore::FontDatabase::collectionForFamily):
+ (WebCore::FontCache::systemFallbackForCharacters):
+
+ Collect the names of fonts that end up needing character specific system fallbacks.
+
+ (WebCore::FontCache::collectPrewarmInformation const):
+
+ Include them into prewarm information.
+
+ (WebCore::FontCache::prewarm):
+
+ Invoking CTFontCreateForCharactersWithLanguage for the correct named font seems sufficient to fully
+ prewarm it for fallbacks (independent of size, locale or other characteristics).
+ Any future calls to systemFallbackForCharacters are fast.
+
2018-10-15 Chris Dumez <cdu...@apple.com>
Restrict browsing context lookup by name to frames that are related to one another
Modified: trunk/Source/WebCore/page/PrewarmInformation.h (237115 => 237116)
--- trunk/Source/WebCore/page/PrewarmInformation.h 2018-10-15 15:54:50 UTC (rev 237115)
+++ trunk/Source/WebCore/page/PrewarmInformation.h 2018-10-15 16:02:35 UTC (rev 237116)
@@ -32,7 +32,7 @@
namespace WebCore {
struct WEBCORE_EXPORT PrewarmInformation {
- FontPrewarmInformation font;
+ FontCache::PrewarmInformation fontCache;
template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static std::optional<PrewarmInformation> decode(Decoder&);
@@ -41,17 +41,18 @@
template<class Encoder>
void PrewarmInformation::encode(Encoder& encoder) const
{
- encoder << font;
+ encoder << fontCache;
}
template<class Decoder>
std::optional<PrewarmInformation> PrewarmInformation::decode(Decoder& decoder)
{
- PrewarmInformation prewarmInfo;
- if (!decoder.decode(prewarmInfo.font))
+ std::optional<FontCache::PrewarmInformation> fontCachePrewarmInformation;
+ decoder >> fontCachePrewarmInformation;
+ if (!fontCachePrewarmInformation)
return { };
- return prewarmInfo;
+ return PrewarmInformation { WTFMove(*fontCachePrewarmInformation) };
}
}
Modified: trunk/Source/WebCore/page/ProcessWarming.cpp (237115 => 237116)
--- trunk/Source/WebCore/page/ProcessWarming.cpp 2018-10-15 15:54:50 UTC (rev 237115)
+++ trunk/Source/WebCore/page/ProcessWarming.cpp 2018-10-15 16:02:35 UTC (rev 237116)
@@ -88,14 +88,12 @@
WebCore::PrewarmInformation ProcessWarming::collectPrewarmInformation()
{
- PrewarmInformation info;
- info.font = FontCache::singleton().collectPrewarmInformation();
- return info;
+ return { FontCache::singleton().collectPrewarmInformation() };
}
void ProcessWarming::prewarmWithInformation(const PrewarmInformation& prewarmInfo)
{
- FontCache::singleton().prewarm(prewarmInfo.font);
+ FontCache::singleton().prewarm(prewarmInfo.fontCache);
}
}
Modified: trunk/Source/WebCore/platform/graphics/FontCache.cpp (237115 => 237116)
--- trunk/Source/WebCore/platform/graphics/FontCache.cpp 2018-10-15 15:54:50 UTC (rev 237115)
+++ trunk/Source/WebCore/platform/graphics/FontCache.cpp 2018-10-15 16:02:35 UTC (rev 237116)
@@ -483,12 +483,12 @@
#if !PLATFORM(COCOA)
-FontPrewarmInformation FontCache::collectPrewarmInformation() const
+FontCache::PrewarmInformation FontCache::collectPrewarmInformation() const
{
return { };
}
-void FontCache::prewarm(const FontPrewarmInformation&)
+void FontCache::prewarm(const PrewarmInformation&)
{
}
Modified: trunk/Source/WebCore/platform/graphics/FontCache.h (237115 => 237116)
--- trunk/Source/WebCore/platform/graphics/FontCache.h 2018-10-15 15:54:50 UTC (rev 237115)
+++ trunk/Source/WebCore/platform/graphics/FontCache.h 2018-10-15 16:02:35 UTC (rev 237116)
@@ -69,8 +69,6 @@
#endif
#endif
-using FontPrewarmInformation = Vector<String>;
-
// This key contains the FontDescription fields other than family that matter when fetching FontDatas (platform fonts).
struct FontDescriptionKey {
FontDescriptionKey() = default;
@@ -239,9 +237,19 @@
bool shouldMockBoldSystemFontForAccessibility() const { return m_shouldMockBoldSystemFontForAccessibility; }
void setShouldMockBoldSystemFontForAccessibility(bool shouldMockBoldSystemFontForAccessibility) { m_shouldMockBoldSystemFontForAccessibility = shouldMockBoldSystemFontForAccessibility; }
- FontPrewarmInformation collectPrewarmInformation() const;
- void prewarm(const FontPrewarmInformation&);
+ struct PrewarmInformation {
+ Vector<String> seenFamilies;
+ Vector<String> fontNamesRequiringSystemFallback;
+ bool isEmpty() const;
+ PrewarmInformation isolatedCopy() const;
+
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static std::optional<PrewarmInformation> decode(Decoder&);
+ };
+ PrewarmInformation collectPrewarmInformation() const;
+ void prewarm(const PrewarmInformation&);
+
private:
FontCache();
~FontCache() = delete;
@@ -266,6 +274,7 @@
#if PLATFORM(COCOA)
ListHashSet<String> m_seenFamiliesForPrewarming;
+ ListHashSet<String> m_fontNamesRequiringSystemFallbackForPrewarming;
RefPtr<WorkQueue> m_prewarmQueue;
friend class ComplexTextController;
@@ -286,4 +295,34 @@
#endif
+
+inline bool FontCache::PrewarmInformation::isEmpty() const
+{
+ return seenFamilies.isEmpty() && fontNamesRequiringSystemFallback.isEmpty();
}
+
+inline FontCache::PrewarmInformation FontCache::PrewarmInformation::isolatedCopy() const
+{
+ return { seenFamilies.isolatedCopy(), fontNamesRequiringSystemFallback.isolatedCopy() };
+}
+
+template<class Encoder>
+void FontCache::PrewarmInformation::encode(Encoder& encoder) const
+{
+ encoder << seenFamilies;
+ encoder << fontNamesRequiringSystemFallback;
+}
+
+template<class Decoder>
+std::optional<FontCache::PrewarmInformation> FontCache::PrewarmInformation::decode(Decoder& decoder)
+{
+ PrewarmInformation prewarmInformation;
+ if (!decoder.decode(prewarmInformation.seenFamilies))
+ return { };
+ if (!decoder.decode(prewarmInformation.fontNamesRequiringSystemFallback))
+ return { };
+
+ return prewarmInformation;
+}
+
+}
Modified: trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp (237115 => 237116)
--- trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp 2018-10-15 15:54:50 UTC (rev 237115)
+++ trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp 2018-10-15 16:02:35 UTC (rev 237116)
@@ -916,7 +916,7 @@
}();
std::lock_guard<Lock> locker(m_familyNameToFontDescriptorsLock);
- return m_familyNameToFontDescriptors.add(folded.isolatedCopy(), installedFontFamily).iterator->value;
+ return m_familyNameToFontDescriptors.add(folded.isolatedCopy(), WTFMove(installedFontFamily)).iterator->value;
}
const InstalledFont& fontForPostScriptName(const AtomicString& postScriptName)
@@ -1366,8 +1366,14 @@
#endif
const FontPlatformData& platformData = originalFontData->platformData();
+
+ auto fullName = String(adoptCF(CTFontCopyFullName(platformData.font())).get());
+ if (!fullName.isEmpty())
+ m_fontNamesRequiringSystemFallbackForPrewarming.add(fullName);
+
auto result = lookupFallbackFont(platformData.font(), description.weight(), description.locale(), characters, length);
result = preparePlatformFont(result.get(), description, nullptr, nullptr, { }, description.computedSize());
+
if (!result)
return lastResortFallbackFont(description);
@@ -1519,18 +1525,14 @@
return fontForPlatformData(platformData);
}
-FontPrewarmInformation FontCache::collectPrewarmInformation() const
+FontCache::PrewarmInformation FontCache::collectPrewarmInformation() const
{
- FontPrewarmInformation fontPrewarmInformation;
- fontPrewarmInformation = copyToVector(m_seenFamiliesForPrewarming);
- return fontPrewarmInformation;
+ return { copyToVector(m_seenFamiliesForPrewarming), copyToVector(m_fontNamesRequiringSystemFallbackForPrewarming) };
}
-void FontCache::prewarm(const FontPrewarmInformation& fontPrewarmInformation)
+void FontCache::prewarm(const PrewarmInformation& prewarmInformation)
{
- auto& families = fontPrewarmInformation;
-
- if (families.isEmpty())
+ if (prewarmInformation.isEmpty())
return;
if (!m_prewarmQueue)
@@ -1538,9 +1540,19 @@
auto& database = FontDatabase::singletonDisallowingUserInstalledFonts();
- m_prewarmQueue->dispatch([&database, families = families.isolatedCopy()] {
- for (auto& family : families)
+ m_prewarmQueue->dispatch([&database, prewarmInformation = prewarmInformation.isolatedCopy()] {
+ for (auto& family : prewarmInformation.seenFamilies)
database.collectionForFamily(family);
+
+ for (auto& fontName : prewarmInformation.fontNamesRequiringSystemFallback) {
+ auto cfFontName = fontName.createCFString();
+ if (auto warmingFont = adoptCF(CTFontCreateWithName(cfFontName.get(), 0, nullptr))) {
+ // This is sufficient to warm CoreText caches for language and character specific fallbacks.
+ CFIndex coveredLength = 0;
+ UChar character = ' ';
+ auto fallbackWarmingFont = adoptCF(CTFontCreateForCharactersWithLanguage(warmingFont.get(), &character, 1, nullptr, &coveredLength));
+ }
+ }
});
}