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

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

Issue 2407573002: Wait to notify completion until after a Lo-Fi image is reloaded. (Closed)
Patch Set: Moved flag into ImageResource. Created 4 years, 2 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 64
65 return toImageResource( 65 return toImageResource(
66 fetcher->requestResource(request, ImageResourceFactory())); 66 fetcher->requestResource(request, ImageResourceFactory()));
67 } 67 }
68 68
69 ImageResource::ImageResource(const ResourceRequest& resourceRequest, 69 ImageResource::ImageResource(const ResourceRequest& resourceRequest,
70 const ResourceLoaderOptions& options) 70 const ResourceLoaderOptions& options)
71 : Resource(resourceRequest, Image, options), 71 : Resource(resourceRequest, Image, options),
72 m_devicePixelRatioHeaderValue(1.0), 72 m_devicePixelRatioHeaderValue(1.0),
73 m_image(nullptr), 73 m_image(nullptr),
74 m_hasDevicePixelRatioHeaderValue(false) { 74 m_hasDevicePixelRatioHeaderValue(false),
75 m_isSchedulingReload(false) {
75 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this; 76 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(ResourceRequest) " << this;
76 } 77 }
77 78
78 ImageResource::ImageResource(blink::Image* image, 79 ImageResource::ImageResource(blink::Image* image,
79 const ResourceLoaderOptions& options) 80 const ResourceLoaderOptions& options)
80 : Resource(ResourceRequest(""), Image, options), 81 : Resource(ResourceRequest(""), Image, options),
81 m_devicePixelRatioHeaderValue(1.0), 82 m_devicePixelRatioHeaderValue(1.0),
82 m_image(image), 83 m_image(image),
83 m_hasDevicePixelRatioHeaderValue(false) { 84 m_hasDevicePixelRatioHeaderValue(false),
85 m_isSchedulingReload(false) {
84 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(Image) " << this; 86 RESOURCE_LOADING_DVLOG(1) << "new ImageResource(Image) " << this;
85 setStatus(Cached); 87 setStatus(Cached);
86 } 88 }
87 89
88 ImageResource::~ImageResource() { 90 ImageResource::~ImageResource() {
89 RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this; 91 RESOURCE_LOADING_DVLOG(1) << "~ImageResource " << this;
90 clearImage(); 92 clearImage();
91 } 93 }
92 94
93 DEFINE_TRACE(ImageResource) { 95 DEFINE_TRACE(ImageResource) {
94 visitor->trace(m_multipartParser); 96 visitor->trace(m_multipartParser);
95 Resource::trace(visitor); 97 Resource::trace(visitor);
96 ImageObserver::trace(visitor); 98 ImageObserver::trace(visitor);
97 MultipartImageResourceParser::Client::trace(visitor); 99 MultipartImageResourceParser::Client::trace(visitor);
98 } 100 }
99 101
100 void ImageResource::checkNotify() { 102 void ImageResource::checkNotify() {
103 // Don't notify observers and clients of completion if this ImageResource is
104 // about to be reloaded.
105 if (m_isSchedulingReload)
106 return;
107
101 notifyObserversInternal(MarkFinishedOption::ShouldMarkFinished); 108 notifyObserversInternal(MarkFinishedOption::ShouldMarkFinished);
102 Resource::checkNotify(); 109 Resource::checkNotify();
103 } 110 }
104 111
105 void ImageResource::notifyObserversInternal( 112 void ImageResource::notifyObserversInternal(
106 MarkFinishedOption markFinishedOption) { 113 MarkFinishedOption markFinishedOption) {
107 if (isLoading()) 114 if (isLoading() || m_isSchedulingReload)
Nate Chapin 2016/10/12 23:45:23 This should be redundant. checkNotify() is already
sclittle 2016/10/12 23:49:05 Done.
108 return; 115 return;
109 116
110 for (auto* observer : m_observers.asVector()) { 117 for (auto* observer : m_observers.asVector()) {
111 if (m_observers.contains(observer)) { 118 if (m_observers.contains(observer)) {
112 if (markFinishedOption == MarkFinishedOption::ShouldMarkFinished) 119 if (markFinishedOption == MarkFinishedOption::ShouldMarkFinished)
113 markObserverFinished(observer); 120 markObserverFinished(observer);
114 observer->imageNotifyFinished(this); 121 observer->imageNotifyFinished(this);
115 } 122 }
116 } 123 }
117 } 124 }
118 125
119 void ImageResource::markObserverFinished(ImageResourceObserver* observer) { 126 void ImageResource::markObserverFinished(ImageResourceObserver* observer) {
120 if (m_observers.contains(observer)) { 127 if (m_observers.contains(observer)) {
121 m_finishedObservers.add(observer); 128 m_finishedObservers.add(observer);
122 m_observers.remove(observer); 129 m_observers.remove(observer);
123 } 130 }
124 } 131 }
125 132
126 void ImageResource::didAddClient(ResourceClient* client) { 133 void ImageResource::didAddClient(ResourceClient* client) {
127 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); 134 DCHECK((m_multipartParser && isLoading()) || !data() || m_image);
135
136 // Don't notify observers and clients of completion if this ImageResource is
137 // about to be reloaded.
138 if (m_isSchedulingReload)
139 return;
140
128 Resource::didAddClient(client); 141 Resource::didAddClient(client);
129 } 142 }
130 143
131 void ImageResource::addObserver(ImageResourceObserver* observer) { 144 void ImageResource::addObserver(ImageResourceObserver* observer) {
132 willAddClientOrObserver(MarkAsReferenced); 145 willAddClientOrObserver(MarkAsReferenced);
133 146
134 m_observers.add(observer); 147 m_observers.add(observer);
135 148
136 if (isCacheValidator()) 149 if (isCacheValidator())
137 return; 150 return;
138 151
139 // When the response is not multipart, if |data()| exists, |m_image| must be 152 // When the response is not multipart, if |data()| exists, |m_image| must be
140 // created. This is assured that |updateImage()| is called when |appendData()| 153 // created. This is assured that |updateImage()| is called when |appendData()|
141 // is called. 154 // is called.
142 // 155 //
143 // On the other hand, when the response is multipart, |updateImage()| is not 156 // On the other hand, when the response is multipart, |updateImage()| is not
144 // called in |appendData()|, which means |m_image| might not be created even 157 // called in |appendData()|, which means |m_image| might not be created even
145 // when |data()| exists. This is intentional since creating a |m_image| on 158 // when |data()| exists. This is intentional since creating a |m_image| on
146 // receiving data might destroy an existing image in a previous part. 159 // receiving data might destroy an existing image in a previous part.
147 DCHECK((m_multipartParser && isLoading()) || !data() || m_image); 160 DCHECK((m_multipartParser && isLoading()) || !data() || m_image);
148 161
149 if (m_image && !m_image->isNull()) { 162 if (m_image && !m_image->isNull()) {
150 observer->imageChanged(this); 163 observer->imageChanged(this);
151 } 164 }
152 165
153 if (isLoaded()) { 166 if (isLoaded() && !m_isSchedulingReload) {
154 markObserverFinished(observer); 167 markObserverFinished(observer);
155 observer->imageNotifyFinished(this); 168 observer->imageNotifyFinished(this);
156 } 169 }
157 } 170 }
158 171
159 void ImageResource::removeObserver(ImageResourceObserver* observer) { 172 void ImageResource::removeObserver(ImageResourceObserver* observer) {
160 DCHECK(observer); 173 DCHECK(observer);
161 174
162 if (m_observers.contains(observer)) 175 if (m_observers.contains(observer))
163 m_observers.remove(observer); 176 m_observers.remove(observer);
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 m_image->setAnimationPolicy(newPolicy); 538 m_image->setAnimationPolicy(newPolicy);
526 } 539 }
527 } 540 }
528 541
529 void ImageResource::reloadIfLoFi(ResourceFetcher* fetcher) { 542 void ImageResource::reloadIfLoFi(ResourceFetcher* fetcher) {
530 if (resourceRequest().loFiState() != WebURLRequest::LoFiOn) 543 if (resourceRequest().loFiState() != WebURLRequest::LoFiOn)
531 return; 544 return;
532 if (isLoaded() && 545 if (isLoaded() &&
533 !response().httpHeaderField("chrome-proxy").contains("q=low")) 546 !response().httpHeaderField("chrome-proxy").contains("q=low"))
534 return; 547 return;
548
549 // Prevent clients and observers from being notified of completion while the
550 // reload is being scheduled, so that e.g. canceling an existing load in
551 // progress doesn't cause clients and observers to be notified of completion
552 // prematurely.
553 DCHECK(!m_isSchedulingReload);
554 m_isSchedulingReload = true;
555
535 setCachePolicyBypassingCache(); 556 setCachePolicyBypassingCache();
536 setLoFiStateOff(); 557 setLoFiStateOff();
537 if (isLoading()) 558 if (isLoading()) {
538 loader()->cancel(); 559 loader()->cancel();
539 clear(); 560 // Canceling the loader causes error() to be called, which in turn calls
540 notifyObservers(); 561 // clear() and notifyObservers(), so there's no need to call these again
562 // here.
563 } else {
564 clear();
565 notifyObservers();
566 }
541 567
542 setStatus(NotStarted); 568 setStatus(NotStarted);
569
570 DCHECK(m_isSchedulingReload);
571 m_isSchedulingReload = false;
572
543 fetcher->startLoad(this); 573 fetcher->startLoad(this);
544 } 574 }
545 575
546 void ImageResource::changedInRect(const blink::Image* image, 576 void ImageResource::changedInRect(const blink::Image* image,
547 const IntRect& rect) { 577 const IntRect& rect) {
548 if (!image || image != m_image) 578 if (!image || image != m_image)
549 return; 579 return;
550 notifyObservers(&rect); 580 notifyObservers(&rect);
551 } 581 }
552 582
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
586 return response().serviceWorkerResponseType() != 616 return response().serviceWorkerResponseType() !=
587 WebServiceWorkerResponseTypeOpaque; 617 WebServiceWorkerResponseTypeOpaque;
588 if (!getImage()->currentFrameHasSingleSecurityOrigin()) 618 if (!getImage()->currentFrameHasSingleSecurityOrigin())
589 return false; 619 return false;
590 if (passesAccessControlCheck(securityOrigin)) 620 if (passesAccessControlCheck(securityOrigin))
591 return true; 621 return true;
592 return !securityOrigin->taintsCanvas(response().url()); 622 return !securityOrigin->taintsCanvas(response().url());
593 } 623 }
594 624
595 } // namespace blink 625 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/fetch/ImageResource.h ('k') | third_party/WebKit/Source/core/fetch/ImageResourceTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698