source: webkit/trunk/Source/WebCore/css/CSSFontFace.h

Last change on this file was 286625, checked in by Cameron McCormack, 3 years ago

Move FontCache singleton and instance on WorkerGlobalScope to ThreadGlobalData
https://bugs.webkit.org/show_bug.cgi?id=233747

Reviewed by Darin Adler.

Source/WebCore:

There are various places in font code where we need access to a
FontCache instance. Currently we:

  • assume that we're on the main thread and call FontCache::singleton(), or
  • get a FontCache off WorkerGlobalScope and pass it down (or store it) where it's needed, then pass it to fontCacheFallingBackToSingleton.

Having to thread through, or store, the FontCache pointer is
inconvenient, and there are some places where we don't have access to
a FontCache pointer, but we're on a worker, and we call
fontCacheFallingBackToSingleton and incorrectly get back the main
thread's instance.

I think it would be cleaner if we moved both the main thread FontCache
singleton, and the one stored on a WorkerGlobalScope, to
ThreadGlobalData, which is easily globally accessible. Performing a
TLS lookup is cheap these days.

  • css/CSSFontFace.h:
  • css/CSSFontFace.cpp:

(WebCore::CSSFontFace::font):
(WebCore::CSSFontFace::fontCacheFallingBackToSingleton):
Remove fontCacheFallingBackToSingleton and replace calls to it with
FontCache::forCurrentThread.

  • css/CSSFontFaceSet.cpp:

(WebCore::CSSFontFaceSet::ensureLocalFontFacesForFamilyRegistered):
Replace getting the FontCache from the ScriptExecutionContext with a
call to FontCache::forCurrentThread.

  • css/CSSFontFaceSource.cpp:

(WebCore::CSSFontFaceSource::load):
(WebCore::CSSFontFaceSource::font):

  • editing/cocoa/FontAttributeChangesCocoa.mm:

(WebCore::FontChanges::platformFontFamilyNameForCSS const):

  • inspector/agents/InspectorCSSAgent.cpp:

(WebCore::InspectorCSSAgent::getSupportedSystemFontFamilyNames):

  • page/MemoryRelease.cpp:

(WebCore::releaseNoncriticalMemory):

  • page/ProcessWarming.cpp:

(WebCore::ProcessWarming::prewarmGlobally):
(WebCore::ProcessWarming::collectPrewarmInformation):
(WebCore::ProcessWarming::prewarmWithInformation):

  • page/SettingsBase.cpp:

(WebCore::invalidateAfterGenericFamilyChange):
Replace calls to FontCache::singleton with calls to
FontCache::forCurrentThread.

  • css/CSSFontSelector.h:
  • css/CSSFontSelector.cpp:

(WebCore::CSSFontSelector::CSSFontSelector):
(WebCore::CSSFontSelector::~CSSFontSelector):
(WebCore::CSSFontSelector::fontRangesForFamily):
(WebCore::CSSFontSelector::fallbackFontAt):
Remove CSSFontSelector::m_fontCache and use
FontCache::forCurrentThread instead. For the CSSFontSelector
destructor, we call forCurrentThreadIfNotDestroyed since it
can run after ThreadGlobalData::destroy has been called for
a worker, and we don't want to cause a fresh FontCache object to be
created at this point.

  • dom/ScriptExecutionContext.h:
  • dom/ScriptExecutionContext.cpp:

(WebCore::ScriptExecutionContext::fontCache):
Remove the FontCache member.

  • platform/ThreadGlobalData.h:

(WebCore::ThreadGlobalData::ThreadGlobalData::cachedResourceRequestInitiators):
(WebCore::ThreadGlobalData::ThreadGlobalData::eventNames):
(WebCore::ThreadGlobalData::ThreadGlobalData::qualifiedNameCache):
(WebCore::ThreadGlobalData::ThreadGlobalData::mimeTypeRegistryThreadGlobalData):
(WebCore::ThreadGlobalData::ThreadGlobalData::fontCache):
(WebCore::ThreadGlobalData::ThreadGlobalData::fontCacheIfNotDestroyed):

  • platform/ThreadGlobalData.cpp:

(WebCore::ThreadGlobalData::destroy):
(WebCore::ThreadGlobalData::initializeFontCache):
Add accessors for a lazily created FontCache. Also record whether
destroy has been called on the ThreadGlobalData so that
fontCacheIfNotDestroyed can check it, and the other lazy object
creation methods can assert destroy hasn't been called yet.

  • platform/graphics/Font.h:
  • platform/graphics/Font.cpp:

(WebCore::Font::create):
(WebCore::Font::Font):
(WebCore::Font::systemFallbackFontForCharacter const):

  • platform/graphics/FontCache.cpp:

(WebCore::FontCache::fontForPlatformData):

  • workers/WorkerFontLoadRequest.cpp:

(WebCore::WorkerFontLoadRequest::createFont):
Remove FontCache arguments and use FontCache::forCurrentThread in
their place.

  • platform/graphics/FontCache.cpp:

(WebCore::FontCache::create): Removed.
(WebCore::FontCache::singleton):
(WebCore::FontCache::forCurrentThread):
Replace FontCache::singleton with FontCache::forCurrentThread, which
looks up the FontCache on ThreadGlobalData.
(WebCore::FontCache::invalidateAllFontCaches):
New function that will in the future invalidate the main thread and
all worker thread FontCaches.

  • platform/graphics/FontCache.h:

Remove refcounting from FontCache since we no longer need to store a
strong reference to it on other objects.
(WebCore::FontCache::fontCacheFallingBackToSingleton): Deleted.

  • platform/graphics/FontCascade.cpp:

(WebCore::FontCascade::isCurrent const):
(WebCore::FontCascade::update const):
Call FontCache::forCurrentThread instead of getting it from the
FontSelector.

  • platform/graphics/FontCascadeFonts.cpp:

(WebCore::FontCascadeFonts::FontCascadeFonts):
(WebCore::realizeNextFallback):
(WebCore::FontCascadeFonts::realizeFallbackRangesAt):
(WebCore::FontCascadeFonts::glyphDataForSystemFallback):

  • platform/graphics/cairo/FontCairoHarfbuzzNG.cpp:

(WebCore::FontCascade::fontForCombiningCharacterSequence const):
Use FontCache::forCurrentThread.

  • platform/graphics/FontSelector.h:

Remove fontCache method.

  • platform/graphics/cocoa/FontCacheCoreText.cpp:

(WebCore::fontCacheRegisteredFontsChangedNotificationCallback):
(WebCore::fontWithFamilySpecialCase):
(WebCore::FontCache::prewarmGlobally):

  • platform/graphics/cocoa/FontFamilySpecificationCoreText.cpp:

(WebCore::FontFamilySpecificationCoreText::fontRanges const):

  • platform/graphics/cocoa/SystemFontDatabaseCoreText.cpp:

(WebCore::SystemFontDatabaseCoreText::systemFontParameters):

  • platform/graphics/mac/ComplexTextControllerCoreText.mm:

(WebCore::ComplexTextController::collectComplexTextRunsForCharacters):

  • testing/InternalSettings.cpp:

(WebCore::InternalSettings::Backup::restoreTo):
(WebCore::InternalSettings::setShouldMockBoldSystemFontForAccessibility):
Use FontCache::forCurrentThread.

  • platform/graphics/cocoa/FontCacheCoreText.cpp:

(WebCore::invalidateFontCache):

  • testing/Internals.cpp:

(WebCore::Internals::invalidateFontCache):
Call the new FontCache::invalidateAllFontCaches.

  • platform/graphics/win/FontCacheWin.cpp:

(WebCore::getCJKCodePageMasks):
(WebCore::FontCache::systemFallbackForCharacters):
Use the FontCache instance we have access to rather than call
FontCache::singleton.

  • workers/WorkerGlobalScope.h:
  • workers/WorkerGlobalScope.cpp:

(WebCore::WorkerGlobalScope::fontCache):
Remove the FontCache member and accessor.

Source/WebKit:

  • WebProcess/WebProcess.cpp:

(WebKit::WebProcess::terminate):
Update existing main threa callers of FontCache::singleton() to use
FontCache::forCurrentThread().

Source/WebKitLegacy/mac:

  • Misc/WebCoreStatistics.mm:

(+[WebCoreStatistics cachedFontDataCount]):
(+[WebCoreStatistics cachedFontDataInactiveCount]):
(+[WebCoreStatistics purgeInactiveFontData]):
Update existing main thread callers of FontCache::singleton() to use
FontCache::forCurrentThread().

Source/WebKitLegacy/win:

  • WebCoreStatistics.cpp:

(WebCoreStatistics::cachedFontDataCount):
(WebCoreStatistics::cachedFontDataInactiveCount):
(WebCoreStatistics::purgeInactiveFontData):
Update existing main thread callers of FontCache::singleton() to use
FontCache::forCurrentThread().

  • Property svn:eol-style set to native
File size: 8.5 KB
Line 
1/*
2 * Copyright (C) 2007-2021 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "FontSelectionValueInlines.h"
29#include "FontTaggedSettings.h"
30#include "Settings.h"
31#include "StyleRule.h"
32#include "TextFlags.h"
33#include <memory>
34#include <wtf/Forward.h>
35#include <wtf/HashSet.h>
36#include <wtf/WeakPtr.h>
37
38namespace JSC {
39class CallFrame;
40}
41
42namespace WebCore {
43
44class CSSFontFaceSource;
45class CSSFontSelector;
46class CSSSegmentedFontFace;
47class CSSValue;
48class CSSValueList;
49class FontCreationContext;
50class FontDescription;
51class Font;
52class FontFace;
53class ScriptExecutionContext;
54enum class ExternalResourceDownloadPolicy;
55
56DECLARE_ALLOCATOR_WITH_HEAP_IDENTIFIER(CSSFontFace);
57class CSSFontFace final : public RefCounted<CSSFontFace> {
58 WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(CSSFontFace);
59public:
60 static Ref<CSSFontFace> create(CSSFontSelector&, StyleRuleFontFace* cssConnection = nullptr, FontFace* wrapper = nullptr, bool isLocalFallback = false);
61 virtual ~CSSFontFace();
62
63 // FIXME: These functions don't need to have boolean return values.
64 // Callers only call this with known-valid CSS values.
65 bool setFamilies(CSSValue&);
66 void setStyle(CSSValue&);
67 void setWeight(CSSValue&);
68 void setStretch(CSSValue&);
69 bool setUnicodeRange(CSSValue&);
70 void setFeatureSettings(CSSValue&);
71 void setLoadingBehavior(CSSValue&);
72
73 // Pending => Loading => TimedOut
74 // || \\ // ||
75 // || \\ // ||
76 // || \\// ||
77 // || // ||
78 // || //\\ ||
79 // || // \\ ||
80 // \/ \/ \/ \/
81 // Success Failure
82 enum class Status : uint8_t { Pending, Loading, TimedOut, Success, Failure };
83
84 struct UnicodeRange;
85
86 // Optional return values to represent default string for members of FontFace.h
87 const std::optional<CSSValueList*> families() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<CSSValueList*>>(m_families.get()); }
88 std::optional<FontSelectionRange> weight() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontSelectionRange>>(m_fontSelectionCapabilities.computeWeight()); }
89 std::optional<FontSelectionRange> stretch() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontSelectionRange>>(m_fontSelectionCapabilities.computeWidth()); }
90 std::optional<FontSelectionRange> italic() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontSelectionRange>>(m_fontSelectionCapabilities.computeSlope()); }
91 std::optional<FontSelectionCapabilities> fontSelectionCapabilities() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontSelectionCapabilities>>(m_fontSelectionCapabilities.computeFontSelectionCapabilities()); }
92 const std::optional<Vector<UnicodeRange>> ranges() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<Vector<UnicodeRange>>>(m_ranges); }
93 const std::optional<FontFeatureSettings> featureSettings() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontFeatureSettings>>(m_featureSettings); }
94 std::optional<FontLoadingBehavior> loadingBehavior() const { return m_status == Status::Failure ? std::nullopt : static_cast<std::optional<FontLoadingBehavior>>(m_loadingBehavior); }
95 void setWeight(FontSelectionRange weight) { m_fontSelectionCapabilities.weight = weight; }
96 void setStretch(FontSelectionRange stretch) { m_fontSelectionCapabilities.width = stretch; }
97 void setStyle(FontSelectionRange italic) { m_fontSelectionCapabilities.slope = italic; }
98 void setFontSelectionCapabilities(FontSelectionCapabilities capabilities) { m_fontSelectionCapabilities = capabilities; }
99 bool isLocalFallback() const { return m_isLocalFallback; }
100 Status status() const { return m_status; }
101 StyleRuleFontFace* cssConnection() const { return m_cssConnection.get(); }
102
103 class Client;
104 void addClient(Client&);
105 void removeClient(Client&);
106
107 bool computeFailureState() const;
108
109 void opportunisticallyStartFontDataURLLoading();
110
111 void adoptSource(std::unique_ptr<CSSFontFaceSource>&&);
112 void sourcesPopulated() { m_sourcesPopulated = true; }
113
114 void fontLoaded(CSSFontFaceSource&);
115
116 void load();
117
118 RefPtr<Font> font(const FontDescription&, bool syntheticBold, bool syntheticItalic, ExternalResourceDownloadPolicy, const FontPaletteValues&);
119
120 static void appendSources(CSSFontFace&, CSSValueList&, ScriptExecutionContext*, bool isInitiatingElementInUserAgentShadowTree);
121
122 class Client {
123 public:
124 virtual ~Client() = default;
125 virtual void fontLoaded(CSSFontFace&) { }
126 virtual void fontStateChanged(CSSFontFace&, Status /*oldState*/, Status /*newState*/) { }
127 virtual void fontPropertyChanged(CSSFontFace&, CSSValueList* /*oldFamilies*/ = nullptr) { }
128 virtual void updateStyleIfNeeded(CSSFontFace&) { }
129 virtual void ref() = 0;
130 virtual void deref() = 0;
131 };
132
133 struct UnicodeRange {
134 UChar32 from;
135 UChar32 to;
136 bool operator==(const UnicodeRange& other) const { return from == other.from && to == other.to; }
137 bool operator!=(const UnicodeRange& other) const { return !(*this == other); }
138 };
139
140 bool rangesMatchCodePoint(UChar32) const;
141
142 // We don't guarantee that the FontFace wrapper will be the same every time you ask for it.
143 Ref<FontFace> wrapper(ScriptExecutionContext*);
144 void setWrapper(FontFace&);
145 FontFace* existingWrapper();
146
147 struct FontLoadTiming {
148 Seconds blockPeriod;
149 Seconds swapPeriod;
150 };
151 FontLoadTiming fontLoadTiming() const;
152 bool shouldIgnoreFontLoadCompletions() const { return m_shouldIgnoreFontLoadCompletions; }
153
154 bool purgeable() const;
155
156 AllowUserInstalledFonts allowUserInstalledFonts() const { return m_allowUserInstalledFonts; }
157
158 void updateStyleIfNeeded();
159
160 bool hasSVGFontFaceSource() const;
161 void setErrorState();
162
163private:
164 CSSFontFace(const Settings::Values*, StyleRuleFontFace*, FontFace*, bool isLocalFallback);
165
166 size_t pump(ExternalResourceDownloadPolicy);
167 void setStatus(Status);
168 void notifyClientsOfFontPropertyChange();
169
170 void initializeWrapper();
171
172 void fontLoadEventOccurred();
173 void timeoutFired();
174
175 Document* document();
176
177 RefPtr<CSSValueList> m_families;
178 Vector<UnicodeRange> m_ranges;
179
180 FontFeatureSettings m_featureSettings;
181 FontLoadingBehavior m_loadingBehavior { FontLoadingBehavior::Auto };
182
183 Vector<std::unique_ptr<CSSFontFaceSource>, 0, CrashOnOverflow, 0> m_sources;
184 RefPtr<StyleRuleFontFace> m_cssConnection;
185 HashSet<Client*> m_clients;
186 WeakPtr<FontFace> m_wrapper;
187 FontSelectionSpecifiedCapabilities m_fontSelectionCapabilities;
188
189 Status m_status { Status::Pending };
190 bool m_isLocalFallback { false };
191 bool m_sourcesPopulated { false };
192 bool m_mayBePurged { true };
193 bool m_shouldIgnoreFontLoadCompletions { false };
194 FontLoadTimingOverride m_fontLoadTimingOverride { FontLoadTimingOverride::None };
195 AllowUserInstalledFonts m_allowUserInstalledFonts { AllowUserInstalledFonts::Yes };
196
197 Timer m_timeoutTimer;
198};
199
200}
Note: See TracBrowser for help on using the repository browser.