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

Unified Diff: third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp

Issue 2516593003: Pull up clearCacheExceptFrame to ImageDecoder. (Closed)
Patch Set: Make clearCacheExceptFrame non-virtual Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
diff --git a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
index 56cd271008cf8efd64ecb104b292c4ffdf65c44e..bfaa3d5ce8c0fa799a3667088a8a28d05ba79c92 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
@@ -214,7 +214,40 @@ size_t ImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) {
if (m_frameBufferCache.size() <= 1)
return 0;
- return clearCacheExceptTwoFrames(clearExceptFrame, kNotFound);
+ // We expect that after this call, we'll be asked to decode frames after this
+ // one. So we want to avoid clearing frames such that those requests would
+ // force re-decoding from the beginning of the image. There are two cases in
+ // which preserving |clearCacheExcept| frame is not enough to avoid that:
+ //
+ // 1. |clearExceptFrame| is not yet sufficiently decoded to decode subsequent
+ // frames. We need the previous frame to sufficiently decode this frame.
+ // 2. The disposal method of |clearExceptFrame| is DisposeOverwritePrevious.
+ // In that case, we need to keep the required previous frame in the cache
+ // to prevent re-decoding that frame when |clearExceptFrame| is disposed.
+ //
+ // If either 1 or 2 is true, store the required previous frame in
+ // |clearExceptFrame2| so it won't be cleared.
+ size_t clearExceptFrame2 = kNotFound;
+ if (clearExceptFrame < m_frameBufferCache.size()) {
+ const ImageFrame& frame = m_frameBufferCache[clearExceptFrame];
+ if (!frameStatusSufficientForSuccessors(clearExceptFrame) ||
+ frame.getDisposalMethod() == ImageFrame::DisposeOverwritePrevious)
+ clearExceptFrame2 = frame.requiredPreviousFrameIndex();
+ }
+
+ // Now |clearExceptFrame2| indicates the frame that future frames will depend
scroggo_chromium 2016/11/28 16:34:38 I don't think this comment is quite correct. It's
joostouwerling 2016/11/30 15:09:17 I don't think it was inherently wrong, but I clari
+ // on. But if decoding is skipping forward past intermediate frames, this
+ // frame may be insufficiently decoded. So we need to keep traversing back
+ // through the required previous frames until we find the nearest ancestor
+ // that is sufficiently decoded. Preserving that will minimize the amount of
+ // future decoding needed.
+ while (clearExceptFrame2 < m_frameBufferCache.size() &&
+ !frameStatusSufficientForSuccessors(clearExceptFrame2)) {
+ clearExceptFrame2 =
+ m_frameBufferCache[clearExceptFrame2].requiredPreviousFrameIndex();
+ }
+
+ return clearCacheExceptTwoFrames(clearExceptFrame, clearExceptFrame2);
}
size_t ImageDecoder::clearCacheExceptTwoFrames(size_t clearExceptFrame1,

Powered by Google App Engine
This is Rietveld 408576698