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

Unified Diff: Source/platform/graphics/ImageFrameGenerator.cpp

Issue 688423004: Remove multi-frame image decoder when the image is completely decoded (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: fix DeferredImageDecoderTest crash Created 6 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: 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);
« no previous file with comments | « Source/platform/graphics/ImageFrameGenerator.h ('k') | Source/platform/graphics/ImageFrameGeneratorTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698