SkImageFilter::onMakeColorSpace() - more overrides

Fills out most of the simple implementations.
Improves 22 gms in gbr-8888.

Bug: skia:
Change-Id: I881ade140993568263de75be51aed240d2de8cc6
Reviewed-on: https://skia-review.googlesource.com/13126
Commit-Queue: Matt Sarett <msarett@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
This commit is contained in:
Matt Sarett 2017-04-10 16:35:33 -04:00 committed by Skia Commit-Bot
parent 67cadde35b
commit 6d72ed918d
28 changed files with 213 additions and 7 deletions

View File

@ -411,8 +411,24 @@ protected:
}
private:
// For makeColorSpace().
friend class ArithmeticImageFilterImpl;
friend class SkAlphaThresholdFilterImpl;
friend class SkBlurImageFilterImpl;
friend class SkColorFilterImageFilter;
friend class SkColorSpaceXformer;
friend class SkComposeImageFilter;
friend class SkDisplacementMapEffect;
friend class SkDropShadowImageFilter;
friend class SkImageSource;
friend class SkMagnifierImageFilter;
friend class SkMatrixConvolutionImageFilter;
friend class SkMergeImageFilter;
friend class SkMorphologyImageFilter;
friend class SkOffsetImageFilter;
friend class SkTileImageFilter;
friend class SkXfermodeImageFilter_Base;
friend class SkGraphics;
static void PurgeCache();

View File

@ -25,6 +25,7 @@ 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;
bool onIsColorFilterNode(SkColorFilter**) const override;
bool onCanHandleComplexCTM() const override { return true; }
bool affectsTransparentBlack() const override;

View File

@ -26,6 +26,7 @@ protected:
}
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
SkIPoint* offset) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
SkIRect onFilterBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
bool onCanHandleComplexCTM() const override { return true; }

View File

@ -35,6 +35,7 @@ public:
virtual SkIRect onFilterBounds(const SkIRect& src, const SkMatrix&,
MapDirection) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
SK_TO_STRING_OVERRIDE()

View File

@ -36,6 +36,7 @@ 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;
SkIRect onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
private:

View File

@ -29,6 +29,7 @@ protected:
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
SkIPoint* offset) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
private:
explicit SkImageSource(sk_sp<SkImage>);

View File

@ -30,6 +30,7 @@ protected:
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
SkIPoint* offset) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
private:
SkRect fSrcRect;

View File

@ -81,6 +81,7 @@ protected:
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
SkIPoint* offset) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
bool affectsTransparentBlack() const override;

View File

@ -27,6 +27,7 @@ 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;
bool onCanHandleComplexCTM() const override { return true; }
private:

View File

@ -42,6 +42,7 @@ protected:
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source,
const Context&,
SkIPoint* offset) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
void flatten(SkWriteBuffer&) const override;
SkISize radius() const { return fRadius; }

View File

@ -26,6 +26,7 @@ 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;
SkIRect onFilterNodeBounds(const SkIRect&, const SkMatrix&, MapDirection) const override;
private:

View File

@ -33,6 +33,7 @@ protected:
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
SkIPoint* offset) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
private:
SkTileImageFilter(const SkRect& srcRect, const SkRect& dstRect, sk_sp<SkImageFilter> input)

View File

@ -35,6 +35,7 @@ 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;
SkIRect onFilterNodeBounds(const SkIRect& src, const SkMatrix&, MapDirection) const override;
private:
@ -273,6 +274,17 @@ sk_sp<SkSpecialImage> SkBlurImageFilterImpl::onFilterImage(SkSpecialImage* sourc
dst, &source->props());
}
sk_sp<SkImageFilter> SkBlurImageFilterImpl::onMakeColorSpace(SkColorSpaceXformer* xformer)
const {
SkASSERT(1 == this->countInputs());
if (!this->getInput(0)) {
return sk_ref_sp(const_cast<SkBlurImageFilterImpl*>(this));
}
sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
return SkImageFilter::MakeBlur(fSigma.width(), fSigma.height(), std::move(input),
this->getCropRectIfSet());
}
SkRect SkBlurImageFilterImpl::computeFastBounds(const SkRect& src) const {
SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;

View File

@ -44,6 +44,17 @@ sk_sp<SkImage> SkColorSpaceXformer::apply(const SkBitmap& src) {
return xformed;
}
// As far as I know, SkModeColorFilter is the only color filter that holds a color.
sk_sp<SkColorFilter> SkColorSpaceXformer::apply(const SkColorFilter* colorFilter) {
SkColor color;
SkBlendMode mode;
if (colorFilter->asColorMode(&color, &mode)) {
return SkColorFilter::MakeModeFilter(this->apply(color), mode);
}
return sk_ref_sp(const_cast<SkColorFilter*>(colorFilter));
}
void SkColorSpaceXformer::apply(SkColor* xformed, const SkColor* srgb, int n) {
SkAssertResult(fFromSRGB->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, xformed,
SkColorSpaceXform::kBGRA_8888_ColorFormat, srgb,
@ -160,12 +171,10 @@ const SkPaint& SkColorSpaceXformer::apply(const SkPaint& src) {
}
}
// As far as I know, SkModeColorFilter is the only color filter that holds a color.
if (auto cf = src.getColorFilter()) {
SkColor color;
SkBlendMode mode;
if (cf->asColorMode(&color, &mode)) {
get_dst()->setColorFilter(SkColorFilter::MakeModeFilter(this->apply(color), mode));
auto replacement = this->apply(cf);
if (replacement.get() != cf) {
get_dst()->setColorFilter(std::move(replacement));
}
}

View File

@ -18,12 +18,13 @@ public:
sk_sp<SkImage> apply(const SkImage* src);
sk_sp<SkImage> apply(const SkBitmap& bitmap);
sk_sp<SkColorFilter> apply(const SkColorFilter* shader);
const SkPaint* apply(const SkPaint* src);
const SkPaint& apply(const SkPaint& src);
void apply(SkColor dst[], const SkColor src[], int n);
SkColor apply(SkColor srgb);
private:
SkColor apply(SkColor srgb);
sk_sp<SkShader> apply(const SkShader* shader);
SkColorSpaceXformer() {}

View File

@ -37,8 +37,10 @@ protected:
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
SkIPoint* offset) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
#if SK_SUPPORT_GPU
sk_sp<GrTextureProxy> createMaskTexture(GrContext*,
sk_sp<GrTextureProxy> createMaskTexture(GrContext*,
const SkMatrix&,
const SkIRect& bounds) const;
#endif
@ -262,6 +264,18 @@ sk_sp<SkSpecialImage> SkAlphaThresholdFilterImpl::onFilterImage(SkSpecialImage*
dst);
}
sk_sp<SkImageFilter> SkAlphaThresholdFilterImpl::onMakeColorSpace(SkColorSpaceXformer* xformer)
const {
SkASSERT(1 == this->countInputs());
if (!this->getInput(0)) {
return sk_ref_sp(const_cast<SkAlphaThresholdFilterImpl*>(this));
}
sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
return SkAlphaThresholdFilter::Make(fRegion, fInnerThreshold, fOuterThreshold,
std::move(input), this->getCropRectIfSet());
}
#ifndef SK_IGNORE_TO_STRING
void SkAlphaThresholdFilterImpl::toString(SkString* str) const {
str->appendf("SkAlphaThresholdImageFilter: (");

View File

@ -9,6 +9,7 @@
#include "SkCanvas.h"
#include "SkColorFilter.h"
#include "SkColorSpaceXformer.h"
#include "SkReadBuffer.h"
#include "SkSpecialImage.h"
#include "SkSpecialSurface.h"
@ -116,6 +117,18 @@ sk_sp<SkSpecialImage> SkColorFilterImageFilter::onFilterImage(SkSpecialImage* so
return surf->makeImageSnapshot();
}
sk_sp<SkImageFilter> SkColorFilterImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer)
const {
SkASSERT(1 == this->countInputs());
sk_sp<SkImageFilter> input =
this->getInput(0) ? this->getInput(0)->makeColorSpace(xformer) : nullptr;
sk_sp<SkColorFilter> colorFilter = xformer->apply(fColorFilter.get());
return SkColorFilterImageFilter::Make(std::move(colorFilter), std::move(input),
this->getCropRectIfSet());
}
bool SkColorFilterImageFilter::onIsColorFilterNode(SkColorFilter** filter) const {
SkASSERT(1 == this->countInputs());
if (!this->cropRectIsSet()) {

View File

@ -61,6 +61,13 @@ sk_sp<SkSpecialImage> SkComposeImageFilter::onFilterImage(SkSpecialImage* source
return outer;
}
sk_sp<SkImageFilter> SkComposeImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
SkASSERT(2 == this->countInputs() && this->getInput(0) && this->getInput(1));
return SkComposeImageFilter::Make(this->getInput(0)->makeColorSpace(xformer),
this->getInput(1)->makeColorSpace(xformer));
}
SkIRect SkComposeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
MapDirection direction) const {
SkImageFilter* outer = this->getInput(0);

View File

@ -412,6 +412,23 @@ sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* sou
dst);
}
sk_sp<SkImageFilter> SkDisplacementMapEffect::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
SkASSERT(2 == this->countInputs());
if (!this->getInput(1)) {
return sk_ref_sp(const_cast<SkDisplacementMapEffect*>(this));
}
// Intentionally avoid xforming the displacement filter. The values will be used as
// offsets, not as colors.
sk_sp<SkImageFilter> displacement = sk_ref_sp(const_cast<SkImageFilter*>(this->getInput(0)));
sk_sp<SkImageFilter> color =
this->getInput(1) ? this->getInput(1)->makeColorSpace(xformer) : nullptr;
return SkDisplacementMapEffect::Make(fXChannelSelector, fYChannelSelector, fScale,
std::move(displacement), std::move(color),
this->getCropRectIfSet());
}
SkRect SkDisplacementMapEffect::computeFastBounds(const SkRect& src) const {
SkRect bounds = this->getColorInput() ? this->getColorInput()->computeFastBounds(src) : src;
bounds.outset(SkScalarAbs(fScale) * SK_ScalarHalf, SkScalarAbs(fScale) * SK_ScalarHalf);

View File

@ -9,6 +9,7 @@
#include "SkBlurImageFilter.h"
#include "SkCanvas.h"
#include "SkColorSpaceXformer.h"
#include "SkReadBuffer.h"
#include "SkSpecialImage.h"
#include "SkSpecialSurface.h"
@ -112,6 +113,16 @@ sk_sp<SkSpecialImage> SkDropShadowImageFilter::onFilterImage(SkSpecialImage* sou
return surf->makeImageSnapshot();
}
sk_sp<SkImageFilter> SkDropShadowImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
SkASSERT(1 == this->countInputs());
sk_sp<SkImageFilter> input =
this->getInput(0) ? this->getInput(0)->makeColorSpace(xformer) : nullptr;
return SkDropShadowImageFilter::Make(fDx, fDy, fSigmaX, fSigmaY, xformer->apply(fColor),
fShadowMode, std::move(input));
}
SkRect SkDropShadowImageFilter::computeFastBounds(const SkRect& src) const {
SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
SkRect shadowBounds = bounds;

View File

@ -8,6 +8,7 @@
#include "SkImageSource.h"
#include "SkCanvas.h"
#include "SkColorSpaceXformer.h"
#include "SkImage.h"
#include "SkReadBuffer.h"
#include "SkSpecialImage.h"
@ -131,6 +132,12 @@ sk_sp<SkSpecialImage> SkImageSource::onFilterImage(SkSpecialImage* source, const
return surf->makeImageSnapshot();
}
sk_sp<SkImageFilter> SkImageSource::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
SkASSERT(0 == this->countInputs());
return SkImageSource::Make(xformer->apply(fImage.get()), fSrcRect, fDstRect, fFilterQuality);
}
SkRect SkImageSource::computeFastBounds(const SkRect& src) const {
return fDstRect;
}

View File

@ -447,6 +447,17 @@ sk_sp<SkSpecialImage> SkMagnifierImageFilter::onFilterImage(SkSpecialImage* sour
dst);
}
sk_sp<SkImageFilter> SkMagnifierImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
SkASSERT(1 == this->countInputs());
if (!this->getInput(0)) {
return sk_ref_sp(const_cast<SkMagnifierImageFilter*>(this));
}
sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
return SkMagnifierImageFilter::Make(fSrcRect, fInset, std::move(input),
this->getCropRectIfSet());
}
#ifndef SK_IGNORE_TO_STRING
void SkMagnifierImageFilter::toString(SkString* str) const {
str->appendf("SkMagnifierImageFilter: (");

View File

@ -388,6 +388,19 @@ sk_sp<SkSpecialImage> SkMatrixConvolutionImageFilter::onFilterImage(SkSpecialIma
dst);
}
sk_sp<SkImageFilter> SkMatrixConvolutionImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer)
const {
SkASSERT(1 == this->countInputs());
if (!this->getInput(0)) {
return sk_ref_sp(const_cast<SkMatrixConvolutionImageFilter*>(this));
}
sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
return SkMatrixConvolutionImageFilter::Make(fKernelSize, fKernel, fGain, fBias, fKernelOffset,
fTileMode, fConvolveAlpha, std::move(input),
this->getCropRectIfSet());
}
SkIRect SkMatrixConvolutionImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
MapDirection direction) const {
SkIRect dst = src;

View File

@ -143,6 +143,18 @@ sk_sp<SkSpecialImage> SkMergeImageFilter::onFilterImage(SkSpecialImage* source,
return surf->makeImageSnapshot();
}
sk_sp<SkImageFilter> SkMergeImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
SkSTArray<5, sk_sp<SkImageFilter>> inputs(this->countInputs());
SkSTArray<5, SkBlendMode> modes(this->countInputs());
for (int i = 0; i < this->countInputs(); i++) {
inputs.push_back(this->getInput(i) ? this->getInput(i)->makeColorSpace(xformer) : nullptr);
modes.push_back((SkBlendMode) fModes[i]);
}
return SkMergeImageFilter::MakeN(inputs.begin(), this->countInputs(), modes.begin(),
this->getCropRectIfSet());
}
sk_sp<SkFlattenable> SkMergeImageFilter::CreateProc(SkReadBuffer& buffer) {
Common common;
if (!common.unflatten(buffer, -1)) {

View File

@ -660,3 +660,17 @@ sk_sp<SkSpecialImage> SkMorphologyImageFilter::onFilterImage(SkSpecialImage* sou
return SkSpecialImage::MakeFromRaster(SkIRect::MakeWH(bounds.width(), bounds.height()),
dst, &source->props());
}
sk_sp<SkImageFilter> SkMorphologyImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
SkASSERT(1 == this->countInputs());
if (!this->getInput(0)) {
return sk_ref_sp(const_cast<SkMorphologyImageFilter*>(this));
}
sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
return (SkMorphologyImageFilter::kDilate_Op == this->op())
? SkDilateImageFilter::Make(fRadius.width(), fRadius.height(), std::move(input),
this->getCropRectIfSet())
: SkErodeImageFilter::Make(fRadius.width(), fRadius.height(), std::move(input),
this->getCropRectIfSet());
}

View File

@ -73,6 +73,17 @@ sk_sp<SkSpecialImage> SkOffsetImageFilter::onFilterImage(SkSpecialImage* source,
}
}
sk_sp<SkImageFilter> SkOffsetImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
SkASSERT(1 == this->countInputs());
if (!this->getInput(0)) {
return sk_ref_sp(const_cast<SkOffsetImageFilter*>(this));
}
sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
return SkOffsetImageFilter::Make(fOffset.fX, fOffset.fY, std::move(input),
this->getCropRectIfSet());
}
SkRect SkOffsetImageFilter::computeFastBounds(const SkRect& src) const {
SkRect bounds = this->getInput(0) ? this->getInput(0)->computeFastBounds(src) : src;
bounds.offset(fOffset.fX, fOffset.fY);

View File

@ -116,6 +116,16 @@ sk_sp<SkSpecialImage> SkTileImageFilter::onFilterImage(SkSpecialImage* source,
return surf->makeImageSnapshot();
}
sk_sp<SkImageFilter> SkTileImageFilter::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
SkASSERT(1 == this->countInputs());
if (!this->getInput(0)) {
return sk_ref_sp(const_cast<SkTileImageFilter*>(this));
}
sk_sp<SkImageFilter> input = this->getInput(0)->makeColorSpace(xformer);
return SkTileImageFilter::Make(fSrcRect, fDstRect, std::move(input));
}
SkIRect SkTileImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix& ctm,
MapDirection direction) const {
SkRect rect = kReverse_MapDirection == direction ? fSrcRect : fDstRect;

View File

@ -38,6 +38,7 @@ public:
protected:
sk_sp<SkSpecialImage> onFilterImage(SkSpecialImage* source, const Context&,
SkIPoint* offset) const override;
sk_sp<SkImageFilter> onMakeColorSpace(SkColorSpaceXformer*) const override;
#if SK_SUPPORT_GPU
sk_sp<SkSpecialImage> filterImageGPU(SkSpecialImage* source,
@ -187,6 +188,22 @@ sk_sp<SkSpecialImage> SkXfermodeImageFilter_Base::onFilterImage(SkSpecialImage*
return surf->makeImageSnapshot();
}
sk_sp<SkImageFilter> SkXfermodeImageFilter_Base::onMakeColorSpace(SkColorSpaceXformer* xformer)
const {
SkASSERT(2 == this->countInputs());
if (!this->getInput(0) && !this->getInput(1)) {
return sk_ref_sp(const_cast<SkXfermodeImageFilter_Base*>(this));
}
sk_sp<SkImageFilter> background =
this->getInput(0) ? this->getInput(0)->makeColorSpace(xformer) : nullptr;
sk_sp<SkImageFilter> foreground =
this->getInput(1) ? this->getInput(1)->makeColorSpace(xformer) : nullptr;
return SkXfermodeImageFilter::Make(fMode, std::move(background), std::move(foreground),
this->getCropRectIfSet());
}
void SkXfermodeImageFilter_Base::drawForeground(SkCanvas* canvas, SkSpecialImage* img,
const SkIRect& fgBounds) const {
SkPaint paint;