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

Side by Side Diff: third_party/WebKit/Source/core/loader/resource/ImageResource.cpp

Issue 2527353002: Phase II Step 3: Reload LoFi/placeholder images via new ImageResource
Patch Set: Reflect comments and rebase 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 /* 1 /*
2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de) 2 Copyright (C) 1998 Lars Knoll (knoll@mpi-hd.mpg.de)
3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org) 3 Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org) 4 Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com) 5 Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. 6 Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
7 7
8 This library is free software; you can redistribute it and/or 8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public 9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either 10 License as published by the Free Software Foundation; either
(...skipping 23 matching lines...) Expand all
34 #include "platform/SharedBuffer.h" 34 #include "platform/SharedBuffer.h"
35 #include "platform/instrumentation/tracing/TraceEvent.h" 35 #include "platform/instrumentation/tracing/TraceEvent.h"
36 #include "platform/loader/fetch/MemoryCache.h" 36 #include "platform/loader/fetch/MemoryCache.h"
37 #include "platform/loader/fetch/ResourceClient.h" 37 #include "platform/loader/fetch/ResourceClient.h"
38 #include "platform/loader/fetch/ResourceFetcher.h" 38 #include "platform/loader/fetch/ResourceFetcher.h"
39 #include "platform/loader/fetch/ResourceLoader.h" 39 #include "platform/loader/fetch/ResourceLoader.h"
40 #include "platform/loader/fetch/ResourceLoadingLog.h" 40 #include "platform/loader/fetch/ResourceLoadingLog.h"
41 #include "platform/network/HTTPParsers.h" 41 #include "platform/network/HTTPParsers.h"
42 #include "platform/weborigin/SecurityViolationReportingPolicy.h" 42 #include "platform/weborigin/SecurityViolationReportingPolicy.h"
43 #include "public/platform/Platform.h" 43 #include "public/platform/Platform.h"
44 #include "public/platform/WebCachePolicy.h"
44 #include "v8/include/v8.h" 45 #include "v8/include/v8.h"
45 #include "wtf/CurrentTime.h" 46 #include "wtf/CurrentTime.h"
46 #include "wtf/StdLibExtras.h" 47 #include "wtf/StdLibExtras.h"
47 48
48 namespace blink { 49 namespace blink {
49 namespace { 50 namespace {
50 // The amount of time to wait before informing the clients that the image has 51 // The amount of time to wait before informing the clients that the image has
51 // been updated (in seconds). This effectively throttles invalidations that 52 // been updated (in seconds). This effectively throttles invalidations that
52 // result from new data arriving for this image. 53 // result from new data arriving for this image.
53 constexpr double kFlushDelaySeconds = 1.; 54 constexpr double kFlushDelaySeconds = 1.;
54 } // namespace 55 } // namespace
55 56
56 class ImageResource::ImageResourceInfoImpl final 57 class ImageResource::ImageResourceInfoImpl final
57 : public GarbageCollectedFinalized<ImageResourceInfoImpl>, 58 : public GarbageCollectedFinalized<ImageResourceInfoImpl>,
58 public ImageResourceInfo { 59 public ImageResourceInfo {
59 USING_GARBAGE_COLLECTED_MIXIN(ImageResourceInfoImpl); 60 USING_GARBAGE_COLLECTED_MIXIN(ImageResourceInfoImpl);
60 61
61 public: 62 public:
62 ImageResourceInfoImpl(ImageResource* resource) : m_resource(resource) { 63 ImageResourceInfoImpl(ImageResource* resource) : m_resource(resource) {
63 DCHECK(m_resource); 64 DCHECK(m_resource);
64 } 65 }
65 DEFINE_INLINE_VIRTUAL_TRACE() { 66 DEFINE_INLINE_VIRTUAL_TRACE() {
66 visitor->trace(m_resource); 67 visitor->trace(m_resource);
67 ImageResourceInfo::trace(visitor); 68 ImageResourceInfo::trace(visitor);
68 } 69 }
69 70
70 private: 71 private:
71 const KURL& url() const override { return m_resource->url(); } 72 const KURL& url() const override { return m_resource->url(); }
72 bool isSchedulingReload() const override {
73 return m_resource->m_isSchedulingReload;
74 }
75 bool hasDevicePixelRatioHeaderValue() const override { 73 bool hasDevicePixelRatioHeaderValue() const override {
76 return m_resource->m_hasDevicePixelRatioHeaderValue; 74 return m_resource->m_hasDevicePixelRatioHeaderValue;
77 } 75 }
78 float devicePixelRatioHeaderValue() const override { 76 float devicePixelRatioHeaderValue() const override {
79 return m_resource->m_devicePixelRatioHeaderValue; 77 return m_resource->m_devicePixelRatioHeaderValue;
80 } 78 }
81 const ResourceResponse& response() const override { 79 const ResourceResponse& response() const override {
82 return m_resource->response(); 80 return m_resource->response();
83 } 81 }
84 ResourceStatus getStatus() const override { return m_resource->getStatus(); } 82 ResourceStatus getStatus() const override { return m_resource->getStatus(); }
85 bool shouldShowPlaceholder() const override { 83 bool shouldShowPlaceholder() const override {
86 return m_resource->shouldShowPlaceholder(); 84 return m_resource->shouldShowPlaceholder();
87 } 85 }
88 bool isCacheValidator() const override { 86 bool isCacheValidator() const override {
89 return m_resource->isCacheValidator(); 87 return m_resource->isCacheValidator();
90 } 88 }
91 bool schedulingReloadOrShouldReloadBrokenPlaceholder() const override {
92 return m_resource->m_isSchedulingReload ||
93 m_resource->shouldReloadBrokenPlaceholder();
94 }
95 bool isAccessAllowed( 89 bool isAccessAllowed(
96 SecurityOrigin* securityOrigin, 90 SecurityOrigin* securityOrigin,
97 DoesCurrentFrameHaveSingleSecurityOrigin 91 DoesCurrentFrameHaveSingleSecurityOrigin
98 doesCurrentFrameHasSingleSecurityOrigin) const override { 92 doesCurrentFrameHasSingleSecurityOrigin) const override {
99 return m_resource->isAccessAllowed(securityOrigin, 93 return m_resource->isAccessAllowed(securityOrigin,
100 doesCurrentFrameHasSingleSecurityOrigin); 94 doesCurrentFrameHasSingleSecurityOrigin);
101 } 95 }
102 bool hasCacheControlNoStoreHeader() const override { 96 bool hasCacheControlNoStoreHeader() const override {
103 return m_resource->hasCacheControlNoStoreHeader(); 97 return m_resource->hasCacheControlNoStoreHeader();
104 } 98 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
168 fetcher->context().sendImagePing(requestURL); 162 fetcher->context().sendImagePing(requestURL);
169 } 163 }
170 return nullptr; 164 return nullptr;
171 } 165 }
172 166
173 return toImageResource( 167 return toImageResource(
174 fetcher->requestResource(request, ImageResourceFactory(request))); 168 fetcher->requestResource(request, ImageResourceFactory(request)));
175 } 169 }
176 170
177 bool ImageResource::canReuse(const FetchRequest& request) const { 171 bool ImageResource::canReuse(const FetchRequest& request) const {
172 if (!getContent())
173 return false;
174
178 // If the image is a placeholder, but this fetch doesn't allow a 175 // If the image is a placeholder, but this fetch doesn't allow a
179 // placeholder, then do not reuse this resource. 176 // placeholder, then do not reuse this resource.
180 if (request.placeholderImageRequestType() != FetchRequest::AllowPlaceholder && 177 if (request.placeholderImageRequestType() != FetchRequest::AllowPlaceholder &&
181 m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder) 178 m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder)
182 return false; 179 return false;
180
183 return true; 181 return true;
184 } 182 }
185 183
186 ImageResource* ImageResource::create(const ResourceRequest& request) { 184 ImageResource* ImageResource::create(const ResourceRequest& request) {
187 return new ImageResource(request, ResourceLoaderOptions(), 185 return new ImageResource(request, ResourceLoaderOptions(),
188 ImageResourceContent::create(), false); 186 ImageResourceContent::create(), false);
189 } 187 }
190 188
191 ImageResource::ImageResource(const ResourceRequest& resourceRequest, 189 ImageResource::ImageResource(const ResourceRequest& resourceRequest,
192 const ResourceLoaderOptions& options, 190 const ResourceLoaderOptions& options,
193 ImageResourceContent* content, 191 ImageResourceContent* content,
194 bool isPlaceholder) 192 bool isPlaceholder)
195 : Resource(resourceRequest, Image, options), 193 : Resource(resourceRequest, Image, options),
196 m_content(content), 194 m_content(content),
197 m_devicePixelRatioHeaderValue(1.0), 195 m_devicePixelRatioHeaderValue(1.0),
198 m_hasDevicePixelRatioHeaderValue(false), 196 m_hasDevicePixelRatioHeaderValue(false),
199 m_isSchedulingReload(false),
200 m_placeholderOption( 197 m_placeholderOption(
201 isPlaceholder ? PlaceholderOption::ShowAndReloadPlaceholderAlways 198 isPlaceholder ? PlaceholderOption::ShowAndReloadPlaceholderAlways
202 : PlaceholderOption::DoNotReloadPlaceholder), 199 : PlaceholderOption::DoNotReloadPlaceholder),
203 m_flushTimer(this, &ImageResource::flushImageIfNeeded) { 200 m_flushTimer(this, &ImageResource::flushImageIfNeeded) {
204 DCHECK(getContent()); 201 DCHECK(getContent());
205 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this; 202 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this;
206 getContent()->setImageResourceInfo(new ImageResourceInfoImpl(this)); 203 getContent()->setImageResourceInfo(new ImageResourceInfoImpl(this));
207 } 204 }
208 205
209 ImageResource::~ImageResource() { 206 ImageResource::~ImageResource() {
210 RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this; 207 RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this;
211 } 208 }
212 209
213 DEFINE_TRACE(ImageResource) { 210 DEFINE_TRACE(ImageResource) {
214 visitor->trace(m_multipartParser); 211 visitor->trace(m_multipartParser);
215 visitor->trace(m_content); 212 visitor->trace(m_content);
216 Resource::trace(visitor); 213 Resource::trace(visitor);
217 MultipartImageResourceParser::Client::trace(visitor); 214 MultipartImageResourceParser::Client::trace(visitor);
218 } 215 }
219 216
220 void ImageResource::checkNotify() {
221 // Don't notify clients of completion if this ImageResource is
222 // about to be reloaded.
223 if (m_isSchedulingReload || shouldReloadBrokenPlaceholder())
224 return;
225
226 Resource::checkNotify();
227 }
228
229 bool ImageResource::hasClientsOrObservers() const { 217 bool ImageResource::hasClientsOrObservers() const {
230 return Resource::hasClientsOrObservers() || getContent()->hasObservers(); 218 return Resource::hasClientsOrObservers() ||
219 (getContent() && getContent()->hasObservers());
231 } 220 }
232 221
233 void ImageResource::didAddClient(ResourceClient* client) { 222 void ImageResource::didAddClient(ResourceClient* client) {
234 DCHECK((m_multipartParser && isLoading()) || !data() || 223 DCHECK((m_multipartParser && isLoading()) || !data() ||
235 getContent()->hasImage()); 224 (getContent() && getContent()->hasImage()));
236
237 // Don't notify observers and clients of completion if this ImageResource is
238 // about to be reloaded.
239 if (m_isSchedulingReload || shouldReloadBrokenPlaceholder())
240 return;
241
242 Resource::didAddClient(client); 225 Resource::didAddClient(client);
243 } 226 }
244 227
245 void ImageResource::destroyDecodedDataForFailedRevalidation() { 228 void ImageResource::destroyDecodedDataForFailedRevalidation() {
246 // Clears the image, as we must create a new image for the failed 229 // Clears the image, as we must create a new image for the failed
247 // revalidation response. 230 // revalidation response.
248 updateImage(nullptr, ImageResourceContent::ClearAndUpdateImage, false); 231 updateImage(nullptr, ImageResourceContent::ClearAndUpdateImage, false);
249 setDecodedSize(0); 232 setDecodedSize(0);
250 } 233 }
251 234
252 void ImageResource::destroyDecodedDataIfPossible() { 235 void ImageResource::destroyDecodedDataIfPossible() {
236 if (!getContent())
237 return;
253 getContent()->destroyDecodedData(); 238 getContent()->destroyDecodedData();
254 if (getContent()->hasImage() && !isPreloaded() && 239 if (getContent()->hasImage() && !isPreloaded() &&
255 getContent()->isRefetchableDataFromDiskCache()) { 240 getContent()->isRefetchableDataFromDiskCache()) {
256 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize", 241 UMA_HISTOGRAM_MEMORY_KB("Memory.Renderer.EstimatedDroppableEncodedSize",
257 encodedSize() / 1024); 242 encodedSize() / 1024);
258 } 243 }
259 } 244 }
260 245
261 void ImageResource::allClientsAndObserversRemoved() { 246 void ImageResource::allClientsAndObserversRemoved() {
262 CHECK(!getContent()->hasImage() || !errorOccurred()); 247 CHECK(!getContent() || !getContent()->hasImage() || !errorOccurred());
263 // If possible, delay the resetting until back at the event loop. Doing so 248 if (getContent()) {
264 // after a conservative GC prevents resetAnimation() from upsetting ongoing 249 // If possible, delay the resetting until back at the event loop. Doing so
265 // animation updates (crbug.com/613709) 250 // after a conservative GC prevents resetAnimation() from upsetting ongoing
266 if (!ThreadHeap::willObjectBeLazilySwept(this)) { 251 // animation updates (crbug.com/613709)
267 Platform::current()->currentThread()->getWebTaskRunner()->postTask( 252 if (!ThreadHeap::willObjectBeLazilySwept(this)) {
268 BLINK_FROM_HERE, WTF::bind(&ImageResourceContent::doResetAnimation, 253 Platform::current()->currentThread()->getWebTaskRunner()->postTask(
269 wrapWeakPersistent(getContent()))); 254 BLINK_FROM_HERE, WTF::bind(&ImageResourceContent::doResetAnimation,
270 } else { 255 wrapWeakPersistent(getContent())));
271 getContent()->doResetAnimation(); 256 } else {
257 getContent()->doResetAnimation();
258 }
272 } 259 }
273 if (m_multipartParser) 260 if (m_multipartParser)
274 m_multipartParser->cancel(); 261 m_multipartParser->cancel();
275 Resource::allClientsAndObserversRemoved(); 262 Resource::allClientsAndObserversRemoved();
276 } 263 }
277 264
278 PassRefPtr<const SharedBuffer> ImageResource::resourceBuffer() const { 265 PassRefPtr<const SharedBuffer> ImageResource::resourceBuffer() const {
266 if (!getContent()) {
267 DCHECK(!data());
268 return nullptr;
269 }
270
279 if (data()) 271 if (data())
280 return data(); 272 return data();
281 return getContent()->resourceBuffer(); 273 return getContent()->resourceBuffer();
282 } 274 }
283 275
284 void ImageResource::appendData(const char* data, size_t length) { 276 void ImageResource::appendData(const char* data, size_t length) {
285 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length); 277 v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(length);
286 if (m_multipartParser) { 278 if (m_multipartParser) {
287 m_multipartParser->appendData(data, length); 279 m_multipartParser->appendData(data, length);
288 } else { 280 } else {
289 Resource::appendData(data, length); 281 Resource::appendData(data, length);
290 282
283 if (!getContent())
284 return;
285
291 // Update the image immediately if needed. 286 // Update the image immediately if needed.
292 if (getContent()->shouldUpdateImageImmediately()) { 287 if (getContent()->shouldUpdateImageImmediately()) {
293 updateImage(this->data(), ImageResourceContent::UpdateImage, false); 288 updateImage(this->data(), ImageResourceContent::UpdateImage, false);
294 return; 289 return;
295 } 290 }
296 291
297 // For other cases, only update at |kFlushDelaySeconds| intervals. This 292 // For other cases, only update at |kFlushDelaySeconds| intervals. This
298 // throttles how frequently we update |m_image| and how frequently we 293 // throttles how frequently we update |m_image| and how frequently we
299 // inform the clients which causes an invalidation of this image. In other 294 // inform the clients which causes an invalidation of this image. In other
300 // words, we only invalidate this image every |kFlushDelaySeconds| seconds 295 // words, we only invalidate this image every |kFlushDelaySeconds| seconds
(...skipping 22 matching lines...) Expand all
323 } 318 }
324 319
325 void ImageResource::decodeError(bool allDataReceived) { 320 void ImageResource::decodeError(bool allDataReceived) {
326 size_t size = encodedSize(); 321 size_t size = encodedSize();
327 322
328 clearData(); 323 clearData();
329 setEncodedSize(0); 324 setEncodedSize(0);
330 if (!errorOccurred()) 325 if (!errorOccurred())
331 setStatus(ResourceStatus::DecodeError); 326 setStatus(ResourceStatus::DecodeError);
332 327
328 // Tries to reload here to avoid imageNotifyFinished()
329 // notification in the case of decode error.
330 if (loader())
331 loader()->reloadIfLoFiOrPlaceholderImage(this);
332
333 // Finishes loading if needed, and notifies observers. 333 // Finishes loading if needed, and notifies observers.
334 if (!allDataReceived && loader()) { 334 if (!allDataReceived && loader()) {
335 // Observers are notified via ImageResource::finish(). 335 // Observers are notified via ImageResource::finish().
336 // TODO(hiroshige): Do not call didFinishLoading() directly. 336 // TODO(hiroshige): Do not call didFinishLoading() directly.
337 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size); 337 loader()->didFinishLoading(monotonicallyIncreasingTime(), size, size);
338 } else { 338 } else if (getContent()) {
339 auto result = getContent()->updateImage( 339 auto result = getContent()->updateImage(
340 nullptr, ImageResourceContent::ClearImageAndNotifyObservers, 340 nullptr, ImageResourceContent::ClearImageAndNotifyObservers,
341 allDataReceived); 341 allDataReceived);
342 DCHECK_EQ(result, ImageResourceContent::UpdateImageResult::NoDecodeError); 342 DCHECK_EQ(result, ImageResourceContent::UpdateImageResult::NoDecodeError);
343 } 343 }
344 344
345 memoryCache()->remove(this); 345 memoryCache()->remove(this);
346 } 346 }
347 347
348 void ImageResource::updateImageAndClearBuffer() { 348 void ImageResource::updateImageAndClearBuffer() {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 return errorOccurred(); 451 return errorOccurred();
452 case PlaceholderOption::ReloadPlaceholderOnDecodeError: 452 case PlaceholderOption::ReloadPlaceholderOnDecodeError:
453 return getStatus() == ResourceStatus::DecodeError; 453 return getStatus() == ResourceStatus::DecodeError;
454 case PlaceholderOption::DoNotReloadPlaceholder: 454 case PlaceholderOption::DoNotReloadPlaceholder:
455 return false; 455 return false;
456 } 456 }
457 NOTREACHED(); 457 NOTREACHED();
458 return false; 458 return false;
459 } 459 }
460 460
461 void ImageResource::detachContent() {
462 bool contentHadObservers = getContent() && getContent()->hasObservers();
463
464 m_content = nullptr;
465 clearData();
466 memoryCache()->remove(this);
467
468 if (contentHadObservers)
469 didRemoveClientOrObserver();
470 }
471
461 static bool isLoFiImage(const ImageResource& resource) { 472 static bool isLoFiImage(const ImageResource& resource) {
462 if (!(resource.resourceRequest().previewsState() & 473 if (!(resource.resourceRequest().previewsState() &
463 WebURLRequest::ServerLoFiOn)) { 474 WebURLRequest::ServerLoFiOn)) {
464 return false; 475 return false;
465 } 476 }
466 return !resource.isLoaded() || 477 return !resource.isLoaded() ||
467 resource.response() 478 resource.response()
468 .httpHeaderField("chrome-proxy-content-transform") 479 .httpHeaderField("chrome-proxy-content-transform")
469 .contains("empty-image"); 480 .contains("empty-image");
470 } 481 }
471 482
472 void ImageResource::reloadIfLoFiOrPlaceholderImage( 483 ImageResource* ImageResource::reloadIfLoFiOrPlaceholderImage(
473 ResourceFetcher* fetcher, 484 ResourceFetcher* fetcher,
474 ReloadLoFiOrPlaceholderPolicy policy) { 485 ReloadLoFiOrPlaceholderPolicy policy) {
486 DCHECK(fetcher);
487
475 if (policy == kReloadIfNeeded && !shouldReloadBrokenPlaceholder()) 488 if (policy == kReloadIfNeeded && !shouldReloadBrokenPlaceholder())
476 return; 489 return nullptr;
477 490
478 if (m_placeholderOption == PlaceholderOption::DoNotReloadPlaceholder && 491 if (m_placeholderOption == PlaceholderOption::DoNotReloadPlaceholder &&
479 !isLoFiImage(*this)) 492 !isLoFiImage(*this))
480 return; 493 return nullptr;
481 494
482 // Prevent clients and observers from being notified of completion while the 495 ImageResourceContent* content = getContent();
483 // reload is being scheduled, so that e.g. canceling an existing load in 496 if (!content)
484 // progress doesn't cause clients and observers to be notified of completion 497 return nullptr;
485 // prematurely.
486 DCHECK(!m_isSchedulingReload);
487 m_isSchedulingReload = true;
488 498
489 setCachePolicyBypassingCache(); 499 // Creates request/options for new ImageResource for reloading.
500 ResourceLoaderOptions reloadingOptions = options();
501 ResourceRequest reloadingRequest = resourceRequest();
502 reloadingRequest.setCachePolicy(WebCachePolicy::BypassingCache);
503 reloadingRequest.setPreviewsState(WebURLRequest::PreviewsNoTransform);
504 if (m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder)
505 reloadingRequest.clearHTTPHeaderField("range");
490 506
491 setPreviewsStateNoTransform(); 507 // Clear the image before reloading starts to avoid mixing the image from
508 // previous response with the response from the new reloading response.
509 updateImage(nullptr, ImageResourceContent::ClearImageAndNotifyObservers,
510 false);
492 511
493 if (m_placeholderOption != PlaceholderOption::DoNotReloadPlaceholder) 512 detachContent();
494 clearRangeRequestHeader(); 513 // |this->getContent()| is nullptr after this point.
495 m_placeholderOption = PlaceholderOption::DoNotReloadPlaceholder;
496 514
497 if (isLoading()) { 515 // TODO(hiroshige): Use ResourceFetcher::requestResource() to unify the
498 loader()->cancel(); 516 // starting points of resource loading into requestResource().
499 // Canceling the loader causes error() to be called, which in turn calls 517 // Currently we call ResourceFetcher::startLoad() instead, in order to avoid
500 // clear() and notifyObservers(), so there's no need to call these again 518 // re-applying modifications to ResourceRequest in requestResource().
501 // here. 519 ImageResource* reloadingResource =
502 } else { 520 new ImageResource(reloadingRequest, reloadingOptions, content, false);
503 clearData(); 521 DCHECK(!reloadingResource || content == reloadingResource->getContent());
504 setEncodedSize(0); 522 memoryCache()->add(reloadingResource);
505 updateImage(nullptr, ImageResourceContent::ClearImageAndNotifyObservers, 523 fetcher->addToDocumentResources(reloadingResource);
506 false); 524 fetcher->startLoad(reloadingResource);
507 }
508 525
509 setStatus(ResourceStatus::NotStarted); 526 return reloadingResource;
510
511 DCHECK(m_isSchedulingReload);
512 m_isSchedulingReload = false;
513
514 fetcher->startLoad(this);
515 } 527 }
516 528
517 void ImageResource::onePartInMultipartReceived( 529 void ImageResource::onePartInMultipartReceived(
518 const ResourceResponse& response) { 530 const ResourceResponse& response) {
519 DCHECK(m_multipartParser); 531 DCHECK(m_multipartParser);
520 532
521 setResponse(response); 533 setResponse(response);
522 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) { 534 if (m_multipartParsingState == MultipartParsingState::WaitingForFirstPart) {
523 // We have nothing to do because we don't have any data. 535 // We have nothing to do because we don't have any data.
524 m_multipartParsingState = MultipartParsingState::ParsingFirstPart; 536 m_multipartParsingState = MultipartParsingState::ParsingFirstPart;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 575
564 ImageResourceContent* ImageResource::getContent() { 576 ImageResourceContent* ImageResource::getContent() {
565 return m_content; 577 return m_content;
566 } 578 }
567 579
568 const ImageResourceContent* ImageResource::getContent() const { 580 const ImageResourceContent* ImageResource::getContent() const {
569 return m_content; 581 return m_content;
570 } 582 }
571 583
572 ResourcePriority ImageResource::priorityFromObservers() { 584 ResourcePriority ImageResource::priorityFromObservers() {
585 if (!getContent())
586 return ResourcePriority();
573 return getContent()->priorityFromObservers(); 587 return getContent()->priorityFromObservers();
574 } 588 }
575 589
576 void ImageResource::updateImage( 590 void ImageResource::updateImage(
577 PassRefPtr<SharedBuffer> sharedBuffer, 591 PassRefPtr<SharedBuffer> sharedBuffer,
578 ImageResourceContent::UpdateImageOption updateImageOption, 592 ImageResourceContent::UpdateImageOption updateImageOption,
579 bool allDataReceived) { 593 bool allDataReceived) {
594 if (!getContent())
595 return;
580 auto result = getContent()->updateImage(std::move(sharedBuffer), 596 auto result = getContent()->updateImage(std::move(sharedBuffer),
581 updateImageOption, allDataReceived); 597 updateImageOption, allDataReceived);
582 if (result == ImageResourceContent::UpdateImageResult::ShouldDecodeError) { 598 if (result == ImageResourceContent::UpdateImageResult::ShouldDecodeError) {
599 // TODO before commit (hiroshige): Update the comment.
583 // In case of decode error, we call imageNotifyFinished() iff we don't 600 // In case of decode error, we call imageNotifyFinished() iff we don't
584 // initiate reloading: 601 // initiate reloading:
585 // [(a): when this is in the middle of loading, or (b): otherwise] 602 // [(a): when this is in the middle of loading, or (b): otherwise]
586 // 1. The updateImage() call above doesn't call notifyObservers(). 603 // 1. The updateImage() call above doesn't call notifyObservers().
587 // 2. notifyObservers(ShouldNotifyFinish) is called 604 // 2. notifyObservers(ShouldNotifyFinish) is called
588 // (a) via updateImage() called in ImageResource::finish() 605 // (a) via updateImage() called in ImageResource::finish()
589 // called via didFinishLoading() called in decodeError(), or 606 // called via didFinishLoading() called in decodeError(), or
590 // (b) via updateImage() called in decodeError(). 607 // (b) via updateImage() called in decodeError().
591 // imageNotifyFinished() is called here iff we will not initiate 608 // imageNotifyFinished() is called here iff we will not initiate
592 // reloading in Step 3 due to notifyObservers()'s 609 // reloading in Step 3 due to notifyObservers()'s
593 // schedulingReloadOrShouldReloadBrokenPlaceholder() check. 610 // schedulingReloadOrShouldReloadBrokenPlaceholder() check.
594 // 3. reloadIfLoFiOrPlaceholderImage() is called via ResourceFetcher 611 // 3. reloadIfLoFiOrPlaceholderImage() is called via ResourceFetcher
595 // (a) via didFinishLoading() called in decodeError(), or 612 // (a) via didFinishLoading() called in decodeError(), or
596 // (b) after returning ImageResource::updateImage(). 613 // (b) after returning ImageResource::updateImage().
597 decodeError(allDataReceived); 614 decodeError(allDataReceived);
598 } 615 }
599 } 616 }
600 617
601 } // namespace blink 618 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698