From e22a6a29e2e5664ee907f1abccf615a900cbcfad Mon Sep 17 00:00:00 2001 From: Matt Sarett Date: Wed, 12 Apr 2017 16:26:21 -0400 Subject: [PATCH] SkPictureImageFilter::onMakeColorSpace() 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 Reviewed-by: Mike Klein --- include/effects/SkPictureImageFilter.h | 7 ++++++- src/core/SkColorSpaceXformer.h | 2 ++ src/effects/SkPictureImageFilter.cpp | 27 +++++++++++++++++++++++---- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/include/effects/SkPictureImageFilter.h b/include/effects/SkPictureImageFilter.h index 2782532..13bf66a 100644 --- a/include/effects/SkPictureImageFilter.h +++ b/include/effects/SkPictureImageFilter.h @@ -53,11 +53,12 @@ protected: void flatten(SkWriteBuffer&) const override; sk_sp onFilterImage(SkSpecialImage* source, const Context&, SkIPoint* offset) const override; + sk_sp onMakeColorSpace(SkColorSpaceXformer*) const override; private: explicit SkPictureImageFilter(sk_sp picture); SkPictureImageFilter(sk_sp picture, const SkRect& cropRect, - PictureResolution, SkFilterQuality); + PictureResolution, SkFilterQuality, sk_sp); 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 fColorSpace; + typedef SkImageFilter INHERITED; }; diff --git a/src/core/SkColorSpaceXformer.h b/src/core/SkColorSpaceXformer.h index 6d5aaac..5fc62e0 100644 --- a/src/core/SkColorSpaceXformer.h +++ b/src/core/SkColorSpaceXformer.h @@ -24,6 +24,8 @@ public: void apply(SkColor dst[], const SkColor src[], int n); SkColor apply(SkColor srgb); + sk_sp dst() const { return fDst; } + private: sk_sp apply(const SkShader* shader); diff --git a/src/effects/SkPictureImageFilter.cpp b/src/effects/SkPictureImageFilter.cpp index 6539104..12ec3c2 100644 --- a/src/effects/SkPictureImageFilter.cpp +++ b/src/effects/SkPictureImageFilter.cpp @@ -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 SkPictureImageFilter::Make(sk_sp picture, return sk_sp(new SkPictureImageFilter(std::move(picture), cropRect, kDeviceSpace_PictureResolution, - kLow_SkFilterQuality)); + kLow_SkFilterQuality, + nullptr)); } sk_sp SkPictureImageFilter::MakeForLocalSpace(sk_sp picture, @@ -32,7 +35,8 @@ sk_sp SkPictureImageFilter::MakeForLocalSpace(sk_sp pi return sk_sp(new SkPictureImageFilter(std::move(picture), cropRect, kLocalSpace_PictureResolution, - filterQuality)); + filterQuality, + nullptr)); } SkPictureImageFilter::SkPictureImageFilter(sk_sp picture) @@ -45,12 +49,14 @@ SkPictureImageFilter::SkPictureImageFilter(sk_sp picture) SkPictureImageFilter::SkPictureImageFilter(sk_sp picture, const SkRect& cropRect, PictureResolution pictureResolution, - SkFilterQuality filterQuality) + SkFilterQuality filterQuality, + sk_sp colorSpace) : INHERITED(nullptr, 0, nullptr) , fPicture(std::move(picture)) , fCropRect(cropRect) , fPictureResolution(pictureResolution) - , fFilterQuality(filterQuality) { + , fFilterQuality(filterQuality) + , fColorSpace(std::move(colorSpace)) { } sk_sp SkPictureImageFilter::CreateProc(SkReadBuffer& buffer) { @@ -126,6 +132,14 @@ sk_sp SkPictureImageFilter::onFilterImage(SkSpecialImage* source SkCanvas* canvas = surf->getCanvas(); SkASSERT(canvas); + std::unique_ptr 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 SkPictureImageFilter::onFilterImage(SkSpecialImage* source return surf->makeImageSnapshot(); } +sk_sp SkPictureImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const { + return sk_sp(new SkPictureImageFilter(fPicture, fCropRect, fPictureResolution, + fFilterQuality, xformer->dst())); +} + void SkPictureImageFilter::drawPictureAtDeviceResolution(SkCanvas* canvas, const SkIRect& deviceBounds, const Context& ctx) const { -- 2.7.4