Index: third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp |
diff --git a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp |
index ad4312a12c35d111c8d411957956c4a64cf5ccda..ce558ab747d9cde03b8d07a8d1d176a123f87637 100644 |
--- a/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp |
+++ b/third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp |
@@ -28,7 +28,6 @@ |
#include "platform/RuntimeEnabledFeatures.h" |
#include "platform/SharedBuffer.h" |
#include "platform/graphics/DecodingImageGenerator.h" |
-#include "platform/graphics/FrameData.h" |
#include "platform/graphics/ImageDecodingStore.h" |
#include "platform/graphics/ImageFrameGenerator.h" |
#include "platform/image-decoders/SegmentReader.h" |
@@ -37,6 +36,25 @@ |
namespace blink { |
+struct DeferredFrameData { |
+ DISALLOW_NEW_EXCEPT_PLACEMENT_NEW(); |
+ WTF_MAKE_NONCOPYABLE(DeferredFrameData); |
+public: |
+ DeferredFrameData() |
+ : m_orientation(DefaultImageOrientation) |
+ , m_duration(0) |
+ , m_isComplete(false) |
+ , m_frameBytes(0) |
+ , m_uniqueID(DecodingImageGenerator::kNeedNewImageUniqueID) |
+ {} |
+ |
+ ImageOrientation m_orientation; |
+ float m_duration; |
+ bool m_isComplete; |
+ size_t m_frameBytes; |
+ uint32_t m_uniqueID; |
+}; |
+ |
bool DeferredImageDecoder::s_enabled = true; |
PassOwnPtr<DeferredImageDecoder> DeferredImageDecoder::create(const SharedBuffer& data, ImageDecoder::AlphaOption alphaOption, ImageDecoder::GammaAndColorProfileOption colorOptions) |
@@ -90,16 +108,15 @@ PassRefPtr<SkImage> DeferredImageDecoder::createFrameAtIndex(size_t index) |
prepareLazyDecodedFrames(); |
if (index < m_frameData.size()) { |
- FrameData* frameData = &m_frameData[index]; |
- // ImageFrameGenerator has the latest known alpha state. There will be a |
- // performance boost if this frame is opaque. |
- ASSERT(m_frameGenerator); |
- frameData->m_hasAlpha = m_frameGenerator->hasAlpha(index); |
+ DeferredFrameData* frameData = &m_frameData[index]; |
if (m_actualDecoder) |
frameData->m_frameBytes = m_actualDecoder->frameBytesAtIndex(index); |
else |
frameData->m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelData); |
- return createFrameImageAtIndex(index, !frameData->m_hasAlpha); |
+ // ImageFrameGenerator has the latest known alpha state. There will be a |
+ // performance boost if this frame is opaque. |
+ DCHECK(m_frameGenerator); |
+ return createFrameImageAtIndex(index, !m_frameGenerator->hasAlpha(index)); |
} |
if (!m_actualDecoder || m_actualDecoder->failed()) |
@@ -258,7 +275,6 @@ void DeferredImageDecoder::prepareLazyDecodedFrames() |
return; |
for (size_t i = previousSize; i < m_frameData.size(); ++i) { |
- m_frameData[i].m_haveMetadata = true; |
m_frameData[i].m_duration = m_actualDecoder->frameDurationAtIndex(i); |
m_frameData[i].m_orientation = m_actualDecoder->orientation(); |
m_frameData[i].m_isComplete = m_actualDecoder->frameIsCompleteAtIndex(i); |
@@ -283,7 +299,7 @@ inline SkImageInfo imageInfoFrom(const SkISize& decodedSize, bool knownToBeOpaqu |
return SkImageInfo::MakeN32(decodedSize.width(), decodedSize.height(), knownToBeOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType); |
} |
-PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) const |
+PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, bool knownToBeOpaque) |
{ |
const SkISize& decodedSize = m_frameGenerator->getFullSize(); |
ASSERT(decodedSize.width() > 0); |
@@ -291,11 +307,19 @@ PassRefPtr<SkImage> DeferredImageDecoder::createFrameImageAtIndex(size_t index, |
RefPtr<SkROBuffer> roBuffer = adoptRef(m_rwBuffer->newRBufferSnapshot()); |
RefPtr<SegmentReader> segmentReader = SegmentReader::createFromSkROBuffer(roBuffer.release()); |
- DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenerator, imageInfoFrom(decodedSize, knownToBeOpaque), segmentReader.release(), m_allDataReceived, index); |
+ DecodingImageGenerator* generator = new DecodingImageGenerator(m_frameGenerator, imageInfoFrom(decodedSize, knownToBeOpaque), segmentReader.release(), m_allDataReceived, index, m_frameData[index].m_uniqueID); |
RefPtr<SkImage> image = adoptRef(SkImage::NewFromGenerator(generator)); // SkImage takes ownership of the generator. |
if (!image) |
return nullptr; |
+ // We can consider decoded bitmap constant and reuse uniqueID only after all |
+ // data is received. We reuse it also for multiframe images when image data |
+ // is partially received but the frame data is fully received. |
+ if (m_allDataReceived || m_frameData[index].m_isComplete) { |
+ DCHECK(m_frameData[index].m_uniqueID == DecodingImageGenerator::kNeedNewImageUniqueID || m_frameData[index].m_uniqueID == image->uniqueID()); |
+ m_frameData[index].m_uniqueID = image->uniqueID(); |
+ } |
+ |
generator->setCanYUVDecode(m_canYUVDecode); |
return image.release(); |
@@ -308,3 +332,10 @@ bool DeferredImageDecoder::hotSpot(IntPoint& hotSpot) const |
} |
} // namespace blink |
+ |
+namespace WTF { |
+template<> struct VectorTraits<blink::DeferredFrameData> : public SimpleClassVectorTraits<blink::DeferredFrameData> { |
+ STATIC_ONLY(VectorTraits); |
+ static const bool canInitializeWithMemset = false; // Not all DeferredFrameData members initialize to 0. |
+}; |
+} |