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
This commit is contained in:
parent
81bb79b7b9
commit
4f0379444d
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
virtual const GrFragmentProcessor* getFragmentProcessorForImageFilter(
|
||||
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.
|
||||
/** 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.
|
||||
*/
|
||||
virtual bool asXPFactory(GrXPFactory** xpf) 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.
|
||||
*/
|
||||
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()
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
SkMatrix foregroundMatrix;
|
||||
foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height());
|
||||
foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX),
|
||||
SkIntToScalar(-foregroundOffset.fY));
|
||||
if (foregroundTex) {
|
||||
SkMatrix foregroundMatrix;
|
||||
foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height());
|
||||
foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX),
|
||||
SkIntToScalar(-foregroundOffset.fY));
|
||||
|
||||
SkAutoTUnref<const GrFragmentProcessor> foregroundFP;
|
||||
|
||||
SkAutoTUnref<const GrFragmentProcessor> foregroundFP(GrTextureDomainEffect::Create(
|
||||
foregroundTex, foregroundMatrix,
|
||||
GrTextureDomain::MakeTexelDomain(foregroundTex, foreground.bounds()),
|
||||
GrTextureDomain::kDecal_Mode,
|
||||
GrTextureParams::kNone_FilterMode)
|
||||
);
|
||||
foregroundFP.reset(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.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);
|
||||
}
|
||||
|
||||
paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
||||
|
||||
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTarget()));
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user