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

Side by Side 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: 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 size = decoder->decodedYUVSize(2, sizeType); 83 size = decoder->decodedYUVSize(2, sizeType);
84 componentSizes[2].set(size.width(), size.height()); 84 componentSizes[2].set(size.width(), size.height());
85 return true; 85 return true;
86 } 86 }
87 87
88 ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<Sha redBuffer> data, bool allDataReceived, bool isMultiFrame) 88 ImageFrameGenerator::ImageFrameGenerator(const SkISize& fullSize, PassRefPtr<Sha redBuffer> data, bool allDataReceived, bool isMultiFrame)
89 : m_fullSize(fullSize) 89 : m_fullSize(fullSize)
90 , m_isMultiFrame(isMultiFrame) 90 , m_isMultiFrame(isMultiFrame)
91 , m_decodeFailedAndEmpty(false) 91 , m_decodeFailedAndEmpty(false)
92 , m_decodeCount(0) 92 , m_decodeCount(0)
93 , m_framesCount(0)
Alpha Left Google 2014/10/31 17:17:49 No need to have this variable.
93 { 94 {
94 setData(data.get(), allDataReceived); 95 setData(data.get(), allDataReceived);
95 } 96 }
96 97
97 ImageFrameGenerator::~ImageFrameGenerator() 98 ImageFrameGenerator::~ImageFrameGenerator()
98 { 99 {
99 ImageDecodingStore::instance()->removeCacheIndexedByGenerator(this); 100 ImageDecodingStore::instance()->removeCacheIndexedByGenerator(this);
100 } 101 }
101 102
102 void ImageFrameGenerator::setData(PassRefPtr<SharedBuffer> data, bool allDataRec eived) 103 void ImageFrameGenerator::setData(PassRefPtr<SharedBuffer> data, bool allDataRec eived)
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 198
198 ImageDecoder* decoder = 0; 199 ImageDecoder* decoder = 0;
199 const bool resumeDecoding = ImageDecodingStore::instance()->lockDecoder(this , m_fullSize, &decoder); 200 const bool resumeDecoding = ImageDecodingStore::instance()->lockDecoder(this , m_fullSize, &decoder);
200 ASSERT(!resumeDecoding || decoder); 201 ASSERT(!resumeDecoding || decoder);
201 202
202 SkBitmap fullSizeImage; 203 SkBitmap fullSizeImage;
203 bool complete = decode(index, &decoder, &fullSizeImage); 204 bool complete = decode(index, &decoder, &fullSizeImage);
204 205
205 if (!decoder) 206 if (!decoder)
206 return SkBitmap(); 207 return SkBitmap();
208 if (index >= m_frameComplete.size())
209 m_frameComplete.resize(index + 1);
210 m_frameComplete[index] = complete;
207 211
208 // If we are not resuming decoding that means the decoder is freshly 212 // If we are not resuming decoding that means the decoder is freshly
209 // created and we have ownership. If we are resuming decoding then 213 // created and we have ownership. If we are resuming decoding then
210 // the decoder is owned by ImageDecodingStore. 214 // the decoder is owned by ImageDecodingStore.
211 OwnPtr<ImageDecoder> decoderContainer; 215 OwnPtr<ImageDecoder> decoderContainer;
212 if (!resumeDecoding) 216 if (!resumeDecoding)
213 decoderContainer = adoptPtr(decoder); 217 decoderContainer = adoptPtr(decoder);
214 218
215 if (fullSizeImage.isNull()) { 219 if (fullSizeImage.isNull()) {
216 // If decode has failed and resulted an empty image we can save work 220 // If decode has failed and resulted an empty image we can save work
217 // in the future by returning early. 221 // in the future by returning early.
218 m_decodeFailedAndEmpty = !m_isMultiFrame && decoder->failed(); 222 m_decodeFailedAndEmpty = !m_isMultiFrame && decoder->failed();
219 223
220 if (resumeDecoding) 224 if (resumeDecoding)
221 ImageDecodingStore::instance()->unlockDecoder(this, decoder); 225 ImageDecodingStore::instance()->unlockDecoder(this, decoder);
222 return SkBitmap(); 226 return SkBitmap();
223 } 227 }
224 228
225 // If the image generated is complete then there is no need to keep 229 // If the image generated is complete then there is no need to keep
226 // the decoder. The exception is multi-frame decoder which can generate 230 // the decoder. The exception is multi-frame decoder which can generate
227 // multiple complete frames. 231 // multiple complete frames.
228 const bool removeDecoder = complete && !m_isMultiFrame; 232 size_t completeFrameCount = 0;
233
234 for (Vector<bool>::iterator it = m_frameComplete.begin(); it != m_frameCompl ete.end(); ++it) {
235 if (*it)
236 completeFrameCount++;
237 }
238
239 const bool removeDecoder = m_framesCount && (completeFrameCount >= m_framesC ount);
Alpha Left Google 2014/10/31 17:17:49 It's better to have all the states to compute |rem
229 240
230 if (resumeDecoding) { 241 if (resumeDecoding) {
231 if (removeDecoder) 242 if (removeDecoder)
232 ImageDecodingStore::instance()->removeDecoder(this, decoder); 243 ImageDecodingStore::instance()->removeDecoder(this, decoder);
Alpha Left Google 2014/10/31 17:17:48 Need to clear m_frameComplete() here.
233 else 244 else
234 ImageDecodingStore::instance()->unlockDecoder(this, decoder); 245 ImageDecodingStore::instance()->unlockDecoder(this, decoder);
235 } else if (!removeDecoder) { 246 } else if (!removeDecoder) {
236 ImageDecodingStore::instance()->insertDecoder(this, decoderContainer.rel ease()); 247 ImageDecodingStore::instance()->insertDecoder(this, decoderContainer.rel ease());
237 } 248 }
238 return fullSizeImage; 249 return fullSizeImage;
239 } 250 }
240 251
241 void ImageFrameGenerator::setHasAlpha(size_t index, bool hasAlpha) 252 void ImageFrameGenerator::setHasAlpha(size_t index, bool hasAlpha)
242 { 253 {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 286
276 if (!m_isMultiFrame && newDecoder && allDataReceived) { 287 if (!m_isMultiFrame && newDecoder && allDataReceived) {
277 // If we're using an external memory allocator that means we're decoding 288 // If we're using an external memory allocator that means we're decoding
278 // directly into the output memory and we can save one memcpy. 289 // directly into the output memory and we can save one memcpy.
279 ASSERT(m_externalAllocator.get()); 290 ASSERT(m_externalAllocator.get());
280 (*decoder)->setMemoryAllocator(m_externalAllocator.get()); 291 (*decoder)->setMemoryAllocator(m_externalAllocator.get());
281 } 292 }
282 (*decoder)->setData(data, allDataReceived); 293 (*decoder)->setData(data, allDataReceived);
283 294
284 ImageFrame* frame = (*decoder)->frameBufferAtIndex(index); 295 ImageFrame* frame = (*decoder)->frameBufferAtIndex(index);
296 if (allDataReceived) {
Alpha Left Google 2014/10/31 17:17:48 I prefer you move this block to "tryToResumeDecode
Zhenyu Shan 2014/11/03 08:19:17 There is an issue here: decoder->frameCount() and
Alpha Left Google 2014/11/05 00:31:00 Okay that makes sense. Please see latest comments.
297 m_framesCount = (*decoder)->frameCount();
298 m_frameComplete.resize(m_framesCount);
299 }
300
285 (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder. 301 (*decoder)->setData(0, false); // Unref SharedBuffer from ImageDecoder.
286 (*decoder)->clearCacheExceptFrame(index); 302 (*decoder)->clearCacheExceptFrame(index);
287 (*decoder)->setMemoryAllocator(0); 303 (*decoder)->setMemoryAllocator(0);
288 304
289 if (!frame || frame->status() == ImageFrame::FrameEmpty) 305 if (!frame || frame->status() == ImageFrame::FrameEmpty)
290 return false; 306 return false;
291 307
292 // A cache object is considered complete if we can decode a complete frame. 308 // A cache object is considered complete if we can decode a complete frame.
293 // Or we have received all data. The image might not be fully decoded in 309 // Or we have received all data. The image might not be fully decoded in
294 // the latter case. 310 // the latter case.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 347
332 // Setting a dummy ImagePlanes object signals to the decoder that we want to do YUV decoding. 348 // Setting a dummy ImagePlanes object signals to the decoder that we want to do YUV decoding.
333 decoder->setData(data, allDataReceived); 349 decoder->setData(data, allDataReceived);
334 OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes); 350 OwnPtr<ImagePlanes> dummyImagePlanes = adoptPtr(new ImagePlanes);
335 decoder->setImagePlanes(dummyImagePlanes.release()); 351 decoder->setImagePlanes(dummyImagePlanes.release());
336 352
337 return updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder:: SizeForMemoryAllocation); 353 return updateYUVComponentSizes(decoder.get(), componentSizes, ImageDecoder:: SizeForMemoryAllocation);
338 } 354 }
339 355
340 } // namespace blink 356 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698