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

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

Issue 2516593003: Pull up clearCacheExceptFrame to ImageDecoder. (Closed)
Patch Set: Add todo for changing MockImageDecoder Created 4 years 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 23dba5bd2ca969bc3e1ff2f368ebb24584eb74b7..d4a4f49d22e60597b671ab18614637015eeb3d67 100644
--- a/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
+++ b/third_party/WebKit/Source/platform/image-decoders/ImageDecoder.cpp
@@ -216,7 +216,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 |clearExceptFrame|
+ // depends on, as described above. 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