Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp

Issue 2717123003: RemoteFontFaceSource should keep FontCustomPlatformData over FontResource revalidation (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/css/RemoteFontFaceSource.h" 5 #include "core/css/RemoteFontFaceSource.h"
6 6
7 #include "core/css/CSSCustomFontData.h" 7 #include "core/css/CSSCustomFontData.h"
8 #include "core/css/CSSFontFace.h" 8 #include "core/css/CSSFontFace.h"
9 #include "core/css/CSSFontSelector.h" 9 #include "core/css/CSSFontSelector.h"
10 #include "core/dom/Document.h" 10 #include "core/dom/Document.h"
11 #include "core/inspector/ConsoleMessage.h" 11 #include "core/inspector/ConsoleMessage.h"
12 #include "core/loader/FrameLoaderClient.h" 12 #include "core/loader/FrameLoaderClient.h"
13 #include "core/page/NetworkStateNotifier.h" 13 #include "core/page/NetworkStateNotifier.h"
14 #include "platform/Histogram.h" 14 #include "platform/Histogram.h"
15 #include "platform/RuntimeEnabledFeatures.h" 15 #include "platform/RuntimeEnabledFeatures.h"
16 #include "platform/fonts/FontCache.h" 16 #include "platform/fonts/FontCache.h"
17 #include "platform/fonts/FontCustomPlatformData.h"
17 #include "platform/fonts/FontDescription.h" 18 #include "platform/fonts/FontDescription.h"
18 #include "platform/fonts/SimpleFontData.h" 19 #include "platform/fonts/SimpleFontData.h"
19 #include "platform/loader/fetch/ResourceFetcher.h" 20 #include "platform/loader/fetch/ResourceFetcher.h"
20 #include "platform/network/ResourceLoadPriority.h" 21 #include "platform/network/ResourceLoadPriority.h"
21 #include "public/platform/WebEffectiveConnectionType.h" 22 #include "public/platform/WebEffectiveConnectionType.h"
22 #include "wtf/CurrentTime.h" 23 #include "wtf/CurrentTime.h"
23 24
24 namespace blink { 25 namespace blink {
25 26
26 namespace { 27 namespace {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create( 73 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create(
73 OtherMessageSource, InfoMessageLevel, 74 OtherMessageSource, InfoMessageLevel,
74 "Slow network is detected. Fallback font will be used while loading: " + 75 "Slow network is detected. Fallback font will be used while loading: " +
75 m_font->url().elidedString())); 76 m_font->url().elidedString()));
76 } 77 }
77 } 78 }
78 79
79 RemoteFontFaceSource::~RemoteFontFaceSource() {} 80 RemoteFontFaceSource::~RemoteFontFaceSource() {}
80 81
81 void RemoteFontFaceSource::dispose() { 82 void RemoteFontFaceSource::dispose() {
82 m_font->removeClient(this); 83 if (m_font) {
83 m_font = nullptr; 84 m_font->removeClient(this);
85 m_font = nullptr;
86 }
84 pruneTable(); 87 pruneTable();
85 } 88 }
86 89
87 void RemoteFontFaceSource::pruneTable() { 90 void RemoteFontFaceSource::pruneTable() {
88 if (m_fontDataTable.isEmpty()) 91 if (m_fontDataTable.isEmpty())
89 return; 92 return;
90 93
91 for (const auto& item : m_fontDataTable) { 94 for (const auto& item : m_fontDataTable) {
92 SimpleFontData* fontData = item.value.get(); 95 SimpleFontData* fontData = item.value.get();
93 if (fontData && fontData->customFontData()) 96 if (fontData && fontData->customFontData())
94 fontData->customFontData()->clearFontFaceSource(); 97 fontData->customFontData()->clearFontFaceSource();
95 } 98 }
96 m_fontDataTable.clear(); 99 m_fontDataTable.clear();
97 } 100 }
98 101
99 bool RemoteFontFaceSource::isLoading() const { 102 bool RemoteFontFaceSource::isLoading() const {
100 return m_font->isLoading(); 103 return m_font && m_font->isLoading();
101 } 104 }
102 105
103 bool RemoteFontFaceSource::isLoaded() const { 106 bool RemoteFontFaceSource::isLoaded() const {
104 return m_font->isLoaded(); 107 return !m_font;
105 } 108 }
106 109
107 bool RemoteFontFaceSource::isValid() const { 110 bool RemoteFontFaceSource::isValid() const {
108 return !m_font->errorOccurred(); 111 return m_font || m_customFontData;
109 } 112 }
110 113
111 void RemoteFontFaceSource::notifyFinished(Resource*) { 114 void RemoteFontFaceSource::notifyFinished(Resource* unusedResource) {
115 DCHECK_EQ(unusedResource, m_font);
112 m_histograms.maySetDataSource(m_font->response().wasCached() 116 m_histograms.maySetDataSource(m_font->response().wasCached()
113 ? FontLoadHistograms::FromDiskCache 117 ? FontLoadHistograms::FromDiskCache
114 : FontLoadHistograms::FromNetwork); 118 : FontLoadHistograms::FromNetwork);
115 m_histograms.recordRemoteFont(m_font.get(), m_isInterventionTriggered); 119 m_histograms.recordRemoteFont(m_font.get(), m_isInterventionTriggered);
116 m_histograms.fontLoaded(m_font->isCORSFailed(), 120 m_histograms.fontLoaded(m_font->isCORSFailed(),
117 m_font->getStatus() == ResourceStatus::LoadError, 121 m_font->getStatus() == ResourceStatus::LoadError,
118 m_isInterventionTriggered); 122 m_isInterventionTriggered);
119 123
120 m_font->ensureCustomFontData(); 124 m_customFontData = m_font->getCustomFontData();
125
121 // FIXME: Provide more useful message such as OTS rejection reason. 126 // FIXME: Provide more useful message such as OTS rejection reason.
122 // See crbug.com/97467 127 // See crbug.com/97467
123 if (m_font->getStatus() == ResourceStatus::DecodeError && 128 if (m_font->getStatus() == ResourceStatus::DecodeError &&
124 m_fontSelector->document()) { 129 m_fontSelector->document()) {
125 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create( 130 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create(
126 OtherMessageSource, WarningMessageLevel, 131 OtherMessageSource, WarningMessageLevel,
127 "Failed to decode downloaded font: " + m_font->url().elidedString())); 132 "Failed to decode downloaded font: " + m_font->url().elidedString()));
128 if (m_font->otsParsingMessage().length() > 1) 133 if (m_font->otsParsingMessage().length() > 1)
129 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create( 134 m_fontSelector->document()->addConsoleMessage(ConsoleMessage::create(
130 OtherMessageSource, WarningMessageLevel, 135 OtherMessageSource, WarningMessageLevel,
131 "OTS parsing error: " + m_font->otsParsingMessage())); 136 "OTS parsing error: " + m_font->otsParsingMessage()));
132 } 137 }
133 138
139 m_font->removeClient(this);
140 m_font = nullptr;
hiroshige 2017/02/28 00:18:28 I love clearing |m_font| here, but clearing |m_fon
Kunihiko Sakamoto 2017/02/28 04:04:02 Good point. For @font-face fonts, CSSFontFaceSrcV
Takashi Toyoshima 2017/03/01 06:44:07 https://www.chromestatus.com/metrics/feature/popul
141
134 pruneTable(); 142 pruneTable();
135 if (m_face) { 143 if (m_face) {
136 m_fontSelector->fontFaceInvalidated(); 144 m_fontSelector->fontFaceInvalidated();
137 m_face->fontLoaded(this); 145 m_face->fontLoaded(this);
138 } 146 }
139 } 147 }
140 148
141 void RemoteFontFaceSource::fontLoadShortLimitExceeded(FontResource*) { 149 void RemoteFontFaceSource::fontLoadShortLimitExceeded(FontResource*) {
142 if (m_font->isLoaded()) 150 if (isLoaded())
143 return; 151 return;
144 152
145 if (m_display == FontDisplayFallback) 153 if (m_display == FontDisplayFallback)
146 switchToSwapPeriod(); 154 switchToSwapPeriod();
147 else if (m_display == FontDisplayOptional) 155 else if (m_display == FontDisplayOptional)
148 switchToFailurePeriod(); 156 switchToFailurePeriod();
149 } 157 }
150 158
151 void RemoteFontFaceSource::fontLoadLongLimitExceeded(FontResource*) { 159 void RemoteFontFaceSource::fontLoadLongLimitExceeded(FontResource*) {
152 if (m_font->isLoaded()) 160 if (isLoaded())
153 return; 161 return;
154 162
155 if (m_display == FontDisplayBlock || 163 if (m_display == FontDisplayBlock ||
156 (!m_isInterventionTriggered && m_display == FontDisplayAuto)) 164 (!m_isInterventionTriggered && m_display == FontDisplayAuto))
157 switchToSwapPeriod(); 165 switchToSwapPeriod();
158 else if (m_display == FontDisplayFallback) 166 else if (m_display == FontDisplayFallback)
159 switchToFailurePeriod(); 167 switchToFailurePeriod();
160 168
161 m_histograms.longLimitExceeded(m_isInterventionTriggered); 169 m_histograms.longLimitExceeded(m_isInterventionTriggered);
162 } 170 }
163 171
164 void RemoteFontFaceSource::switchToSwapPeriod() { 172 void RemoteFontFaceSource::switchToSwapPeriod() {
165 ASSERT(m_period == BlockPeriod); 173 ASSERT(m_period == BlockPeriod);
166 m_period = SwapPeriod; 174 m_period = SwapPeriod;
167 175
168 pruneTable(); 176 pruneTable();
169 if (m_face) { 177 if (m_face) {
170 m_fontSelector->fontFaceInvalidated(); 178 m_fontSelector->fontFaceInvalidated();
171 m_face->didBecomeVisibleFallback(this); 179 m_face->didBecomeVisibleFallback(this);
172 } 180 }
173 181
174 m_histograms.recordFallbackTime(m_font.get()); 182 m_histograms.recordFallbackTime();
175 } 183 }
176 184
177 void RemoteFontFaceSource::switchToFailurePeriod() { 185 void RemoteFontFaceSource::switchToFailurePeriod() {
178 if (m_period == BlockPeriod) 186 if (m_period == BlockPeriod)
179 switchToSwapPeriod(); 187 switchToSwapPeriod();
180 ASSERT(m_period == SwapPeriod); 188 ASSERT(m_period == SwapPeriod);
181 m_period = FailurePeriod; 189 m_period = FailurePeriod;
182 } 190 }
183 191
184 bool RemoteFontFaceSource::shouldTriggerWebFontsIntervention() { 192 bool RemoteFontFaceSource::shouldTriggerWebFontsIntervention() {
(...skipping 14 matching lines...) Expand all
199 207
200 return networkIsSlow && m_display == FontDisplayAuto; 208 return networkIsSlow && m_display == FontDisplayAuto;
201 } 209 }
202 210
203 bool RemoteFontFaceSource::isLowPriorityLoadingAllowedForRemoteFont() const { 211 bool RemoteFontFaceSource::isLowPriorityLoadingAllowedForRemoteFont() const {
204 return m_isInterventionTriggered; 212 return m_isInterventionTriggered;
205 } 213 }
206 214
207 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createFontData( 215 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createFontData(
208 const FontDescription& fontDescription) { 216 const FontDescription& fontDescription) {
217 if (m_period == FailurePeriod || !isValid())
218 return nullptr;
209 if (!isLoaded()) 219 if (!isLoaded())
210 return createLoadingFallbackFontData(fontDescription); 220 return createLoadingFallbackFontData(fontDescription);
221 DCHECK(m_customFontData);
211 222
212 if (!m_font->ensureCustomFontData() || m_period == FailurePeriod) 223 m_histograms.recordFallbackTime();
213 return nullptr;
214
215 m_histograms.recordFallbackTime(m_font.get());
216 224
217 return SimpleFontData::create( 225 return SimpleFontData::create(
218 m_font->platformDataFromCustomData(fontDescription.effectiveFontSize(), 226 m_customFontData->fontPlatformData(fontDescription.effectiveFontSize(),
219 fontDescription.isSyntheticBold(), 227 fontDescription.isSyntheticBold(),
220 fontDescription.isSyntheticItalic(), 228 fontDescription.isSyntheticItalic(),
221 fontDescription.orientation(), 229 fontDescription.orientation(),
222 fontDescription.variationSettings()), 230 fontDescription.variationSettings()),
223 CustomFontData::create()); 231 CustomFontData::create());
224 } 232 }
225 233
226 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createLoadingFallbackFontData( 234 PassRefPtr<SimpleFontData> RemoteFontFaceSource::createLoadingFallbackFontData(
227 const FontDescription& fontDescription) { 235 const FontDescription& fontDescription) {
228 // This temporary font is not retained and should not be returned. 236 // This temporary font is not retained and should not be returned.
229 FontCachePurgePreventer fontCachePurgePreventer; 237 FontCachePurgePreventer fontCachePurgePreventer;
230 SimpleFontData* temporaryFont = 238 SimpleFontData* temporaryFont =
231 FontCache::fontCache()->getNonRetainedLastResortFallbackFont( 239 FontCache::fontCache()->getNonRetainedLastResortFallbackFont(
232 fontDescription); 240 fontDescription);
233 if (!temporaryFont) { 241 if (!temporaryFont) {
234 ASSERT_NOT_REACHED(); 242 ASSERT_NOT_REACHED();
235 return nullptr; 243 return nullptr;
236 } 244 }
237 RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create( 245 RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create(
238 this, m_period == BlockPeriod ? CSSCustomFontData::InvisibleFallback 246 this, m_period == BlockPeriod ? CSSCustomFontData::InvisibleFallback
239 : CSSCustomFontData::VisibleFallback); 247 : CSSCustomFontData::VisibleFallback);
240 return SimpleFontData::create(temporaryFont->platformData(), cssFontData); 248 return SimpleFontData::create(temporaryFont->platformData(), cssFontData);
241 } 249 }
242 250
243 void RemoteFontFaceSource::beginLoadIfNeeded() { 251 void RemoteFontFaceSource::beginLoadIfNeeded() {
252 if (isLoaded())
Takashi Toyoshima 2017/02/27 12:56:02 Does this short-circuit affect our metrics?
Kunihiko Sakamoto 2017/02/28 04:04:01 You mean m_histograms.loadStarted() at line 268? T
Takashi Toyoshima 2017/03/01 06:44:07 I see. Thanks!
253 return;
254 DCHECK(m_font);
255
244 if (m_fontSelector->document() && m_font->stillNeedsLoad()) { 256 if (m_fontSelector->document() && m_font->stillNeedsLoad()) {
245 if (!m_font->url().protocolIsData() && !m_font->isLoaded() && 257 if (!m_font->url().protocolIsData() && !m_font->isLoaded() &&
246 m_display == FontDisplayAuto && 258 m_display == FontDisplayAuto &&
247 m_font->isLowPriorityLoadingAllowedForRemoteFont()) { 259 m_font->isLowPriorityLoadingAllowedForRemoteFont()) {
248 // Set the loading priority to VeryLow since this font is not required 260 // Set the loading priority to VeryLow since this font is not required
249 // for painting the text. 261 // for painting the text.
250 m_font->didChangePriority(ResourceLoadPriorityVeryLow, 0); 262 m_font->didChangePriority(ResourceLoadPriorityVeryLow, 0);
251 } 263 }
252 if (m_fontSelector->document()->fetcher()->startLoad(m_font)) { 264 if (m_fontSelector->document()->fetcher()->startLoad(m_font)) {
253 // Start timers only when load is actually started asynchronously. 265 // Start timers only when load is actually started asynchronously.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 } 302 }
291 303
292 void RemoteFontFaceSource::FontLoadHistograms::longLimitExceeded( 304 void RemoteFontFaceSource::FontLoadHistograms::longLimitExceeded(
293 bool isInterventionTriggered) { 305 bool isInterventionTriggered) {
294 m_isLongLimitExceeded = true; 306 m_isLongLimitExceeded = true;
295 maySetDataSource(FromNetwork); 307 maySetDataSource(FromNetwork);
296 if (m_fontDisplay == FontDisplayAuto) 308 if (m_fontDisplay == FontDisplayAuto)
297 recordInterventionResult(isInterventionTriggered); 309 recordInterventionResult(isInterventionTriggered);
298 } 310 }
299 311
300 void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime( 312 void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime() {
301 const FontResource* font) {
302 if (m_blankPaintTime <= 0) 313 if (m_blankPaintTime <= 0)
303 return; 314 return;
304 int duration = static_cast<int>(currentTimeMS() - m_blankPaintTime); 315 int duration = static_cast<int>(currentTimeMS() - m_blankPaintTime);
305 DEFINE_STATIC_LOCAL(CustomCountHistogram, blankTextShownTimeHistogram, 316 DEFINE_STATIC_LOCAL(CustomCountHistogram, blankTextShownTimeHistogram,
306 ("WebFont.BlankTextShownTime", 0, 10000, 50)); 317 ("WebFont.BlankTextShownTime", 0, 10000, 50));
307 blankTextShownTimeHistogram.count(duration); 318 blankTextShownTimeHistogram.count(duration);
308 m_blankPaintTime = -1; 319 m_blankPaintTime = -1;
309 } 320 }
310 321
311 void RemoteFontFaceSource::FontLoadHistograms::recordRemoteFont( 322 void RemoteFontFaceSource::FontLoadHistograms::recordRemoteFont(
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
466 return Miss; 477 return Miss;
467 case FromUnknown: 478 case FromUnknown:
468 // Fall through. 479 // Fall through.
469 default: 480 default:
470 NOTREACHED(); 481 NOTREACHED();
471 } 482 }
472 return Miss; 483 return Miss;
473 } 484 }
474 485
475 } // namespace blink 486 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698