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 |