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 f1ed3bc48ad0ecf9c56f6faecef61b7225add1a4..1a2ee7c3ec3d11ce78292ce0ba6ec5a9912a8725 100644 |
--- a/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp |
+++ b/third_party/WebKit/Source/platform/graphics/BitmapImage.cpp |
@@ -31,12 +31,20 @@ |
#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/core/SkImageGenerator.h" |
#include "wtf/PassRefPtr.h" |
+#include "wtf/RefPtr.h" |
#include "wtf/text/WTFString.h" |
namespace blink { |
@@ -102,11 +110,6 @@ BitmapImage::~BitmapImage() |
stopAnimation(); |
} |
-bool BitmapImage::isBitmapImage() const |
-{ |
- return true; |
-} |
- |
bool BitmapImage::currentFrameHasSingleSecurityOrigin() const |
{ |
return true; |
@@ -265,26 +268,75 @@ String BitmapImage::filenameExtension() const |
return m_source.filenameExtension(); |
} |
+PassRefPtr<SkImage> BitmapImage::pictureForCurrentFrame() |
+{ |
+ RELEASE_ASSERT(currentFrame() < m_frames.size() && m_frames[currentFrame()].m_frame); |
+ |
+ FrameData& frame = m_frames[currentFrame()]; |
+ |
+ RELEASE_ASSERT(currentScreenId()); // There should be an active graphics screen. |
+ |
+ RefPtr<SkColorFilter> colorTransform; |
+ if (imageColorProfilesEnabled()) { |
+ RefPtr<ColorSpaceProfile> source = colorProfile(); |
+ if (!source) |
+ source = screenColorProfile(ScreenDevice::sRGB); |
+ colorTransform = createColorSpaceFilter(source.get(), screenColorProfile(currentScreenId()).get()); |
+ } |
+ |
+ if (!colorTransform) |
+ return frame.m_frame; |
+ |
+ RefPtr<SkImage> cachedImage = frame.find(colorTransform.get()); |
+ if (cachedImage) |
+ return cachedImage; |
+ |
+ RefPtr<SkImage> skImage = frame.m_frame; |
+ SkPictureRecorder recorder; |
+ SkRect bounds = SkRect::MakeIWH(skImage->width(), skImage->height()); |
+ SkCanvas* canvas = recorder.beginRecording(bounds, nullptr, 0); |
+ SkPaint paint; |
+ paint.setColorFilter(colorTransform.get()); |
+ canvas->drawImage(skImage.get(), 0, 0, &paint); |
+ |
+ RefPtr<SkPicture> picture = adoptRef(recorder.endRecording()); |
+ if (!picture) |
+ return skImage; |
+ |
+ SkISize skISize = SkISize::Make(skImage->width(), skImage->height()); |
+ skImage = adoptRef(SkImage::NewFromPicture(picture.get(), skISize, nullptr, nullptr)); |
+ |
+ // FIXME: Should we not cache if (currentScreenId() == ScreenDevice::sRGBCanvas)? |
+ frame.cache(colorTransform.get(), skImage.get()); |
+ return skImage; |
+} |
+ |
void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dstRect, const FloatRect& srcRect, RespectImageOrientationEnum shouldRespectImageOrientation, ImageClampingMode clampMode) |
{ |
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())); |
+ skImage = pictureForCurrentFrame(); |
+ if (!skImage) |
+ return; |
+ FloatRect adjustedSrcRect = srcRect; |
+ 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,13 +353,11 @@ 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); |
+ canvas->drawImageRect(skImage.get(), adjustedSrcRect, adjustedDstRect, &paint, srcRectConstraint); |
- if (currentFrameIsLazyDecoded()) |
- PlatformInstrumentation::didDrawLazyPixelRef(image->uniqueID()); |
+ canvas->restoreToCount(initialSaveCount); |
+ if (skImage->isLazyGenerated()) |
+ PlatformInstrumentation::didDrawLazyPixelRef(skImage->uniqueID()); |
if (ImageObserver* observer = imageObserver()) |
observer->didDraw(this); |
@@ -399,6 +449,11 @@ PassRefPtr<Image> BitmapImage::imageForDefaultFrame() |
return Image::imageForDefaultFrame(); |
} |
+PassRefPtr<SkColorFilter> BitmapImage::imageColorTransform() |
+{ |
+ return createColorSpaceFilter(colorProfile().get(), screenColorProfile(currentScreenId()).get()); |
+} |
+ |
bool BitmapImage::frameHasAlphaAtIndex(size_t index) |
{ |
if (m_frames.size() <= index) |