aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2016-02-09 05:09:27 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-02-09 05:09:28 -0800
commit4f0379444db31421894d2fce7c85889fe5eaa01a (patch)
treee15ab5418f286694b6bc6cb2cd3ddbb6cec77253
parent81bb79b7b97909eb2b10444c4bd06bc9e1e56db3 (diff)
Alter SkXfermode's asFragmentProcessor & asXPFactory contracts
-rw-r--r--include/client/android/SkAvoidXfermode.h6
-rw-r--r--include/client/android/SkPixelXorXfermode.h7
-rw-r--r--include/core/SkXfermode.h39
-rw-r--r--include/effects/SkXfermodeImageFilter.h4
-rw-r--r--src/core/SkXfermode.cpp50
-rw-r--r--src/core/SkXfermode_proccoeff.h7
-rw-r--r--src/effects/SkArithmeticMode.cpp41
-rw-r--r--src/effects/SkAvoidXfermode.cpp16
-rw-r--r--src/effects/SkPixelXorXfermode.cpp16
-rw-r--r--src/effects/SkXfermodeImageFilter.cpp128
-rw-r--r--src/gpu/SkGr.cpp13
-rw-r--r--src/utils/debugger/SkOverdrawMode.cpp16
12 files changed, 163 insertions, 180 deletions
diff --git a/include/client/android/SkAvoidXfermode.h b/include/client/android/SkAvoidXfermode.h
index 8d08827489..34deb8f02f 100644
--- a/include/client/android/SkAvoidXfermode.h
+++ b/include/client/android/SkAvoidXfermode.h
@@ -52,9 +52,9 @@ public:
const SkAlpha aa[]) const override;
#if SK_SUPPORT_GPU
- bool asFragmentProcessor(const GrFragmentProcessor** output,
- const GrFragmentProcessor* dst) const override;
- bool asXPFactory(GrXPFactory** xpf) const override;
+ const GrFragmentProcessor* getFragmentProcessorForImageFilter(
+ const GrFragmentProcessor* dst) const override;
+ GrXPFactory* asXPFactory() const override;
#endif
SK_TO_STRING_OVERRIDE()
diff --git a/include/client/android/SkPixelXorXfermode.h b/include/client/android/SkPixelXorXfermode.h
index 4aa78ccf5e..447bd81317 100644
--- a/include/client/android/SkPixelXorXfermode.h
+++ b/include/client/android/SkPixelXorXfermode.h
@@ -22,10 +22,9 @@ public:
}
#if SK_SUPPORT_GPU
- bool asFragmentProcessor(const GrFragmentProcessor** output,
- const GrFragmentProcessor* dst) const override;
-
- bool asXPFactory(GrXPFactory**) const override;
+ const GrFragmentProcessor* getFragmentProcessorForImageFilter(
+ const GrFragmentProcessor* dst) const override;
+ GrXPFactory* asXPFactory() const override;
#endif
SK_TO_STRING_OVERRIDE()
diff --git a/include/core/SkXfermode.h b/include/core/SkXfermode.h
index 9549452960..76c57a51dd 100644
--- a/include/core/SkXfermode.h
+++ b/include/core/SkXfermode.h
@@ -194,37 +194,22 @@ public:
*/
static bool IsOpaque(const SkXfermode* xfer, SrcColorOpacity opacityType);
- /** Used to do in-shader blending between two colors computed in the shader via a
- GrFragmentProcessor. The input to the returned FP is the src color. The dst color is
- provided by the dst param which becomes a child FP of the returned FP. If the params are
- null then this is just a query of whether the SkXfermode could support this functionality.
- It is legal for the function to succeed but return a null output. This indicates that
+#if SK_SUPPORT_GPU
+ /** Used by the SkXfermodeImageFilter to blend two colors via a GrFragmentProcessor.
+ The input to the returned FP is the src color. The dst color is
+ provided by the dst param which becomes a child FP of the returned FP.
+ It is legal for the function to return a null output. This indicates that
the output of the blend is simply the src color.
*/
- virtual bool asFragmentProcessor(const GrFragmentProcessor** output,
- const GrFragmentProcessor* dst) const;
-
- /** A subclass may implement this factory function to work with the GPU backend. It is legal
- to call this with xpf NULL to simply test the return value. If xpf is non-NULL then the
- xfermode may optionally allocate a factory to return to the caller as *xpf. The caller
- will install it and own a ref to it. Since the xfermode may or may not assign *xpf, the
- caller should set *xpf to NULL beforehand. XferProcessors cannot use a background texture.
- */
- virtual bool asXPFactory(GrXPFactory** xpf) const;
+ virtual const GrFragmentProcessor* getFragmentProcessorForImageFilter(
+ const GrFragmentProcessor* dst) const;
- /** Returns true if the xfermode can be expressed as an xfer processor factory (xpFactory).
- This helper calls the asXPFactory() virtual. If the xfermode is NULL, it is treated as
- kSrcOver_Mode. It is legal to call this with xpf param NULL to simply test the return value.
+ /** A subclass must implement this factory function to work with the GPU backend.
+ The xfermode will return a factory for which the caller will get a ref. It is up
+ to the caller to install it. XferProcessors cannot use a background texture.
*/
- static inline bool AsXPFactory(SkXfermode* xfermode, GrXPFactory** xpf) {
- if (nullptr == xfermode) {
- if (xpf) {
- *xpf = nullptr;
- }
- return true;
- }
- return xfermode->asXPFactory(xpf);
- }
+ virtual GrXPFactory* asXPFactory() const;
+#endif
SK_TO_STRING_PUREVIRT()
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
diff --git a/include/effects/SkXfermodeImageFilter.h b/include/effects/SkXfermodeImageFilter.h
index d59b7a2b25..693425ed05 100644
--- a/include/effects/SkXfermodeImageFilter.h
+++ b/include/effects/SkXfermodeImageFilter.h
@@ -21,8 +21,6 @@ class SK_API SkXfermodeImageFilter : public SkImageFilter {
*/
public:
- virtual ~SkXfermodeImageFilter();
-
static SkImageFilter* Create(SkXfermode* mode, SkImageFilter* background,
SkImageFilter* foreground = NULL,
const CropRect* cropRect = NULL) {
@@ -50,7 +48,7 @@ protected:
void flatten(SkWriteBuffer&) const override;
private:
- SkXfermode* fMode;
+ SkAutoTUnref<SkXfermode> fMode;
typedef SkImageFilter INHERITED;
};
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