diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkXfermode.cpp | 50 | ||||
-rw-r--r-- | src/core/SkXfermode_proccoeff.h | 7 | ||||
-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 | ||||
-rw-r--r-- | src/gpu/SkGr.cpp | 13 | ||||
-rw-r--r-- | src/utils/debugger/SkOverdrawMode.cpp | 16 |
8 files changed, 144 insertions, 143 deletions
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp index 81083199b3..2f29f1a63d 100644 --- a/src/core/SkXfermode.cpp +++ b/src/core/SkXfermode.cpp @@ -737,14 +737,22 @@ bool SkXfermode::asMode(Mode* mode) const { return false; } -bool SkXfermode::asFragmentProcessor(const GrFragmentProcessor**, - const GrFragmentProcessor*) const { - return false; +#if SK_SUPPORT_GPU +const GrFragmentProcessor* SkXfermode::getFragmentProcessorForImageFilter( + const GrFragmentProcessor*) const { + // This should never be called. + // TODO: make pure virtual in SkXfermode once Android update lands + SkASSERT(0); + return nullptr; } -bool SkXfermode::asXPFactory(GrXPFactory**) const { - return false; +GrXPFactory* SkXfermode::asXPFactory() const { + // This should never be called. + // TODO: make pure virtual in SkXfermode once Android update lands + SkASSERT(0); + return nullptr; } +#endif SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{ // no-op. subclasses should override this @@ -989,33 +997,21 @@ void SkProcCoeffXfermode::xferA8(SkAlpha* SK_RESTRICT dst, #include "effects/GrPorterDuffXferProcessor.h" #include "effects/GrXfermodeFragmentProcessor.h" -bool SkProcCoeffXfermode::asFragmentProcessor(const GrFragmentProcessor** fp, - const GrFragmentProcessor* dst) const { - if (fp) { - SkASSERT(dst); - *fp = GrXfermodeFragmentProcessor::CreateFromDstProcessor(dst, fMode); - SkASSERT(*fp || kSrc_Mode == fMode); - } - return true; +const GrFragmentProcessor* SkProcCoeffXfermode::getFragmentProcessorForImageFilter( + const GrFragmentProcessor* dst) const { + SkASSERT(dst); + return GrXfermodeFragmentProcessor::CreateFromDstProcessor(dst, fMode); } -bool SkProcCoeffXfermode::asXPFactory(GrXPFactory** xp) const { +GrXPFactory* SkProcCoeffXfermode::asXPFactory() const { if (CANNOT_USE_COEFF != fSrcCoeff) { - if (xp) { - *xp = GrPorterDuffXPFactory::Create(fMode); - SkASSERT(*xp); - } - return true; + GrXPFactory* result = GrPorterDuffXPFactory::Create(fMode); + SkASSERT(result); + return result; } - if (GrCustomXfermode::IsSupportedMode(fMode)) { - if (xp) { - *xp = GrCustomXfermode::CreateXPFactory(fMode); - SkASSERT(*xp); - } - return true; - } - return false; + SkASSERT(GrCustomXfermode::IsSupportedMode(fMode)); + return GrCustomXfermode::CreateXPFactory(fMode); } #endif diff --git a/src/core/SkXfermode_proccoeff.h b/src/core/SkXfermode_proccoeff.h index 264d65c2bc..3b45594867 100644 --- a/src/core/SkXfermode_proccoeff.h +++ b/src/core/SkXfermode_proccoeff.h @@ -45,10 +45,9 @@ public: bool isOpaque(SkXfermode::SrcColorOpacity opacityType) const override; #if SK_SUPPORT_GPU - bool asFragmentProcessor(const GrFragmentProcessor**, - const GrFragmentProcessor*) const override; - - bool asXPFactory(GrXPFactory**) const override; + const GrFragmentProcessor* getFragmentProcessorForImageFilter( + const GrFragmentProcessor*) const override; + GrXPFactory* asXPFactory() const override; #endif SK_TO_STRING_OVERRIDE() 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())); diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp index e4dc467e7f..df65e451fe 100644 --- a/src/gpu/SkGr.cpp +++ b/src/gpu/SkGr.cpp @@ -489,10 +489,15 @@ static inline bool skpaint_to_grpaint_impl(GrContext* context, } } - SkXfermode* mode = skPaint.getXfermode(); - GrXPFactory* xpFactory = nullptr; - SkXfermode::AsXPFactory(mode, &xpFactory); - SkSafeUnref(grPaint->setXPFactory(xpFactory)); + // When the xfermode is null on the SkPaint (meaning kSrcOver) we need the XPFactory field on + // the GrPaint to also be null (also kSrcOver). + SkASSERT(!grPaint->getXPFactory()); + SkXfermode* xfermode = skPaint.getXfermode(); + if (xfermode) { + // SafeUnref in case a new xfermode is added that returns null. + // In such cases we will fall back to kSrcOver_Mode. + SkSafeUnref(grPaint->setXPFactory(xfermode->asXPFactory())); + } #ifndef SK_IGNORE_GPU_DITHER if (skPaint.isDither() && grPaint->numColorFragmentProcessors() > 0) { diff --git a/src/utils/debugger/SkOverdrawMode.cpp b/src/utils/debugger/SkOverdrawMode.cpp index 400e58309f..3b695eca26 100644 --- a/src/utils/debugger/SkOverdrawMode.cpp +++ b/src/utils/debugger/SkOverdrawMode.cpp @@ -291,19 +291,13 @@ public: SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOverdrawXfermode) #if SK_SUPPORT_GPU - bool asFragmentProcessor(const GrFragmentProcessor** output, - const GrFragmentProcessor* dst) const override { - if (output) { - *output = GrOverdrawFP::Create(dst); - } - return true; + const GrFragmentProcessor* getFragmentProcessorForImageFilter( + const GrFragmentProcessor* dst) const override { + return GrOverdrawFP::Create(dst); } - bool asXPFactory(GrXPFactory** xpf) const override { - if (xpf) { - *xpf = GrOverdrawXPFactory::Create(); - } - return true; + GrXPFactory* asXPFactory() const override { + return GrOverdrawXPFactory::Create(); } #endif |