Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/BitmapImage.cpp |
| diff --git a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp |
| index 78511f31d29142eb28e38b71f05c9731c1ab2495..9ff61ac3a4ea0efbf4124cb449c4af3cb116adc0 100644 |
| --- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp |
| +++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp |
| @@ -69,6 +69,7 @@ BitmapImage::BitmapImage(ImageObserver* observer) |
| , m_sizeAvailable(false) |
| , m_hasUniformFrameSize(true) |
| , m_haveFrameCount(false) |
| + , m_frameIndex(0) |
|
Peter Kasting
2016/05/04 03:01:06
Here and below: Initialize members in the same ord
aleksandar.stojiljkovic
2016/05/07 19:50:52
Done.
|
| { |
| } |
| @@ -86,6 +87,8 @@ BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) |
| , m_haveSize(true) |
| , m_sizeAvailable(true) |
| , m_haveFrameCount(true) |
| + , m_frameIndex(0) |
| + , m_frame(adoptRef(SkImage::NewFromBitmap(bitmap))) |
| { |
| // Since we don't have a decoder, we can't figure out the image orientation. |
| // Set m_sizeRespectingOrientation to be the same as m_size so it's not 0x0. |
| @@ -93,7 +96,6 @@ BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer) |
| m_frames.grow(1); |
| m_frames[0].m_hasAlpha = !bitmap.isOpaque(); |
| - m_frames[0].m_frame = adoptRef(SkImage::NewFromBitmap(bitmap)); |
| m_frames[0].m_haveMetadata = true; |
| } |
| @@ -107,31 +109,13 @@ bool BitmapImage::currentFrameHasSingleSecurityOrigin() const |
| return true; |
| } |
| -void BitmapImage::destroyDecodedData(bool destroyAll) |
| +void BitmapImage::destroyDecodedData() |
| { |
| - for (size_t i = 0; i < m_frames.size(); ++i) { |
| - // The underlying frame isn't actually changing (we're just trying to |
| - // save the memory for the framebuffer data), so we don't need to clear |
| - // the metadata. |
| - m_frames[i].clear(false); |
| - } |
| - |
| - m_source.clearCacheExceptFrame(destroyAll ? kNotFound : m_currentFrame); |
| - notifyMemoryChanged(); |
| -} |
| - |
| -void BitmapImage::destroyDecodedDataIfNecessary() |
| -{ |
| - // Animated images >5MB are considered large enough that we'll only hang on |
| - // to one frame at a time. |
| - static const size_t cLargeAnimationCutoff = 5242880; |
| - size_t allFrameBytes = 0; |
| + m_frame.clear(); |
| for (size_t i = 0; i < m_frames.size(); ++i) |
| - allFrameBytes += m_frames[i].m_frameBytes; |
| - |
| - if (allFrameBytes > cLargeAnimationCutoff) { |
| - destroyDecodedData(false); |
| - } |
| + m_frames[i].clear(true); |
| + m_source.clearCacheExceptFrame(kNotFound); |
| + notifyMemoryChanged(); |
| } |
| void BitmapImage::notifyMemoryChanged() |
| @@ -149,7 +133,7 @@ size_t BitmapImage::totalFrameBytes() |
| return totalBytes; |
| } |
| -void BitmapImage::cacheFrame(size_t index) |
| +PassRefPtr<SkImage> BitmapImage::cacheFrame(size_t index) |
| { |
| size_t numFrames = frameCount(); |
| if (m_frames.size() < numFrames) |
| @@ -157,7 +141,9 @@ void BitmapImage::cacheFrame(size_t index) |
| // We are caching frame snapshots. This is OK even for partially decoded frames, |
| // as they are cleared by dataChanged() when new data arrives. |
| - m_frames[index].m_frame = m_source.createFrameAtIndex(index); |
| + RefPtr<SkImage> image = m_source.createFrameAtIndex(index); |
|
Peter Kasting
2016/05/04 03:01:06
Note that Skia is currently switching to sk_sp and
aleksandar.stojiljkovic
2016/05/04 20:56:29
I found several patches related to switch to sk_sp
|
| + m_frame = image; |
| + m_frameIndex = index; |
| m_frames[index].m_orientation = m_source.orientationAtIndex(index); |
| m_frames[index].m_haveMetadata = true; |
| @@ -172,6 +158,7 @@ void BitmapImage::cacheFrame(size_t index) |
| m_hasUniformFrameSize = false; |
| notifyMemoryChanged(); |
| + return image.release(); |
| } |
| void BitmapImage::updateSize() const |
| @@ -230,6 +217,9 @@ bool BitmapImage::dataChanged(bool allDataReceived) |
| m_frames[i].clear(true); |
| } |
| + if (m_frameIndex < m_frames.size() && m_frames[m_frameIndex].m_haveMetadata && !m_frames[m_frameIndex].m_isComplete) |
| + m_frame.clear(); |
|
Peter Kasting
2016/05/04 03:01:06
I think this would be more clearly associated with
aleksandar.stojiljkovic
2016/05/04 20:56:29
Done.
|
| + |
| // Feed all the data we've seen so far to the image decoder. |
| m_allDataReceived = allDataReceived; |
| ASSERT(data()); |
| @@ -291,7 +281,7 @@ void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& |
| WebCoreClampingModeToSkiaRectConstraint(clampMode)); |
| canvas->restoreToCount(initialSaveCount); |
| - if (currentFrameIsLazyDecoded()) |
| + if (image->isLazyGenerated()) |
| PlatformInstrumentation::didDrawLazyPixelRef(image->uniqueID()); |
| if (ImageObserver* observer = getImageObserver()) |
| @@ -333,23 +323,19 @@ bool BitmapImage::isSizeAvailable() |
| return m_sizeAvailable; |
| } |
| -bool BitmapImage::ensureFrameIsCached(size_t index) |
| -{ |
| - if (index >= frameCount()) |
| - return false; |
| - |
| - if (index >= m_frames.size() || !m_frames[index].m_frame) |
| - cacheFrame(index); |
| - |
| - return true; |
| -} |
| - |
| PassRefPtr<SkImage> BitmapImage::frameAtIndex(size_t index) |
| { |
| - if (!ensureFrameIsCached(index)) |
| + if (index >= frameCount()) |
| return nullptr; |
| - return m_frames[index].m_frame; |
| + RefPtr<SkImage> image; |
| + if (index == m_frameIndex) |
| + image = m_frame; |
| + |
| + if (image) { |
| + return image.release(); |
| + } |
| + return cacheFrame(index); |
|
Peter Kasting
2016/05/04 03:01:06
It seems like this is a long-winded way of writing
aleksandar.stojiljkovic
2016/05/04 20:56:29
Done.
|
| } |
| bool BitmapImage::frameIsCompleteAtIndex(size_t index) |
| @@ -565,9 +551,6 @@ void BitmapImage::resetAnimation() |
| m_repetitionsComplete = 0; |
| m_desiredFrameStartTime = 0; |
| m_animationFinished = false; |
|
Peter Kasting
2016/05/04 03:01:06
Should we clear m_frame here?
aleksandar.stojiljkovic
2016/05/04 20:56:29
Done.
Peter Kasting
2016/05/07 01:58:29
For clarity, I wasn't very sure whether we should
aleksandar.stojiljkovic
2016/05/07 19:50:52
Sorry, the way I handled this clear() was obscure
|
| - |
| - // For extremely large animations, when the animation is reset, we just throw everything away. |
| - destroyDecodedDataIfNecessary(); |
| } |
| bool BitmapImage::maybeAnimated() |
| @@ -625,12 +608,12 @@ bool BitmapImage::internalAdvanceAnimation(bool skippingFrames) |
| } else |
| m_currentFrame = 0; |
| } |
| - destroyDecodedDataIfNecessary(); |
| // We need to draw this frame if we advanced to it while not skipping, or if |
| // while trying to skip frames we hit the last frame and thus had to stop. |
| if (skippingFrames != advancedAnimation) |
| getImageObserver()->animationAdvanced(this); |
| + |
| return advancedAnimation; |
| } |