Chromium Code Reviews| Index: Source/platform/graphics/ImageFrameGenerator.cpp |
| diff --git a/Source/platform/graphics/ImageFrameGenerator.cpp b/Source/platform/graphics/ImageFrameGenerator.cpp |
| index 73c08f1236c6e4b7a7605aade37e30aae9b9e7e4..7d7c69a70ba898429dd4a7814ac60290298acbf5 100644 |
| --- a/Source/platform/graphics/ImageFrameGenerator.cpp |
| +++ b/Source/platform/graphics/ImageFrameGenerator.cpp |
| @@ -133,7 +133,7 @@ bool ImageFrameGenerator::decodeAndScale(const SkImageInfo& info, size_t index, |
| ASSERT(m_fullSize == scaledSize); |
| if (m_decodeFailedAndEmpty) |
| - return 0; |
| + return false; |
| TRACE_EVENT2("blink", "ImageFrameGenerator::decodeAndScale", "generator", this, "decodeCount", static_cast<int>(m_decodeCount)); |
| @@ -169,6 +169,40 @@ bool ImageFrameGenerator::decodeAndScale(const SkImageInfo& info, size_t index, |
| return result; |
| } |
| +bool ImageFrameGenerator::decodeAndScale(void* planes[3], size_t rowBytes[3]) |
| +{ |
| + // This method is called to populate a discardable memory owned by Skia. |
| + |
| + // Prevents concurrent decode or scale operations on the same image data. |
| + MutexLocker lock(m_decodeMutex); |
| + |
| + if (m_decodeFailedAndEmpty) |
| + return false; |
| + |
| + TRACE_EVENT2("blink", "ImageFrameGenerator::decodeAndScale", "generator", this, "decodeCount", static_cast<int>(m_decodeCount)); |
| + |
| + m_hardwareDecoding = (0 != planes) && (0 != planes[0]) && (0 != planes[1]) && (0 != planes[2]) && (0 != rowBytes) && (0 != rowBytes[0]) && (0 != rowBytes[1]) && (0 != rowBytes[2]); |
| + if (!m_hardwareDecoding) { |
| + return false; |
| + } |
| + |
| + DecodingBuffers* decodingBuffers = new DecodingBuffers; |
| + decodingBuffers->set(planes, rowBytes); |
| + m_decodingBuffers = adoptPtr(decodingBuffers); |
| + |
| + ImageDecoder* decoder = 0; |
| + const bool isCached = ImageDecodingStore::instance()->lockDecoder(this, m_fullSize, &decoder); |
| + ASSERT(!isCached || decoder); |
| + |
| + decode(0, &decoder); |
| + |
| + if (isCached) { |
| + ImageDecodingStore::instance()->unlockDecoder(this, decoder); |
| + } |
| + |
| + return m_hardwareDecoding; |
|
Stephen White
2014/07/23 21:45:53
Naming nit: generally we use "accelerated" (or som
sugoi1
2014/07/24 15:48:29
Done.
|
| +} |
| + |
| const ScaledImageFragment* ImageFrameGenerator::tryToLockCompleteCache(const SkISize& scaledSize, size_t index) |
| { |
| const ScaledImageFragment* cachedImage = 0; |
| @@ -262,6 +296,11 @@ PassOwnPtr<ScaledImageFragment> ImageFrameGenerator::decode(size_t index, ImageD |
| (*decoder)->setMemoryAllocator(m_discardableAllocator.get()); |
| } |
| (*decoder)->setData(data, allDataReceived); |
| + if (m_hardwareDecoding) { |
| + (*decoder)->setDecodingBuffers(m_decodingBuffers); |
| + m_hardwareDecoding = (*decoder)->doHardwareDecoding(); |
| + return nullptr; |
| + } |
| // If this call returns a newly allocated DiscardablePixelRef, then |
| // ImageFrame::m_bitmap and the contained DiscardablePixelRef are locked. |
| // They will be unlocked when ImageDecoder is destroyed since ImageDecoder |
| @@ -324,4 +363,57 @@ bool ImageFrameGenerator::hasAlpha(size_t index) |
| return true; |
| } |
| +bool ImageFrameGenerator::getComponentSizes(SkISize* componentSizes) |
| +{ |
| + if (!componentSizes) { |
| + return false; |
| + } |
| + |
| + TRACE_EVENT2("webkit", "ImageFrameGenerator::getImageFormat", "width", m_fullSize.width(), "height", m_fullSize.height()); |
| + |
| + ImageDecoder* decoder = 0; |
| + const bool isCached = ImageDecodingStore::instance()->lockDecoder(this, m_fullSize, &decoder); |
| + ASSERT(!isCached || decoder); |
| + |
| + SharedBuffer* data = 0; |
| + bool allDataReceived = false; |
| + m_data.data(&data, &allDataReceived); |
| + |
| + // Try to create an ImageDecoder |
|
Peter Kasting
2014/07/23 22:17:36
Nit: This comment adds little to the code.
sugoi1
2014/07/24 15:48:29
Done.
|
| + if (!decoder && m_imageDecoderFactory) { |
|
Peter Kasting
2014/07/23 22:17:37
Nit: No {} (several places)
sugoi1
2014/07/24 15:48:29
Done.
|
| + decoder = m_imageDecoderFactory->create().leakPtr(); |
| + } |
| + |
| + if (!decoder) { |
| + decoder = ImageDecoder::create(*data, ImageSource::AlphaPremultiplied, ImageSource::GammaAndColorProfileApplied).leakPtr(); |
| + } |
| + |
| + if (!decoder) { |
|
Peter Kasting
2014/07/23 22:17:36
Nit: This can be moved inside the conditional abov
sugoi1
2014/07/24 15:48:29
Done.
|
| + return false; |
| + } |
| + |
| + // If the decoder isn't cached, take ownership of it here |
|
Peter Kasting
2014/07/23 22:17:36
Nit: Another poor-quality comment.
sugoi1
2014/07/24 15:48:29
Done.
Peter Kasting
2014/07/24 18:08:13
Actually you don't seem to have removed or improve
|
| + OwnPtr<ImageDecoder> decoderContainer; |
|
Peter Kasting
2014/07/23 22:17:36
Nit: Instead of declaring this down here, why not
sugoi1
2014/07/24 15:48:29
Done.
|
| + if (!isCached) { |
| + decoderContainer = adoptPtr(decoder); |
| + } |
| + |
| + decoder->setData(data, allDataReceived); |
| + decoder->setHardwareDecoding(true); |
| + bool canComputeSize = decoder->hardwareDecoding() && decoder->isSizeAvailable(); |
| + if (canComputeSize) { |
| + IntSize size = decoder->decodedSize(0); |
| + componentSizes[0].set(size.width(), size.height()); |
| + size = decoder->decodedSize(1); |
| + componentSizes[1].set(size.width(), size.height()); |
| + size = decoder->decodedSize(2); |
| + componentSizes[2].set(size.width(), size.height()); |
| + } |
| + decoder->setData(0, false); // Unref SharedBuffer from ImageDecoder. |
| + if (isCached) { |
| + ImageDecodingStore::instance()->unlockDecoder(this, decoder); |
| + } |
| + return canComputeSize; |
| +} |
| + |
| } // namespace |