Add interface to SkXfermode to return a GrEffect and blend coeffs.

Review URL: https://codereview.chromium.org/13097006

git-svn-id: http://skia.googlecode.com/svn/trunk@8412 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
bsalomon@google.com 2013-03-27 18:31:15 +00:00
parent 31ec7985f2
commit f51c01328d
3 changed files with 47 additions and 7 deletions

View File

@ -13,6 +13,8 @@
#include "SkFlattenable.h"
#include "SkColor.h"
class GrContext;
class GrEffectRef;
class SkString;
/** \class SkXfermode
@ -74,7 +76,7 @@ public:
/**
* The same as calling xfermode->asCoeff(..), except that this also checks
* if the xfermode is NULL, and if so, treats its as kSrcOver_Mode.
* if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
*/
static bool AsCoeff(const SkXfermode*, Coeff* src, Coeff* dst);
@ -136,7 +138,7 @@ public:
/**
* The same as calling xfermode->asMode(mode), except that this also checks
* if the xfermode is NULL, and if so, treats its as kSrcOver_Mode.
* if the xfermode is NULL, and if so, treats it as kSrcOver_Mode.
*/
static bool AsMode(const SkXfermode*, Mode* mode);
@ -181,6 +183,22 @@ public:
return AsMode(xfer, mode);
}
/** A subclass may implement this factory function to work with the GPU backend. It is legal
to call this with all but the context param NULL to simply test the return value. effect,
src, and dst must all be NULL or all non-NULL. If effect is non-NULL then the xfermode may
optionally allocate an effect to return and the caller as *effect. The caller will install
it and own a ref to it. Since the xfermode may or may not assign *effect, the caller should
set *effect to NULL beforehand. If the function returns true then the src and dst coeffs
will be applied to the draw regardless of whether an effect was returned.
*/
virtual bool asNewEffect(GrContext*, GrEffectRef** effect, Coeff* src, Coeff* dst) const;
/**
* The same as calling xfermode->asNewEffect(...), except that this also checks if the xfermode
* is NULL, and if so, treats it as kSrcOver_Mode.
*/
static bool AsNewEffect(SkXfermode*, GrContext*, GrEffectRef** effect, Coeff* src, Coeff* dst);
SkDEVCODE(virtual void toString(SkString* str) const = 0;)
SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
protected:

View File

@ -680,6 +680,22 @@ bool SkXfermode::asMode(Mode* mode) const {
return false;
}
bool SkXfermode::asNewEffect(GrContext*, GrEffectRef**, Coeff*, Coeff*) const {
return false;
}
bool SkXfermode::AsNewEffect(SkXfermode* xfermode,
GrContext* context,
GrEffectRef** effect,
Coeff* src,
Coeff* dst) {
if (NULL == xfermode) {
return ModeAsCoeff(kSrcOver_Mode, src, dst);
} else {
return xfermode->asNewEffect(context, effect, src, dst);
}
}
SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{
// no-op. subclasses should override this
return dst;
@ -958,6 +974,10 @@ public:
return true;
}
virtual bool asNewEffect(GrContext*, GrEffectRef**, Coeff* src, Coeff* dst) const SK_OVERRIDE {
return this->asCoeff(src, dst);
}
SK_DEVELOPER_TO_STRING()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkProcCoeffXfermode)

View File

@ -484,13 +484,15 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
SkXfermode::Coeff dm = SkXfermode::kISA_Coeff;
SkXfermode* mode = skPaint.getXfermode();
if (mode) {
if (!mode->asCoeff(&sm, &dm)) {
//SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");)
GrEffectRef* xferEffect;
if (SkXfermode::AsNewEffect(mode, dev->context(), &xferEffect, &sm, &dm)) {
// We're not ready for xfermode effects yet
GrAssert(NULL == xferEffect);
} else {
//SkDEBUGCODE(SkDebugf("Unsupported xfer mode.\n");)
#if 0
return false;
return false;
#endif
}
}
grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));