diff options
Diffstat (limited to 'src/gpu/GrBlend.h')
-rw-r--r-- | src/gpu/GrBlend.h | 125 |
1 files changed, 117 insertions, 8 deletions
diff --git a/src/gpu/GrBlend.h b/src/gpu/GrBlend.h index e5b8993377..7021902765 100644 --- a/src/gpu/GrBlend.h +++ b/src/gpu/GrBlend.h @@ -7,13 +7,22 @@ */ #include "GrTypes.h" -#include "GrColor.h" +#include "SkTLogic.h" #include "GrXferProcessor.h" #ifndef GrBlend_DEFINED #define GrBlend_DEFINED -static inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) { +template<GrBlendCoeff Coeff> +struct GrTBlendCoeffRefsSrc : SkTBool<kSC_GrBlendCoeff == Coeff || + kISC_GrBlendCoeff == Coeff || + kSA_GrBlendCoeff == Coeff || + kISA_GrBlendCoeff == Coeff> {}; + +#define GR_BLEND_COEFF_REFS_SRC(COEFF) \ + GrTBlendCoeffRefsSrc<COEFF>::value + +inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) { switch (coeff) { case kSC_GrBlendCoeff: case kISC_GrBlendCoeff: @@ -25,7 +34,17 @@ static inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) { } } -static inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) { + +template<GrBlendCoeff Coeff> +struct GrTBlendCoeffRefsDst : SkTBool<kDC_GrBlendCoeff == Coeff || + kIDC_GrBlendCoeff == Coeff || + kDA_GrBlendCoeff == Coeff || + kIDA_GrBlendCoeff == Coeff> {}; + +#define GR_BLEND_COEFF_REFS_DST(COEFF) \ + GrTBlendCoeffRefsDst<COEFF>::value + +inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) { switch (coeff) { case kDC_GrBlendCoeff: case kIDC_GrBlendCoeff: @@ -37,10 +56,100 @@ static inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) { } } -GrColor GrSimplifyBlend(GrBlendCoeff* srcCoeff, - GrBlendCoeff* dstCoeff, - GrColor srcColor, uint32_t srcCompFlags, - GrColor dstColor, uint32_t dstCompFlags, - GrColor constantColor); + +template<GrBlendCoeff Coeff> +struct GrTBlendCoeffRefsSrc2 : SkTBool<kS2C_GrBlendCoeff == Coeff || + kIS2C_GrBlendCoeff == Coeff || + kS2A_GrBlendCoeff == Coeff || + kIS2A_GrBlendCoeff == Coeff> {}; + +#define GR_BLEND_COEFF_REFS_SRC2(COEFF) \ + GrTBlendCoeffRefsSrc2<COEFF>::value + +inline bool GrBlendCoeffRefsSrc2(GrBlendCoeff coeff) { + switch (coeff) { + case kS2C_GrBlendCoeff: + case kIS2C_GrBlendCoeff: + case kS2A_GrBlendCoeff: + case kIS2A_GrBlendCoeff: + return true; + default: + return false; + } +} + + +template<GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff> +struct GrTBlendCoeffsUseSrcColor : SkTBool<kZero_GrBlendCoeff != SrcCoeff || + GR_BLEND_COEFF_REFS_SRC(DstCoeff)> {}; + +#define GR_BLEND_COEFFS_USE_SRC_COLOR(SRC_COEFF, DST_COEFF) \ + GrTBlendCoeffsUseSrcColor<SRC_COEFF, DST_COEFF>::value + + +template<GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff> +struct GrTBlendCoeffsUseDstColor : SkTBool<GR_BLEND_COEFF_REFS_DST(SrcCoeff) || + kZero_GrBlendCoeff != DstCoeff> {}; + +#define GR_BLEND_COEFFS_USE_DST_COLOR(SRC_COEFF, DST_COEFF) \ + GrTBlendCoeffsUseDstColor<SRC_COEFF, DST_COEFF>::value + + +template<GrBlendEquation Equation> +struct GrTBlendEquationIsAdvanced : SkTBool<Equation >= kFirstAdvancedGrBlendEquation> {}; + +#define GR_BLEND_EQUATION_IS_ADVANCED(EQUATION) \ + GrTBlendEquationIsAdvanced<EQUATION>::value + +inline bool GrBlendEquationIsAdvanced(GrBlendEquation equation) { + return equation >= kFirstAdvancedGrBlendEquation; +} + + +template<GrBlendEquation BlendEquation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff> +struct GrTBlendModifiesDst : SkTBool<(kAdd_GrBlendEquation != BlendEquation && + kReverseSubtract_GrBlendEquation != BlendEquation) || + kZero_GrBlendCoeff != SrcCoeff || + kOne_GrBlendCoeff != DstCoeff> {}; + +#define GR_BLEND_MODIFIES_DST(EQUATION, SRC_COEFF, DST_COEFF) \ + GrTBlendModifiesDst<EQUATION, SRC_COEFF, DST_COEFF>::value + + +/** + * Advanced blend equations can always tweak alpha for coverage. (See GrCustomXfermode.cpp) + * + * For "add" and "reverse subtract" the blend equation with f=coverage is: + * + * D' = f * (S * srcCoeff + D * dstCoeff) + (1-f) * D + * = f * S * srcCoeff + D * (f * dstCoeff + (1 - f)) + * + * (Let srcCoeff be negative for reverse subtract.) We can tweak alpha for coverage when the + * following relationship holds: + * + * (f*S) * srcCoeff' + D * dstCoeff' == f * S * srcCoeff + D * (f * dstCoeff + (1 - f)) + * + * (Where srcCoeff' and dstCoeff' have any reference to S pre-multiplied by f.) + * + * It's easy to see this works for the src term as long as srcCoeff' == srcCoeff (meaning srcCoeff + * does not reference S). For the dst term, this will work as long as the following is true: + *| + * dstCoeff' == f * dstCoeff + (1 - f) + * dstCoeff' == 1 - f * (1 - dstCoeff) + * + * By inspection we can see this will work as long as dstCoeff has a 1, and any other term in + * dstCoeff references S. + */ +template<GrBlendEquation Equation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff> +struct GrTBlendCanTweakAlphaForCoverage : SkTBool<GR_BLEND_EQUATION_IS_ADVANCED(Equation) || + ((kAdd_GrBlendEquation == Equation || + kReverseSubtract_GrBlendEquation == Equation) && + !GR_BLEND_COEFF_REFS_SRC(SrcCoeff) && + (kOne_GrBlendCoeff == DstCoeff || + kISC_GrBlendCoeff == DstCoeff || + kISA_GrBlendCoeff == DstCoeff))> {}; + +#define GR_BLEND_CAN_TWEAK_ALPHA_FOR_COVERAGE(EQUATION, SRC_COEFF, DST_COEFF) \ + GrTBlendCanTweakAlphaForCoverage<EQUATION, SRC_COEFF, DST_COEFF>::value #endif |