| Index: Source/platform/graphics/ImageFrameGenerator.cpp
|
| diff --git a/Source/platform/graphics/ImageFrameGenerator.cpp b/Source/platform/graphics/ImageFrameGenerator.cpp
|
| index 46e281b4f5ad6ca3dbc0987c93883a982d2a18fb..1ce013fc8cbac88720873236819f6ad3584cf09d 100644
|
| --- a/Source/platform/graphics/ImageFrameGenerator.cpp
|
| +++ b/Source/platform/graphics/ImageFrameGenerator.cpp
|
| @@ -90,6 +90,7 @@ ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<Sha
|
| , m_isMultiFrame(isMultiFrame)
|
| , m_decodeFailedAndEmpty(false)
|
| , m_decodeCount(0)
|
| + , m_frameCount(0)
|
| {
|
| setData(data.get(), allDataReceived);
|
| }
|
| @@ -204,6 +205,9 @@ SkBitmap ImageFrameGenerator::tryToResumeDecode(const SkISize& scaledSize, size_
|
|
|
| if (!decoder)
|
| return SkBitmap();
|
| + if (index >= m_frameComplete.size())
|
| + m_frameComplete.resize(index + 1);
|
| + m_frameComplete[index] = complete;
|
|
|
| // If we are not resuming decoding that means the decoder is freshly
|
| // created and we have ownership. If we are resuming decoding then
|
| @@ -223,13 +227,26 @@ SkBitmap ImageFrameGenerator::tryToResumeDecode(const SkISize& scaledSize, size_
|
| }
|
|
|
| // If the image generated is complete then there is no need to keep
|
| - // the decoder. The exception is multi-frame decoder which can generate
|
| - // multiple complete frames.
|
| - const bool removeDecoder = complete && !m_isMultiFrame;
|
| + // the decoder. For multi-frame images, if all frames in the image are
|
| + // decoded, we remove the decoder.
|
| + bool removeDecoder;
|
| +
|
| + if (m_isMultiFrame) {
|
| + size_t decodedFrameCount = 0;
|
| + for (Vector<bool>::iterator it = m_frameComplete.begin(); it != m_frameComplete.end(); ++it) {
|
| + if (*it)
|
| + decodedFrameCount++;
|
| + }
|
| + removeDecoder = m_frameCount && (decodedFrameCount == m_frameCount);
|
| + } else {
|
| + removeDecoder = complete;
|
| + }
|
|
|
| if (resumeDecoding) {
|
| - if (removeDecoder)
|
| + if (removeDecoder) {
|
| ImageDecodingStore::instance()->removeDecoder(this, decoder);
|
| + m_frameComplete.clear();
|
| + }
|
| else
|
| ImageDecodingStore::instance()->unlockDecoder(this, decoder);
|
| } else if (!removeDecoder) {
|
| @@ -282,6 +299,13 @@ bool ImageFrameGenerator::decode(size_t index, ImageDecoder** decoder, SkBitmap*
|
| (*decoder)->setData(data, allDataReceived);
|
|
|
| ImageFrame* frame = (*decoder)->frameBufferAtIndex(index);
|
| + // For multi-frame image decoders, we need to know how many frames are
|
| + // in that image in order to release the decoder when all frames are
|
| + // decoded. frameCount() is reliable only if all data is received and set in
|
| + // decoder, particularly with GIF.
|
| + if (allDataReceived)
|
| + m_frameCount = (*decoder)->frameCount();
|
| +
|
| (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder.
|
| (*decoder)->clearCacheExceptFrame(index);
|
| (*decoder)->setMemoryAllocator(0);
|
|
|