Reviewers: oilpan-reviews, fs, David Vest
CL:
https://codereview.chromium.org/2004263003/Message:
please take a look.
See
https://codereview.chromium.org/2005693002/ for an alternate approach
considered.
Description:
Delay resetting image animation, if possible.
When the last client of an ImageResource removes itself, the animations
of the image is explicitly reset. That resetting can happen either while
finalizing objects after a GC or as part of other explicit removals of
ImageObserver clients. Having that reset happen as part of a garbage
collection is interacting badly with code in the middle of updating
animations (which happen to trigger a GC), so to avoid introducing such
abrupt resets, delay the operation until back at the event loop (and
the animations update step having completed.)
R=
BUG=613709, 581546
Base URL:
https://chromium.googlesource.com/chromium/src.git@masterAffected files (+15, -2 lines):
M third_party/WebKit/Source/core/fetch/ImageResource.h
M third_party/WebKit/Source/core/fetch/ImageResource.cpp
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 81db13640f8150ed4554bcf6542607cb4925b564..c9b6c20697473fa684d89804ff32a475ee39fcb4 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.cpp
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.cpp
@@ -206,10 +206,21 @@ void ImageResource::destroyDecodedDataIfPossible()
}
}
-void ImageResource::allClientsAndObserversRemoved()
+void ImageResource::doResetAnimation()
{
- if (m_image && !errorOccurred())
+ if (m_image)
m_image->resetAnimation();
+}
+
+void ImageResource::allClientsAndObserversRemoved()
+{
+ if (m_image && !errorOccurred()) {
+ // If possible, delay the resetting until back at the event loop.
+ if (!ThreadHeap::willObjectBeLazilySwept(this))
+ Platform::current()->currentThread()->getWebTaskRunner()->postTask(BLINK_FROM_HERE, bind(&ImageResource::doResetAnimation, CrossThreadWeakPersistentThisPointer<ImageResource>(this)));
+ else
+ m_image->resetAnimation();
+ }
if (m_multipartParser)
m_multipartParser->cancel();
Resource::allClientsAndObserversRemoved();
Index: third_party/WebKit/Source/core/fetch/ImageResource.h
diff --git a/third_party/WebKit/Source/core/fetch/ImageResource.h b/third_party/WebKit/Source/core/fetch/ImageResource.h
index 8ab5b6d18f1cb194d287bbde3fd7ef8540201f5c..0d0910f8c0e0e28b3e7bb8114c983dfe67954af3 100644
--- a/third_party/WebKit/Source/core/fetch/ImageResource.h
+++ b/third_party/WebKit/Source/core/fetch/ImageResource.h
@@ -160,6 +160,8 @@ private:
void checkNotify() override;
void markClientsAndObserversFinished() override;
+ void doResetAnimation();
+
float m_devicePixelRatioHeaderValue;
Member<MultipartImageResourceParser> m_multipartParser;