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

Unified Diff: third_party/WebKit/Source/platform/graphics/DeferredImageDecoder.cpp

Issue 1925533003: High CPU and increased memory usage fix for high-res (GIF, WEBP...) animations. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: @scroggo, thanks a lot - this makes page [3] to use 250MB (was 750MB) Created 4 years, 8 months 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 side-by-side diff with in-line comments
Download patch
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 9ea87b7d94178db75d3f5bbe19579caeeb37f9b3..93e2ab841939ce403bd044a1fb3cc22587da9373 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::NeedNewImageUniqueID)
+ {}
+
+ 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.
+ ASSERT(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,12 @@ 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;
+ m_frameData[index].m_uniqueID = (m_allDataReceived || (m_actualDecoder && m_actualDecoder->frameIsCompleteAtIndex(index))) ? image->uniqueID() : DecodingImageGenerator::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
generator->setCanYUVDecode(m_canYUVDecode);
return image.release();
@@ -308,3 +325,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.
+};
+}

Powered by Google App Engine
This is Rietveld 408576698