| Index: Source/platform/graphics/DeferredImageDecoder.cpp
|
| diff --git a/Source/platform/graphics/DeferredImageDecoder.cpp b/Source/platform/graphics/DeferredImageDecoder.cpp
|
| index e1e2ebc949971068a2eadddf6ae5f2008f55dada..61604b6960ac8ac025dd3b43b76a36114056cb33 100644
|
| --- a/Source/platform/graphics/DeferredImageDecoder.cpp
|
| +++ b/Source/platform/graphics/DeferredImageDecoder.cpp
|
| @@ -45,9 +45,7 @@ bool DeferredImageDecoder::s_enabled = false;
|
| DeferredImageDecoder::DeferredImageDecoder(PassOwnPtr<ImageDecoder> actualDecoder)
|
| : m_allDataReceived(false)
|
| , m_lastDataSize(0)
|
| - , m_dataChanged(false)
|
| , m_actualDecoder(actualDecoder)
|
| - , m_orientation(DefaultImageOrientation)
|
| , m_repetitionCount(cAnimationNone)
|
| , m_hasColorProfile(false)
|
| {
|
| @@ -90,26 +88,35 @@ String DeferredImageDecoder::filenameExtension() const
|
| return m_actualDecoder ? m_actualDecoder->filenameExtension() : m_filenameExtension;
|
| }
|
|
|
| -ImageFrame* DeferredImageDecoder::frameBufferAtIndex(size_t index)
|
| +PassRefPtr<NativeImageSkia> DeferredImageDecoder::createFrameAtIndex(size_t index)
|
| {
|
| prepareLazyDecodedFrames();
|
| - if (index < m_lazyDecodedFrames.size()) {
|
| + if (index < m_frameData.size()) {
|
| // ImageFrameGenerator has the latest known alpha state. There will
|
| // be a performance boost if this frame is opaque.
|
| - m_lazyDecodedFrames[index]->setHasAlpha(m_frameGenerator->hasAlpha(index));
|
| - return m_lazyDecodedFrames[index].get();
|
| + SkBitmap bitmap = createBitmap(index);
|
| + if (m_frameGenerator->hasAlpha(index)) {
|
| + m_frameData[index].m_hasAlpha = true;
|
| + bitmap.setAlphaType(kPremul_SkAlphaType);
|
| + } else {
|
| + m_frameData[index].m_hasAlpha = false;
|
| + bitmap.setAlphaType(kOpaque_SkAlphaType);
|
| + }
|
| + m_frameData[index].m_frameBytes = m_size.area() * sizeof(ImageFrame::PixelData);
|
| + return NativeImageSkia::create(bitmap);
|
| }
|
| - if (m_actualDecoder)
|
| - return m_actualDecoder->frameBufferAtIndex(index);
|
| - return 0;
|
| + if (m_actualDecoder) {
|
| + ImageFrame* buffer = m_actualDecoder->frameBufferAtIndex(index);
|
| + if (!buffer || buffer->status() == ImageFrame::FrameEmpty)
|
| + return nullptr;
|
| + return buffer->asNewNativeImage();
|
| + }
|
| + return nullptr;
|
| }
|
|
|
| void DeferredImageDecoder::setData(SharedBuffer& data, bool allDataReceived)
|
| {
|
| if (m_actualDecoder) {
|
| - const bool firstData = !m_data;
|
| - const bool moreData = data.size() > m_lastDataSize;
|
| - m_dataChanged = firstData || moreData;
|
| m_data = RefPtr<SharedBuffer>(data);
|
| m_lastDataSize = data.size();
|
| m_allDataReceived = allDataReceived;
|
| @@ -147,7 +154,7 @@ IntSize DeferredImageDecoder::frameSizeAtIndex(size_t index) const
|
|
|
| size_t DeferredImageDecoder::frameCount()
|
| {
|
| - return m_actualDecoder ? m_actualDecoder->frameCount() : m_lazyDecodedFrames.size();
|
| + return m_actualDecoder ? m_actualDecoder->frameCount() : m_frameData.size();
|
| }
|
|
|
| int DeferredImageDecoder::repetitionCount() const
|
| @@ -157,9 +164,16 @@ int DeferredImageDecoder::repetitionCount() const
|
|
|
| size_t DeferredImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame)
|
| {
|
| - // If image decoding is deferred then frame buffer cache is managed by
|
| - // the compositor and this call is ignored.
|
| - return m_actualDecoder ? m_actualDecoder->clearCacheExceptFrame(clearExceptFrame) : 0;
|
| + if (m_actualDecoder)
|
| + return m_actualDecoder->clearCacheExceptFrame(clearExceptFrame);
|
| + size_t frameBytesCleared = 0;
|
| + for (size_t i = 0; i < m_frameData.size(); ++i) {
|
| + if (i != clearExceptFrame) {
|
| + frameBytesCleared += m_frameData[i].m_frameBytes;
|
| + m_frameData[i].m_frameBytes = 0;
|
| + }
|
| + }
|
| + return frameBytesCleared;
|
| }
|
|
|
| bool DeferredImageDecoder::frameHasAlphaAtIndex(size_t index) const
|
| @@ -175,8 +189,8 @@ bool DeferredImageDecoder::frameIsCompleteAtIndex(size_t index) const
|
| {
|
| if (m_actualDecoder)
|
| return m_actualDecoder->frameIsCompleteAtIndex(index);
|
| - if (index < m_lazyDecodedFrames.size())
|
| - return m_lazyDecodedFrames[index]->status() == ImageFrame::FrameComplete;
|
| + if (index < m_frameData.size())
|
| + return m_frameData[index].m_isComplete;
|
| return false;
|
| }
|
|
|
| @@ -184,21 +198,27 @@ float DeferredImageDecoder::frameDurationAtIndex(size_t index) const
|
| {
|
| if (m_actualDecoder)
|
| return m_actualDecoder->frameDurationAtIndex(index);
|
| - if (index < m_lazyDecodedFrames.size())
|
| - return m_lazyDecodedFrames[index]->duration();
|
| + if (index < m_frameData.size())
|
| + return m_frameData[index].m_duration;
|
| return 0;
|
| }
|
|
|
| unsigned DeferredImageDecoder::frameBytesAtIndex(size_t index) const
|
| {
|
| - // If frame decoding is deferred then it is not managed by MemoryCache
|
| - // so return 0 here.
|
| - return m_frameGenerator ? 0 : m_actualDecoder->frameBytesAtIndex(index);
|
| + if (m_actualDecoder)
|
| + return m_actualDecoder->frameBytesAtIndex(index);
|
| + if (index < m_frameData.size())
|
| + return m_frameData[index].m_frameBytes;
|
| + return 0;
|
| }
|
|
|
| -ImageOrientation DeferredImageDecoder::orientation() const
|
| +ImageOrientation DeferredImageDecoder::orientationAtIndex(size_t index) const
|
| {
|
| - return m_actualDecoder ? m_actualDecoder->orientation() : m_orientation;
|
| + if (m_actualDecoder)
|
| + return m_actualDecoder->orientation();
|
| + if (index < m_frameData.size())
|
| + return m_frameData[index].m_orientation;
|
| + return DefaultImageOrientation;
|
| }
|
|
|
| void DeferredImageDecoder::activateLazyDecoding()
|
| @@ -206,7 +226,6 @@ void DeferredImageDecoder::activateLazyDecoding()
|
| if (m_frameGenerator)
|
| return;
|
| m_size = m_actualDecoder->size();
|
| - m_orientation = m_actualDecoder->orientation();
|
| m_filenameExtension = m_actualDecoder->filenameExtension();
|
| m_hasColorProfile = m_actualDecoder->hasColorProfile();
|
| const bool isSingleFrame = m_actualDecoder->repetitionCount() == cAnimationNone || (m_allDataReceived && m_actualDecoder->frameCount() == 1u);
|
| @@ -223,33 +242,26 @@ void DeferredImageDecoder::prepareLazyDecodedFrames()
|
|
|
| activateLazyDecoding();
|
|
|
| - const size_t previousSize = m_lazyDecodedFrames.size();
|
| - m_lazyDecodedFrames.resize(m_actualDecoder->frameCount());
|
| + const size_t previousSize = m_frameData.size();
|
| + m_frameData.resize(m_actualDecoder->frameCount());
|
|
|
| // We have encountered a broken image file. Simply bail.
|
| - if (m_lazyDecodedFrames.size() < previousSize)
|
| + if (m_frameData.size() < previousSize)
|
| return;
|
|
|
| - for (size_t i = previousSize; i < m_lazyDecodedFrames.size(); ++i) {
|
| + for (size_t i = previousSize; i < m_frameData.size(); ++i) {
|
| OwnPtr<ImageFrame> frame(adoptPtr(new ImageFrame()));
|
| - frame->setSkBitmap(createBitmap(i));
|
| - frame->setDuration(m_actualDecoder->frameDurationAtIndex(i));
|
| - frame->setStatus(m_actualDecoder->frameIsCompleteAtIndex(i) ? ImageFrame::FrameComplete : ImageFrame::FramePartial);
|
| - m_lazyDecodedFrames[i] = frame.release();
|
| + 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);
|
| }
|
|
|
| // The last lazy decoded frame created from previous call might be
|
| // incomplete so update its state.
|
| if (previousSize) {
|
| const size_t lastFrame = previousSize - 1;
|
| - m_lazyDecodedFrames[lastFrame]->setStatus(m_actualDecoder->frameIsCompleteAtIndex(lastFrame) ? ImageFrame::FrameComplete : ImageFrame::FramePartial);
|
| -
|
| - // If data has changed then create a new bitmap. This forces
|
| - // Skia to decode again.
|
| - if (m_dataChanged) {
|
| - m_dataChanged = false;
|
| - m_lazyDecodedFrames[lastFrame]->setSkBitmap(createBitmap(lastFrame));
|
| - }
|
| + m_frameData[lastFrame].m_isComplete = m_actualDecoder->frameIsCompleteAtIndex(lastFrame);
|
| }
|
|
|
| if (m_allDataReceived) {
|
| @@ -262,7 +274,7 @@ void DeferredImageDecoder::prepareLazyDecodedFrames()
|
| // Creates a SkBitmap that is backed by SkDiscardablePixelRef.
|
| SkBitmap DeferredImageDecoder::createBitmap(size_t index)
|
| {
|
| - IntSize decodedSize = m_actualDecoder->decodedSize();
|
| + SkISize decodedSize = m_frameGenerator->getFullSize();
|
| ASSERT(decodedSize.width() > 0);
|
| ASSERT(decodedSize.height() > 0);
|
|
|
|
|