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()); |
} |