Chromium Code Reviews| 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) |