Index: third_party/WebKit/Source/core/fetch/ImageResource.cpp |
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.cpp b/third_party/WebKit/Source/core/fetch/ImageResource.cpp |
index 2ce3c513e34f1eac0ca5b4aed97f58a03c0df13e..5966da9ad7324ba674fe8a80fc4500b29178b5e7 100644 |
--- a/third_party/WebKit/Source/core/fetch/ImageResource.cpp |
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.cpp |
@@ -119,6 +119,15 @@ void ImageResource::load(ResourceFetcher* fetcher, const ResourceLoaderOptions& |
setLoading(false); |
} |
+void ImageResource::notifyObserver(ImageResourceObserver* observer, bool isNotifyingFinish, const IntRect* changeRect) |
+{ |
+ observer->imageChanged(isNotifyingFinish, this, changeRect); |
+ if (isNotifyingFinish && m_observers.contains(observer)) { |
+ m_finishedObservers.add(observer); |
+ m_observers.remove(observer); |
+ } |
+} |
+ |
void ImageResource::addObserver(ImageResourceObserver* observer) |
{ |
willAddClientOrObserver(); |
@@ -133,29 +142,49 @@ void ImageResource::addObserver(ImageResourceObserver* observer) |
m_image->setData(m_data, true); |
} |
- if (m_image && !m_image->isNull()) |
- observer->imageChanged(this); |
+ if (m_image && !m_image->isNull()) { |
+ bool isNotifyingFinish = !isLoading() && !stillNeedsLoad(); |
+ notifyObserver(observer, isNotifyingFinish); |
+ } |
} |
void ImageResource::removeObserver(ImageResourceObserver* observer) |
{ |
ASSERT(observer); |
- ASSERT(m_observers.contains(observer)); |
- m_observers.remove(observer); |
+ |
+ if (m_observers.contains(observer)) |
+ m_observers.remove(observer); |
+ else if (m_finishedObservers.contains(observer)) |
+ m_finishedObservers.remove(observer); |
+ else |
+ ASSERT_NOT_REACHED(); |
+ |
didRemoveClientOrObserver(); |
} |
+static void priorityFromObserver(const ImageResourceObserver* observer, ResourcePriority& priority) |
+{ |
+ ResourcePriority nextPriority = observer->computeResourcePriority(); |
+ if (nextPriority.visibility == ResourcePriority::NotVisible) |
+ return; |
+ priority.visibility = ResourcePriority::Visible; |
+ priority.intraPriorityValue += nextPriority.intraPriorityValue; |
+} |
+ |
ResourcePriority ImageResource::priorityFromObservers() |
{ |
ResourcePriority priority; |
- ImageResourceObserverWalker w(m_observers); |
+ |
+ ImageResourceObserverWalker w(m_finishedObservers); |
esprehn
2016/03/22 23:31:49
ick, single letter variables. :(
hiroshige
2016/03/24 17:26:44
Done.
|
while (const auto* observer = w.next()) { |
- ResourcePriority nextPriority = observer->computeResourcePriority(); |
- if (nextPriority.visibility == ResourcePriority::NotVisible) |
- continue; |
- priority.visibility = ResourcePriority::Visible; |
- priority.intraPriorityValue += nextPriority.intraPriorityValue; |
+ priorityFromObserver(observer, priority); |
+ } |
+ |
+ ImageResourceObserverWalker w2(m_observers); |
esprehn
2016/03/22 23:31:49
can we do finishedWalker and walker or something?
hiroshige
2016/03/24 17:26:44
Done.
|
+ while (const auto* observer = w2.next()) { |
+ priorityFromObserver(observer, priority); |
} |
+ |
return priority; |
} |
@@ -277,11 +306,16 @@ LayoutSize ImageResource::imageSize(RespectImageOrientationEnum shouldRespectIma |
return size; |
} |
-void ImageResource::notifyObservers(const IntRect* changeRect) |
+void ImageResource::notifyObservers(bool isNotifyingFinish, const IntRect* changeRect) |
{ |
- ImageResourceObserverWalker w(m_observers); |
+ ImageResourceObserverWalker w(m_finishedObservers); |
esprehn
2016/03/22 23:31:49
ditto
hiroshige
2016/03/24 17:26:44
Done.
|
while (auto* observer = w.next()) { |
- observer->imageChanged(this, changeRect); |
+ notifyObserver(observer, false, changeRect); |
+ } |
+ |
+ ImageResourceObserverWalker w2(m_observers); |
+ while (auto* observer = w2.next()) { |
+ notifyObserver(observer, isNotifyingFinish, changeRect); |
} |
} |
@@ -351,7 +385,7 @@ void ImageResource::updateImage(bool allDataReceived) |
// It would be nice to only redraw the decoded band of the image, but with the current design |
// (decoding delayed until painting) that seems hard. |
- notifyObservers(); |
+ notifyObservers(allDataReceived); |
} |
} |
@@ -376,7 +410,7 @@ void ImageResource::error(Resource::Status status) |
m_multipartParser->cancel(); |
clear(); |
Resource::error(status); |
- notifyObservers(); |
+ notifyObservers(true); |
} |
void ImageResource::responseReceived(const ResourceResponse& response, PassOwnPtr<WebDataConsumerHandle> handle) |
@@ -423,11 +457,18 @@ bool ImageResource::shouldPauseAnimation(const blink::Image* image) |
if (!image || image != m_image) |
return false; |
- ImageResourceObserverWalker w(m_observers); |
+ ImageResourceObserverWalker w(m_finishedObservers); |
while (auto* observer = w.next()) { |
if (observer->willRenderImage()) |
return false; |
} |
+ |
+ ImageResourceObserverWalker w2(m_observers); |
+ while (auto* observer = w2.next()) { |
+ if (observer->willRenderImage()) |
+ return false; |
+ } |
+ |
return true; |
} |
@@ -435,7 +476,7 @@ void ImageResource::animationAdvanced(const blink::Image* image) |
{ |
if (!image || image != m_image) |
return; |
- notifyObservers(); |
+ notifyObservers(false); |
} |
void ImageResource::updateImageAnimationPolicy() |
@@ -444,12 +485,19 @@ void ImageResource::updateImageAnimationPolicy() |
return; |
ImageAnimationPolicy newPolicy = ImageAnimationPolicyAllowed; |
- ImageResourceObserverWalker w(m_observers); |
+ |
+ ImageResourceObserverWalker w(m_finishedObservers); |
while (auto* observer = w.next()) { |
if (observer->getImageAnimationPolicy(newPolicy)) |
break; |
} |
+ ImageResourceObserverWalker w2(m_observers); |
+ while (auto* observer = w2.next()) { |
+ if (observer->getImageAnimationPolicy(newPolicy)) |
+ break; |
+ } |
+ |
if (m_image->animationPolicy() != newPolicy) { |
m_image->resetAnimation(); |
m_image->setAnimationPolicy(newPolicy); |
@@ -470,7 +518,7 @@ void ImageResource::changedInRect(const blink::Image* image, const IntRect& rect |
{ |
if (!image || image != m_image) |
return; |
- notifyObservers(&rect); |
+ notifyObservers(false, &rect); |
} |
void ImageResource::onePartInMultipartReceived(const ResourceResponse& response, bool isFirstPart) |