| 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 71f1aab4454813ffe452378c8de55d74052000fd..e8689fd07d4f3602dc1b20a88e7755173332b136 100644
|
| --- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
|
| +++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp
|
| @@ -31,21 +31,28 @@
|
| #include "platform/TraceEvent.h"
|
| #include "platform/geometry/FloatRect.h"
|
| #include "platform/graphics/BitmapImageMetrics.h"
|
| +#include "platform/graphics/ColorSpaceFilter.h"
|
| +#include "platform/graphics/ColorSpaceProfile.h"
|
| #include "platform/graphics/DeferredImageDecoder.h"
|
| +#include "platform/graphics/GraphicsContext.h"
|
| +#include "platform/graphics/GraphicsScreen.h"
|
| +#include "platform/graphics/ImageBuffer.h"
|
| #include "platform/graphics/ImageObserver.h"
|
| #include "platform/graphics/StaticBitmapImage.h"
|
| #include "platform/graphics/skia/SkiaUtils.h"
|
| #include "third_party/skia/include/core/SkCanvas.h"
|
| +#include "third_party/skia/include/core/SkColorFilter.h"
|
| +#include "third_party/skia/include/effects/SkColorFilterImageFilter.h"
|
| #include "wtf/PassRefPtr.h"
|
| +#include "wtf/RefPtr.h"
|
| #include "wtf/text/WTFString.h"
|
|
|
| namespace blink {
|
|
|
| PassRefPtr<BitmapImage> BitmapImage::createWithOrientationForTesting(const SkBitmap& bitmap, ImageOrientation orientation)
|
| {
|
| - if (bitmap.isNull()) {
|
| + if (bitmap.isNull())
|
| return BitmapImage::create();
|
| - }
|
|
|
| RefPtr<BitmapImage> result = adoptRef(new BitmapImage(bitmap));
|
| result->m_frames[0].m_orientation = orientation;
|
| @@ -69,6 +76,7 @@ BitmapImage::BitmapImage(ImageObserver* observer)
|
| , m_sizeAvailable(false)
|
| , m_hasUniformFrameSize(true)
|
| , m_haveFrameCount(false)
|
| + , m_drawingToCanvasElement(false)
|
| {
|
| }
|
|
|
| @@ -86,6 +94,7 @@ BitmapImage::BitmapImage(const SkBitmap& bitmap, ImageObserver* observer)
|
| , m_haveSize(true)
|
| , m_sizeAvailable(true)
|
| , m_haveFrameCount(true)
|
| + , m_drawingToCanvasElement(false)
|
| {
|
| // 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.
|
| @@ -102,16 +111,6 @@ BitmapImage::~BitmapImage()
|
| stopAnimation();
|
| }
|
|
|
| -bool BitmapImage::isBitmapImage() const
|
| -{
|
| - return true;
|
| -}
|
| -
|
| -bool BitmapImage::currentFrameHasSingleSecurityOrigin() const
|
| -{
|
| - return true;
|
| -}
|
| -
|
| int BitmapImage::totalFrameBytes()
|
| {
|
| const size_t numFrames = frameCount();
|
| @@ -142,9 +141,8 @@ void BitmapImage::destroyDecodedDataIfNecessary()
|
| for (size_t i = 0; i < m_frames.size(); ++i)
|
| allFrameBytes += m_frames[i].m_frameBytes;
|
|
|
| - if (allFrameBytes > cLargeAnimationCutoff) {
|
| + if (allFrameBytes > cLargeAnimationCutoff)
|
| destroyDecodedData(false);
|
| - }
|
| }
|
|
|
| void BitmapImage::destroyMetadataAndNotify(size_t frameBytesCleared)
|
| @@ -161,7 +159,6 @@ void BitmapImage::cacheFrame(size_t index)
|
|
|
| int deltaBytes = totalFrameBytes();
|
|
|
| -
|
| // 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);
|
| @@ -269,22 +266,24 @@ void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect&
|
| {
|
| TRACE_EVENT0("skia", "BitmapImage::draw");
|
|
|
| - RefPtr<SkImage> image = imageForCurrentFrame();
|
| - if (!image)
|
| - return; // It's too early and we don't have an image yet.
|
| + RefPtr<SkImage> skImage = imageForCurrentFrame();
|
| + if (!skImage)
|
| + return; // Bail: we don't have an image yet.
|
|
|
| FloatRect adjustedSrcRect = srcRect;
|
| - adjustedSrcRect.intersect(FloatRect(0, 0, image->width(), image->height()));
|
| -
|
| + adjustedSrcRect.intersect(FloatRect(0, 0, skImage->width(), skImage->height()));
|
| if (adjustedSrcRect.isEmpty() || dstRect.isEmpty())
|
| return; // Nothing to draw.
|
| + FloatRect adjustedDstRect = dstRect;
|
|
|
| ImageOrientation orientation = DefaultImageOrientation;
|
| if (shouldRespectImageOrientation == RespectImageOrientation)
|
| orientation = frameOrientationAtIndex(m_currentFrame);
|
|
|
| + SkCanvas::SrcRectConstraint srcRectConstraint = WebCoreClampingModeToSkiaRectConstraint(clampMode);
|
| +
|
| int initialSaveCount = canvas->getSaveCount();
|
| - FloatRect adjustedDstRect = dstRect;
|
| +
|
| if (orientation != DefaultImageOrientation) {
|
| canvas->save();
|
|
|
| @@ -301,14 +300,51 @@ void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect&
|
| }
|
| }
|
|
|
| - SkRect skSrcRect = adjustedSrcRect;
|
| - canvas->drawImageRect(image.get(), skSrcRect, adjustedDstRect, &paint,
|
| - WebCoreClampingModeToSkiaRectConstraint(clampMode));
|
| - canvas->restoreToCount(initialSaveCount);
|
| + RefPtr<SkColorFilter> transform;
|
| + if (imageColorProfilesEnabled() && hasColorProfile())
|
| + transform = imageColorTransform();
|
| +
|
| + if (!transform) {
|
| + canvas->drawImageRect(skImage.get(), adjustedSrcRect, adjustedDstRect, &paint, srcRectConstraint);
|
| +
|
| + canvas->restoreToCount(initialSaveCount);
|
| + if (skImage->isLazyGenerated())
|
| + PlatformInstrumentation::didDrawLazyPixelRef(skImage->uniqueID());
|
| + this->didDraw();
|
| + return;
|
| + }
|
| +
|
| + float srcArea = adjustedSrcRect.width() * adjustedSrcRect.height();
|
| + float dstArea = adjustedDstRect.width() * adjustedDstRect.height();
|
| +
|
| + if (dstArea <= srcArea) {
|
| + SkPaint transformPaint = paint;
|
| + transformPaint.setColorFilter(transform.get());
|
| + canvas->drawImageRect(skImage.get(), adjustedSrcRect, adjustedDstRect, &transformPaint, srcRectConstraint);
|
| +
|
| + canvas->restoreToCount(initialSaveCount);
|
| + if (skImage->isLazyGenerated())
|
| + PlatformInstrumentation::didDrawLazyPixelRef(skImage->uniqueID());
|
| + this->didDraw();
|
| + return;
|
| + }
|
| +
|
| + RefPtr<SkImage> image = skImage; // skImage might be indirectly drawn here (due to transforms).
|
|
|
| - if (currentFrameIsLazyDecoded())
|
| - PlatformInstrumentation::didDrawLazyPixelRef(image->uniqueID());
|
| + if (RefPtr<SkImageFilter> imageFilter = adoptRef(SkColorFilterImageFilter::Create(transform.get())))
|
| + image = adoptRef(image->applyFilter(imageFilter.get(), nullptr, true));
|
|
|
| + canvas->drawImageRect(image.get(), adjustedSrcRect, adjustedDstRect, &paint, srcRectConstraint);
|
| +
|
| + canvas->restoreToCount(initialSaveCount);
|
| + if (skImage->isLazyGenerated())
|
| + PlatformInstrumentation::didDrawLazyPixelRef(skImage->uniqueID());
|
| + this->didDraw();
|
| + return;
|
| +}
|
| +
|
| +void BitmapImage::didDraw()
|
| +{
|
| if (ImageObserver* observer = imageObserver())
|
| observer->didDraw(this);
|
|
|
| @@ -398,6 +434,16 @@ PassRefPtr<Image> BitmapImage::imageForDefaultFrame()
|
| return Image::imageForDefaultFrame();
|
| }
|
|
|
| +PassRefPtr<SkColorFilter> BitmapImage::imageColorTransform()
|
| +{
|
| + if (currentScreenId()) // FIXME: remove these <canvas> code asserts.
|
| + RELEASE_ASSERT(!drawingToCanvasElement());
|
| + else
|
| + RELEASE_ASSERT(drawingToCanvasElement()); // sRGB render target.
|
| +
|
| + return createColorSpaceFilter(colorProfile().get(), screenColorProfile(currentScreenId()).get());
|
| +}
|
| +
|
| bool BitmapImage::frameHasAlphaAtIndex(size_t index)
|
| {
|
| if (m_frames.size() <= index)
|
| @@ -416,6 +462,7 @@ bool BitmapImage::currentFrameKnownToBeOpaque(MetadataMode metadataMode)
|
| // chance of an accurate answer, pre-cache the current frame metadata.
|
| frameAtIndex(currentFrame());
|
| }
|
| +
|
| return !frameHasAlphaAtIndex(currentFrame());
|
| }
|
|
|
|
|