diff options
author | 2016-02-09 05:09:27 -0800 | |
---|---|---|
committer | 2016-02-09 05:09:28 -0800 | |
commit | 4f0379444db31421894d2fce7c85889fe5eaa01a (patch) | |
tree | e15ab5418f286694b6bc6cb2cd3ddbb6cec77253 /src/effects | |
parent | 81bb79b7b97909eb2b10444c4bd06bc9e1e56db3 (diff) |
Alter SkXfermode's asFragmentProcessor & asXPFactory contracts
TBR=bsalomon@google.com
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1674673002
Review URL: https://codereview.chromium.org/1674673002
Diffstat (limited to 'src/effects')
-rw-r--r-- | src/effects/SkArithmeticMode.cpp | 41 | ||||
-rw-r--r-- | src/effects/SkAvoidXfermode.cpp | 16 | ||||
-rw-r--r-- | src/effects/SkPixelXorXfermode.cpp | 16 | ||||
-rw-r--r-- | src/effects/SkXfermodeImageFilter.cpp | 128 |
4 files changed, 104 insertions, 97 deletions
diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp index ff062c3966..3af550bac1 100644 --- a/src/effects/SkArithmeticMode.cpp +++ b/src/effects/SkArithmeticMode.cpp @@ -39,10 +39,9 @@ public: SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) #if SK_SUPPORT_GPU - bool asFragmentProcessor(const GrFragmentProcessor**, - const GrFragmentProcessor* dst) const override; - - bool asXPFactory(GrXPFactory**) const override; + const GrFragmentProcessor* getFragmentProcessorForImageFilter( + const GrFragmentProcessor* dst) const override; + GrXPFactory* asXPFactory() const override; #endif private: @@ -244,28 +243,22 @@ SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, ////////////////////////////////////////////////////////////////////////////// #if SK_SUPPORT_GPU -bool SkArithmeticMode_scalar::asFragmentProcessor(const GrFragmentProcessor** fp, - const GrFragmentProcessor* dst) const { - if (fp) { - *fp = GrArithmeticFP::Create(SkScalarToFloat(fK[0]), - SkScalarToFloat(fK[1]), - SkScalarToFloat(fK[2]), - SkScalarToFloat(fK[3]), - fEnforcePMColor, - dst); - } - return true; +const GrFragmentProcessor* SkArithmeticMode_scalar::getFragmentProcessorForImageFilter( + const GrFragmentProcessor* dst) const { + return GrArithmeticFP::Create(SkScalarToFloat(fK[0]), + SkScalarToFloat(fK[1]), + SkScalarToFloat(fK[2]), + SkScalarToFloat(fK[3]), + fEnforcePMColor, + dst); } -bool SkArithmeticMode_scalar::asXPFactory(GrXPFactory** xpf) const { - if (xpf) { - *xpf = GrArithmeticXPFactory::Create(SkScalarToFloat(fK[0]), - SkScalarToFloat(fK[1]), - SkScalarToFloat(fK[2]), - SkScalarToFloat(fK[3]), - fEnforcePMColor); - } - return true; +GrXPFactory* SkArithmeticMode_scalar::asXPFactory() const { + return GrArithmeticXPFactory::Create(SkScalarToFloat(fK[0]), + SkScalarToFloat(fK[1]), + SkScalarToFloat(fK[2]), + SkScalarToFloat(fK[3]), + fEnforcePMColor); } #endif diff --git a/src/effects/SkAvoidXfermode.cpp b/src/effects/SkAvoidXfermode.cpp index 30da0ad7d3..43d80c9810 100644 --- a/src/effects/SkAvoidXfermode.cpp +++ b/src/effects/SkAvoidXfermode.cpp @@ -521,19 +521,13 @@ const GrXPFactory* GrAvoidXPFactory::TestCreate(GrProcessorTestData* d) { /////////////////////////////////////////////////////////////////////////////// -bool SkAvoidXfermode::asFragmentProcessor(const GrFragmentProcessor** output, - const GrFragmentProcessor* dst) const { - if (output) { - *output = AvoidFP::Create(fOpColor, fTolerance, fMode, dst); - } - return true; +const GrFragmentProcessor* SkAvoidXfermode::getFragmentProcessorForImageFilter( + const GrFragmentProcessor* dst) const { + return AvoidFP::Create(fOpColor, fTolerance, fMode, dst); } -bool SkAvoidXfermode::asXPFactory(GrXPFactory** xpf) const { - if (xpf) { - *xpf = GrAvoidXPFactory::Create(fOpColor, fTolerance, fMode); - } - return true; +GrXPFactory* SkAvoidXfermode::asXPFactory() const { + return GrAvoidXPFactory::Create(fOpColor, fTolerance, fMode); } #endif diff --git a/src/effects/SkPixelXorXfermode.cpp b/src/effects/SkPixelXorXfermode.cpp index 833eecd859..7432ef132b 100644 --- a/src/effects/SkPixelXorXfermode.cpp +++ b/src/effects/SkPixelXorXfermode.cpp @@ -368,19 +368,13 @@ const GrXPFactory* GrPixelXorXPFactory::TestCreate(GrProcessorTestData* d) { /////////////////////////////////////////////////////////////////////////////// -bool SkPixelXorXfermode::asFragmentProcessor(const GrFragmentProcessor** output, - const GrFragmentProcessor* dst) const { - if (output) { - *output = PixelXorFP::Create(fOpColor, dst); - } - return true; +const GrFragmentProcessor* SkPixelXorXfermode::getFragmentProcessorForImageFilter( + const GrFragmentProcessor* dst) const { + return PixelXorFP::Create(fOpColor, dst); } -bool SkPixelXorXfermode::asXPFactory(GrXPFactory** xpf) const { - if (xpf) { - *xpf = GrPixelXorXPFactory::Create(fOpColor); - } - return true; +GrXPFactory* SkPixelXorXfermode::asXPFactory() const { + return GrPixelXorXPFactory::Create(fOpColor); } #endif diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index 5f88240481..fbceedb0dd 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -15,6 +15,7 @@ #if SK_SUPPORT_GPU #include "GrContext.h" #include "GrDrawContext.h" +#include "effects/GrConstColorProcessor.h" #include "effects/GrTextureDomain.h" #include "effects/GrSimpleTextureEffect.h" #include "SkGr.h" @@ -25,12 +26,8 @@ SkXfermodeImageFilter::SkXfermodeImageFilter(SkXfermode* mode, SkImageFilter* inputs[2], const CropRect* cropRect) - : INHERITED(2, inputs, cropRect), fMode(mode) { - SkSafeRef(fMode); -} - -SkXfermodeImageFilter::~SkXfermodeImageFilter() { - SkSafeUnref(fMode); + : INHERITED(2, inputs, cropRect) + , fMode(SkSafeRef(mode)) { } SkFlattenable* SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) { @@ -45,10 +42,10 @@ void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { } bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, - const SkBitmap& src, - const Context& ctx, - SkBitmap* dst, - SkIPoint* offset) const { + const SkBitmap& src, + const Context& ctx, + SkBitmap* dst, + SkIPoint* offset) const { SkBitmap background = src, foreground = src; SkIPoint backgroundOffset = SkIPoint::Make(0, 0); if (!this->filterInput(0, proxy, src, ctx, &background, &backgroundOffset)) { @@ -120,41 +117,47 @@ void SkXfermodeImageFilter::toString(SkString* str) const { #if SK_SUPPORT_GPU bool SkXfermodeImageFilter::canFilterImageGPU() const { - return fMode && fMode->asFragmentProcessor(nullptr, nullptr) && !cropRectIsSet(); + return !this->cropRectIsSet(); } +#include "SkXfermode_proccoeff.h" + bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { + GrContext* context = nullptr; SkBitmap background = src; SkIPoint backgroundOffset = SkIPoint::Make(0, 0); if (!this->filterInputGPU(0, proxy, src, ctx, &background, &backgroundOffset)) { - return false; + background.reset(); } - GrTexture* backgroundTex = background.getTexture(); - if (nullptr == backgroundTex) { - SkASSERT(false); - return false; + if (backgroundTex) { + context = backgroundTex->getContext(); } SkBitmap foreground = src; SkIPoint foregroundOffset = SkIPoint::Make(0, 0); if (!this->filterInputGPU(1, proxy, src, ctx, &foreground, &foregroundOffset)) { - return false; + foreground.reset(); } GrTexture* foregroundTex = foreground.getTexture(); - GrContext* context = foregroundTex->getContext(); + if (foregroundTex) { + context = foregroundTex->getContext(); + } + + if (!context) { + return false; + } + SkIRect bounds = background.bounds().makeOffset(backgroundOffset.x(), backgroundOffset.y()); bounds.join(foreground.bounds().makeOffset(foregroundOffset.x(), foregroundOffset.y())); if (bounds.isEmpty()) { return false; } - const GrFragmentProcessor* xferFP = nullptr; - GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = bounds.width(); @@ -166,39 +169,62 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, } GrPaint paint; - SkMatrix backgroundMatrix; - backgroundMatrix.setIDiv(backgroundTex->width(), backgroundTex->height()); - backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX), - SkIntToScalar(-backgroundOffset.fY)); - SkAutoTUnref<const GrFragmentProcessor> bgFP(GrTextureDomainEffect::Create( - backgroundTex, backgroundMatrix, - GrTextureDomain::MakeTexelDomain(backgroundTex, background.bounds()), - GrTextureDomain::kDecal_Mode, - GrTextureParams::kNone_FilterMode) - ); - if (!fMode || !fMode->asFragmentProcessor(&xferFP, bgFP)) { - // canFilterImageGPU() should've taken care of this - SkASSERT(false); - return false; + SkAutoTUnref<const GrFragmentProcessor> bgFP; + + if (backgroundTex) { + SkMatrix backgroundMatrix; + backgroundMatrix.setIDiv(backgroundTex->width(), backgroundTex->height()); + backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX), + SkIntToScalar(-backgroundOffset.fY)); + bgFP.reset(GrTextureDomainEffect::Create( + backgroundTex, backgroundMatrix, + GrTextureDomain::MakeTexelDomain(backgroundTex, background.bounds()), + GrTextureDomain::kDecal_Mode, + GrTextureParams::kNone_FilterMode)); + } else { + bgFP.reset(GrConstColorProcessor::Create(GrColor_TRANSPARENT_BLACK, + GrConstColorProcessor::kIgnore_InputMode)); + } + + if (foregroundTex) { + SkMatrix foregroundMatrix; + foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height()); + foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX), + SkIntToScalar(-foregroundOffset.fY)); + + SkAutoTUnref<const GrFragmentProcessor> foregroundFP; + + foregroundFP.reset(GrTextureDomainEffect::Create( + foregroundTex, foregroundMatrix, + GrTextureDomain::MakeTexelDomain(foregroundTex, foreground.bounds()), + GrTextureDomain::kDecal_Mode, + GrTextureParams::kNone_FilterMode)); + + paint.addColorFragmentProcessor(foregroundFP.get()); + + // A null fMode is interpreted to mean kSrcOver_Mode (to match raster). + SkAutoTUnref<SkXfermode> mode(SkSafeRef(fMode.get())); + if (!mode) { + // It would be awesome to use SkXfermode::Create here but it knows better + // than us and won't return a kSrcOver_Mode SkXfermode. That means we + // have to get one the hard way. + struct ProcCoeff rec; + rec.fProc = SkXfermode::GetProc(SkXfermode::kSrcOver_Mode); + SkXfermode::ModeAsCoeff(SkXfermode::kSrcOver_Mode, &rec.fSC, &rec.fDC); + + mode.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode)); + } + + SkAutoTUnref<const GrFragmentProcessor> xferFP(mode->getFragmentProcessorForImageFilter(bgFP)); + + // A null 'xferFP' here means kSrc_Mode was used in which case we can just proceed + if (xferFP) { + paint.addColorFragmentProcessor(xferFP); + } + } else { + paint.addColorFragmentProcessor(bgFP); } - SkMatrix foregroundMatrix; - foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height()); - foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX), - SkIntToScalar(-foregroundOffset.fY)); - - - SkAutoTUnref<const GrFragmentProcessor> foregroundFP(GrTextureDomainEffect::Create( - foregroundTex, foregroundMatrix, - GrTextureDomain::MakeTexelDomain(foregroundTex, foreground.bounds()), - GrTextureDomain::kDecal_Mode, - GrTextureParams::kNone_FilterMode) - ); - - paint.addColorFragmentProcessor(foregroundFP.get()); - if (xferFP) { - paint.addColorFragmentProcessor(xferFP)->unref(); - } paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget())); |