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