| 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 9fac1def674bfd7a0e64237e30793cd04b3d3a2c..cbef55f92c4db7066a839b2dc657731392961c43 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);
|
| 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);
|
| + while (const auto* observer = w2.next()) {
|
| + priorityFromObserver(observer, priority);
|
| }
|
| +
|
| return priority;
|
| }
|
|
|
| @@ -283,11 +312,16 @@ void ImageResource::computeIntrinsicDimensions(FloatSize& intrinsicSize, FloatSi
|
| m_image->computeIntrinsicDimensions(intrinsicSize, intrinsicRatio);
|
| }
|
|
|
| -void ImageResource::notifyObservers(const IntRect* changeRect)
|
| +void ImageResource::notifyObservers(bool isNotifyingFinish, const IntRect* changeRect)
|
| {
|
| - ImageResourceObserverWalker w(m_observers);
|
| + ImageResourceObserverWalker w(m_finishedObservers);
|
| 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);
|
| }
|
| }
|
|
|
| @@ -357,7 +391,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);
|
| }
|
| }
|
|
|
| @@ -382,7 +416,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)
|
| @@ -429,11 +463,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;
|
| }
|
|
|
| @@ -441,7 +482,7 @@ void ImageResource::animationAdvanced(const blink::Image* image)
|
| {
|
| if (!image || image != m_image)
|
| return;
|
| - notifyObservers();
|
| + notifyObservers(false);
|
| }
|
|
|
| void ImageResource::updateImageAnimationPolicy()
|
| @@ -450,12 +491,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);
|
| @@ -476,7 +524,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)
|
|
|