Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 10 matching lines...) Expand all Loading... | |
| 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 24 */ | 24 */ |
| 25 | 25 |
| 26 #include "platform/graphics/DeferredImageDecoder.h" | 26 #include "platform/graphics/DeferredImageDecoder.h" |
| 27 | 27 |
| 28 #include "platform/RuntimeEnabledFeatures.h" | 28 #include "platform/RuntimeEnabledFeatures.h" |
| 29 #include "platform/SharedBuffer.h" | 29 #include "platform/SharedBuffer.h" |
| 30 #include "platform/graphics/DecodingImageGenerator.h" | 30 #include "platform/graphics/DecodingImageGenerator.h" |
| 31 #include "platform/graphics/FrameData.h" | |
| 32 #include "platform/graphics/ImageDecodingStore.h" | 31 #include "platform/graphics/ImageDecodingStore.h" |
| 33 #include "platform/graphics/ImageFrameGenerator.h" | 32 #include "platform/graphics/ImageFrameGenerator.h" |
| 34 #include "platform/image-decoders/SegmentReader.h" | 33 #include "platform/image-decoders/SegmentReader.h" |
| 35 #include "third_party/skia/include/core/SkImage.h" | 34 #include "third_party/skia/include/core/SkImage.h" |
| 36 #include "wtf/PassOwnPtr.h" | 35 #include "wtf/PassOwnPtr.h" |
| 37 | 36 |
| 38 namespace blink { | 37 namespace blink { |
| 39 | 38 |
| 39 struct DeferredFrameData { | |
| 40 DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); | |
| 41 WTF_MAKE_NONCOPYABLE(DeferredFrameData); | |
| 42 public: | |
| 43 DeferredFrameData() | |
| 44 : m_orientation(DefaultImageOrientation) | |
| 45 , m_duration(0) | |
| 46 , m_isComplete(false) | |
| 47 , m_frameBytes(0) | |
| 48 , m_uniqueID(DecodingImageGenerator::NeedNewImageUniqueID) | |
| 49 {} | |
| 50 | |
| 51 ImageOrientation m_orientation; | |
| 52 float m_duration; | |
| 53 bool m_isComplete; | |
| 54 size_t m_frameBytes; | |
| 55 uint32_t m_uniqueID; | |
| 56 }; | |
| 57 | |
| 40 bool DeferredImageDecoder::s_enabled = true; | 58 bool DeferredImageDecoder::s_enabled = true; |
| 41 | 59 |
| 42 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer & data, ImageDecoder::AlphaOption alphaOption, ImageDecoder::GammaAndColorProfil eOption colorOptions) | 60 PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer & data, ImageDecoder::AlphaOption alphaOption, ImageDecoder::GammaAndColorProfil eOption colorOptions) |
| 43 { | 61 { |
| 44 OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(data, alphaOption, colorOptions); | 62 OwnPtr<ImageDecoder> actualDecoder = ImageDecoder::create(data, alphaOption, colorOptions); |
| 45 | 63 |
| 46 if (!actualDecoder) | 64 if (!actualDecoder) |
| 47 return nullptr; | 65 return nullptr; |
| 48 | 66 |
| 49 return adoptPtr(new DeferredImageDecoder(actualDecoder.release())); | 67 return adoptPtr(new DeferredImageDecoder(actualDecoder.release())); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 83 } | 101 } |
| 84 | 102 |
| 85 PassRefPtr<SkImage> DeferredImageDecoder::createFrameAtIndex(size_t index) | 103 PassRefPtr<SkImage> DeferredImageDecoder::createFrameAtIndex(size_t index) |
| 86 { | 104 { |
| 87 if (m_frameGenerator && m_frameGenerator->decodeFailed()) | 105 if (m_frameGenerator && m_frameGenerator->decodeFailed()) |
| 88 return nullptr; | 106 return nullptr; |
| 89 | 107 |
| 90 prepareLazyDecodedFrames(); | 108 prepareLazyDecodedFrames(); |
| 91 | 109 |
| 92 if (index < m_frameData.size()) { | 110 if (index < m_frameData.size()) { |
| 93 FrameData* frameData = &m_frameData[index]; | 111 DeferredFrameData* frameData = &m_frameData[index]; |
| 94 // ImageFrameGenerator has the latest known alpha state. There will be a | |
| 95 // performance boost if this frame is opaque. | |
| 96 ASSERT(m_frameGenerator); | |
| 97 frameData->m_hasAlpha = m_frameGenerator->hasAlpha(index); | |
| 98 if (m_actualDecoder) | 112 if (m_actualDecoder) |
| 99 frameData->m_frameBytes = m_actualDecoder->frameBytesAtIndex(index); | 113 frameData->m_frameBytes = m_actualDecoder->frameBytesAtIndex(index); |
| 100 else | 114 else |
| 101 frameData->m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelDa ta); | 115 frameData->m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelDa ta); |
| 102 return createFrameImageAtIndex(index, !frameData->m_hasAlpha); | 116 // ImageFrameGenerator has the latest known alpha state. There will be a |
| 117 // performance boost if this frame is opaque. | |
| 118 ASSERT(m_frameGenerator); | |
| 119 return createFrameImageAtIndex(index, !m_frameGenerator->hasAlpha(index) ); | |
| 103 } | 120 } |
| 104 | 121 |
| 105 if (!m_actualDecoder || m_actualDecoder->failed()) | 122 if (!m_actualDecoder || m_actualDecoder->failed()) |
| 106 return nullptr; | 123 return nullptr; |
| 107 | 124 |
| 108 ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index); | 125 ImageFrame* frame = m_actualDecoder->frameBufferAtIndex(index); |
| 109 if (!frame || frame->getStatus() == ImageFrame::FrameEmpty) | 126 if (!frame || frame->getStatus() == ImageFrame::FrameEmpty) |
| 110 return nullptr; | 127 return nullptr; |
| 111 | 128 |
| 112 return adoptRef(SkImage::NewFromBitmap(frame->bitmap())); | 129 return adoptRef(SkImage::NewFromBitmap(frame->bitmap())); |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 251 activateLazyDecoding(); | 268 activateLazyDecoding(); |
| 252 | 269 |
| 253 const size_t previousSize = m_frameData.size(); | 270 const size_t previousSize = m_frameData.size(); |
| 254 m_frameData.resize(m_actualDecoder->frameCount()); | 271 m_frameData.resize(m_actualDecoder->frameCount()); |
| 255 | 272 |
| 256 // We have encountered a broken image file. Simply bail. | 273 // We have encountered a broken image file. Simply bail. |
| 257 if (m_frameData.size() < previousSize) | 274 if (m_frameData.size() < previousSize) |
| 258 return; | 275 return; |
| 259 | 276 |
| 260 for (size_t i = previousSize; i < m_frameData.size(); ++i) { | 277 for (size_t i = previousSize; i < m_frameData.size(); ++i) { |
| 261 m_frameData[i].m_haveMetadata = true; | |
| 262 m_frameData[i].m_duration = m_actualDecoder->frameDurationAtIndex(i); | 278 m_frameData[i].m_duration = m_actualDecoder->frameDurationAtIndex(i); |
| 263 m_frameData[i].m_orientation = m_actualDecoder->orientation(); | 279 m_frameData[i].m_orientation = m_actualDecoder->orientation(); |
| 264 m_frameData[i].m_isComplete = m_actualDecoder->frameIsCompleteAtIndex(i) ; | 280 m_frameData[i].m_isComplete = m_actualDecoder->frameIsCompleteAtIndex(i) ; |
| 265 } | 281 } |
| 266 | 282 |
| 267 // The last lazy decoded frame created from previous call might be | 283 // The last lazy decoded frame created from previous call might be |
| 268 // incomplete so update its state. | 284 // incomplete so update its state. |
| 269 if (previousSize) { | 285 if (previousSize) { |
| 270 const size_t lastFrame = previousSize - 1; | 286 const size_t lastFrame = previousSize - 1; |
| 271 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt Index(lastFrame); | 287 m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAt Index(lastFrame); |
| 272 } | 288 } |
| 273 | 289 |
| 274 if (m_allDataReceived) { | 290 if (m_allDataReceived) { |
| 275 m_repetitionCount = m_actualDecoder->repetitionCount(); | 291 m_repetitionCount = m_actualDecoder->repetitionCount(); |
| 276 m_actualDecoder.clear(); | 292 m_actualDecoder.clear(); |
| 277 // Hold on to m_rwBuffer, which is still needed by createFrameAtIndex. | 293 // Hold on to m_rwBuffer, which is still needed by createFrameAtIndex. |
| 278 } | 294 } |
| 279 } | 295 } |
| 280 | 296 |
| 281 inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaqu e) | 297 inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaqu e) |
| 282 { | 298 { |
| 283 return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), known ToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); | 299 return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), known ToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); |
| 284 } | 300 } |
| 285 | 301 |
| 286 PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const | 302 PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) |
| 287 { | 303 { |
| 288 const SkISize& decodedSize = m_frameGenerator->getFullSize(); | 304 const SkISize& decodedSize = m_frameGenerator->getFullSize(); |
| 289 ASSERT(decodedSize.width() > 0); | 305 ASSERT(decodedSize.width() > 0); |
| 290 ASSERT(decodedSize.height() > 0); | 306 ASSERT(decodedSize.height() > 0); |
| 291 | 307 |
| 292 RefPtr<SkROBuffer> roBuffer = adoptRef(m_rwBuffer->newRBufferSnapshot()); | 308 RefPtr<SkROBuffer> roBuffer = adoptRef(m_rwBuffer->newRBufferSnapshot()); |
| 293 RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkROBuffer(ro Buffer.release()); | 309 RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkROBuffer(ro Buffer.release()); |
| 294 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, imageInfoFrom(decodedSize, knownToBeOpaque), segmentReader.release(), m_all DataReceived, index); | 310 DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenera tor, imageInfoFrom(decodedSize, knownToBeOpaque), segmentReader.release(), m_all DataReceived, index, m_frameData[index].m_uniqueID); |
| 295 RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // S kImage takes ownership of the generator. | 311 RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // S kImage takes ownership of the generator. |
| 296 if (!image) | 312 if (!image) |
| 297 return nullptr; | 313 return nullptr; |
| 298 | 314 |
| 315 m_frameData[index].m_uniqueID = (m_allDataReceived || (m_actualDecoder && m_ actualDecoder->frameIsCompleteAtIndex(index))) ? image->uniqueID() : DecodingIma geGenerator::NeedNewImageUniqueID; | |
|
scroggo_chromium
2016/05/03 13:08:52
Thanks, yes, I forgot to look at the GIF decoder o
Peter Kasting
2016/05/04 03:01:07
I also would think that if m_allDataReceived, then
aleksandar.stojiljkovic
2016/05/04 20:56:29
It is important to have this check:
if (m_allDataR
scroggo_chromium
2016/05/04 21:15:54
Ah, of course! I find it very confusing that frame
| |
| 299 generator->setCanYUVDecode(m_canYUVDecode); | 316 generator->setCanYUVDecode(m_canYUVDecode); |
| 300 | 317 |
| 301 return image.release(); | 318 return image.release(); |
| 302 } | 319 } |
| 303 | 320 |
| 304 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const | 321 bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const |
| 305 { | 322 { |
| 306 // TODO: Implement. | 323 // TODO: Implement. |
| 307 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false; | 324 return m_actualDecoder ? m_actualDecoder->hotSpot(hotSpot) : false; |
| 308 } | 325 } |
| 309 | 326 |
| 310 } // namespace blink | 327 } // namespace blink |
| 328 | |
| 329 namespace WTF { | |
| 330 template<> struct VectorTraits<blink::DeferredFrameData> : public SimpleClassVec torTraits<blink::DeferredFrameData> { | |
| 331 STATIC_ONLY(VectorTraits); | |
| 332 static const bool canInitializeWithMemset = false; // Not all DeferredFrameD ata members initialize to 0. | |
| 333 }; | |
| 334 } | |
| OLD | NEW |