SkPictureImageFilter::onMakeColorSpace()
authorMatt Sarett <msarett@google.com>
Wed, 12 Apr 2017 20:26:21 +0000 (16:26 -0400)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Sat, 15 Apr 2017 12:15:36 +0000 (12:15 +0000)
Improves gm/recordopts.
Does not break gm/pictureimagefilter or gm/fastfilterbounds.

Bug: skia:
Change-Id: I67c8f02a9548bf751350dfa3c7029dd59b8a2d1d
Reviewed-on: https://skia-review.googlesource.com/13276
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
include/effects/SkPictureImageFilter.h
src/core/SkColorSpaceXformer.h
src/effects/SkPictureImageFilter.cpp

index 2782532..13bf66a 100644 (file)
@@ -53,11 +53,12 @@ protected:
     void flatten(SkWriteBuffer&) const override;
     sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
                                         SkIPoint* offset) const override;
+    sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
 
 private:
     explicit SkPictureImageFilter(sk_sp<SkPicture> picture);
     SkPictureImageFilter(sk_sp<SkPicture> picture, const SkRect& cropRect,
-                         PictureResolution, SkFilterQuality);
+                         PictureResolution, SkFilterQuality, sk_sp<SkColorSpace>);
 
     void drawPictureAtDeviceResolution(SkCanvas* canvas,
                                        const SkIRect& deviceBounds,
@@ -72,6 +73,10 @@ private:
     PictureResolution     fPictureResolution;
     SkFilterQuality       fFilterQuality;
 
+    // Should never be set by a public constructor.  This is only used when onMakeColorSpace()
+    // forces a deferred color space xform.
+    sk_sp<SkColorSpace>   fColorSpace;
+
     typedef SkImageFilter INHERITED;
 };
 
index 6d5aaac..5fc62e0 100644 (file)
@@ -24,6 +24,8 @@ public:
     void apply(SkColor dst[], const SkColor src[], int n);
     SkColor apply(SkColor srgb);
 
+    sk_sp<SkColorSpace> dst() const { return fDst; }
+
 private:
     sk_sp<SkShader> apply(const SkShader* shader);
 
index 6539104..12ec3c2 100644 (file)
@@ -8,6 +8,8 @@
 #include "SkPictureImageFilter.h"
 
 #include "SkCanvas.h"
+#include "SkColorSpaceXformCanvas.h"
+#include "SkColorSpaceXformer.h"
 #include "SkReadBuffer.h"
 #include "SkSpecialImage.h"
 #include "SkSpecialSurface.h"
@@ -23,7 +25,8 @@ sk_sp<SkImageFilter> SkPictureImageFilter::Make(sk_sp<SkPicture> picture,
     return sk_sp<SkImageFilter>(new SkPictureImageFilter(std::move(picture), 
                                                          cropRect,
                                                          kDeviceSpace_PictureResolution,
-                                                         kLow_SkFilterQuality));
+                                                         kLow_SkFilterQuality,
+                                                         nullptr));
 }
 
 sk_sp<SkImageFilter> SkPictureImageFilter::MakeForLocalSpace(sk_sp<SkPicture> picture,
@@ -32,7 +35,8 @@ sk_sp<SkImageFilter> SkPictureImageFilter::MakeForLocalSpace(sk_sp<SkPicture> pi
     return sk_sp<SkImageFilter>(new SkPictureImageFilter(std::move(picture),
                                                          cropRect,
                                                          kLocalSpace_PictureResolution,
-                                                         filterQuality));
+                                                         filterQuality,
+                                                         nullptr));
 }
 
 SkPictureImageFilter::SkPictureImageFilter(sk_sp<SkPicture> picture)
@@ -45,12 +49,14 @@ SkPictureImageFilter::SkPictureImageFilter(sk_sp<SkPicture> picture)
 
 SkPictureImageFilter::SkPictureImageFilter(sk_sp<SkPicture> picture, const SkRect& cropRect,
                                            PictureResolution pictureResolution,
-                                           SkFilterQuality filterQuality)
+                                           SkFilterQuality filterQuality,
+                                           sk_sp<SkColorSpace> colorSpace)
     : INHERITED(nullptr, 0, nullptr)
     , fPicture(std::move(picture))
     , fCropRect(cropRect)
     , fPictureResolution(pictureResolution)
-    , fFilterQuality(filterQuality) {
+    , fFilterQuality(filterQuality)
+    , fColorSpace(std::move(colorSpace)) {
 }
 
 sk_sp<SkFlattenable> SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) {
@@ -126,6 +132,14 @@ sk_sp<SkSpecialImage> SkPictureImageFilter::onFilterImage(SkSpecialImage* source
     SkCanvas* canvas = surf->getCanvas();
     SkASSERT(canvas);
 
+    std::unique_ptr<SkCanvas> xformCanvas = nullptr;
+    if (fColorSpace) {
+        // Only non-null in the case where onMakeColorSpace() was called.  This instructs
+        // us to do the color space xform on playback.
+        xformCanvas = SkCreateColorSpaceXformCanvas(canvas, fColorSpace);
+        canvas = xformCanvas.get();
+    }
+
     canvas->clear(0x0);
 
     if (kDeviceSpace_PictureResolution == fPictureResolution ||
@@ -140,6 +154,11 @@ sk_sp<SkSpecialImage> SkPictureImageFilter::onFilterImage(SkSpecialImage* source
     return surf->makeImageSnapshot();
 }
 
+sk_sp<SkImageFilter> SkPictureImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
+    return sk_sp<SkImageFilter>(new SkPictureImageFilter(fPicture, fCropRect, fPictureResolution,
+            fFilterQuality, xformer->dst()));
+}
+
 void SkPictureImageFilter::drawPictureAtDeviceResolution(SkCanvas* canvas,
                                                          const SkIRect& deviceBounds,
                                                          const Context& ctx) const {