| Index: src/gpu/GrBlend.h
 | 
| diff --git a/src/gpu/GrBlend.h b/src/gpu/GrBlend.h
 | 
| index e5b8993377a4ae5baba5c61ad8bb373424d42f19..7021902765bd07024cbe4b8c0d88961c87504908 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
 | 
| 
 |