OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2013 Google Inc. | 3 * Copyright 2013 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrTypes.h" | 9 #include "GrTypes.h" |
10 #include "GrColor.h" | 10 #include "SkTLogic.h" |
11 #include "GrXferProcessor.h" | 11 #include "GrXferProcessor.h" |
12 | 12 |
13 #ifndef GrBlend_DEFINED | 13 #ifndef GrBlend_DEFINED |
14 #define GrBlend_DEFINED | 14 #define GrBlend_DEFINED |
15 | 15 |
16 static inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) { | 16 inline bool GrBlendCoeffRefsSrc(GrBlendCoeff coeff) { |
17 switch (coeff) { | 17 switch (coeff) { |
18 case kSC_GrBlendCoeff: | 18 case kSC_GrBlendCoeff: |
19 case kISC_GrBlendCoeff: | 19 case kISC_GrBlendCoeff: |
20 case kSA_GrBlendCoeff: | 20 case kSA_GrBlendCoeff: |
21 case kISA_GrBlendCoeff: | 21 case kISA_GrBlendCoeff: |
22 return true; | 22 return true; |
23 default: | 23 default: |
24 return false; | 24 return false; |
25 } | 25 } |
26 } | 26 } |
27 | 27 |
28 static inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) { | 28 template<GrBlendCoeff Coeff> |
| 29 struct GrTBlendCoeffRefsSrc : SkTBool<kSC_GrBlendCoeff == Coeff || |
| 30 kISC_GrBlendCoeff == Coeff || |
| 31 kSA_GrBlendCoeff == Coeff || |
| 32 kISA_GrBlendCoeff == Coeff> {}; |
| 33 |
| 34 #define GR_BLEND_COEFF_REFS_SRC(COEFF) \ |
| 35 GrTBlendCoeffRefsSrc<COEFF>::value |
| 36 |
| 37 |
| 38 inline bool GrBlendCoeffRefsDst(GrBlendCoeff coeff) { |
29 switch (coeff) { | 39 switch (coeff) { |
30 case kDC_GrBlendCoeff: | 40 case kDC_GrBlendCoeff: |
31 case kIDC_GrBlendCoeff: | 41 case kIDC_GrBlendCoeff: |
32 case kDA_GrBlendCoeff: | 42 case kDA_GrBlendCoeff: |
33 case kIDA_GrBlendCoeff: | 43 case kIDA_GrBlendCoeff: |
34 return true; | 44 return true; |
35 default: | 45 default: |
36 return false; | 46 return false; |
37 } | 47 } |
38 } | 48 } |
39 | 49 |
40 GrColor GrSimplifyBlend(GrBlendCoeff* srcCoeff, | 50 template<GrBlendCoeff Coeff> |
41 GrBlendCoeff* dstCoeff, | 51 struct GrTBlendCoeffRefsDst : SkTBool<kDC_GrBlendCoeff == Coeff || |
42 GrColor srcColor, uint32_t srcCompFlags, | 52 kIDC_GrBlendCoeff == Coeff || |
43 GrColor dstColor, uint32_t dstCompFlags, | 53 kDA_GrBlendCoeff == Coeff || |
44 GrColor constantColor); | 54 kIDA_GrBlendCoeff == Coeff> {}; |
| 55 |
| 56 #define GR_BLEND_COEFF_REFS_DST(COEFF) \ |
| 57 GrTBlendCoeffRefsDst<COEFF>::value |
| 58 |
| 59 |
| 60 inline bool GrBlendCoeffRefsBlendColor(GrBlendCoeff coeff) { |
| 61 switch (coeff) { |
| 62 case kConstC_GrBlendCoeff: |
| 63 case kIConstC_GrBlendCoeff: |
| 64 case kConstA_GrBlendCoeff: |
| 65 case kIConstA_GrBlendCoeff: |
| 66 return true; |
| 67 default: |
| 68 return false; |
| 69 } |
| 70 } |
| 71 |
| 72 template<GrBlendCoeff Coeff> |
| 73 struct GrTBlendCoeffRefsBlendColor : SkTBool<kConstC_GrBlendCoeff == Coeff || |
| 74 kIConstC_GrBlendCoeff == Coeff || |
| 75 kConstA_GrBlendCoeff == Coeff || |
| 76 kIConstA_GrBlendCoeff == Coeff> {}; |
| 77 |
| 78 #define GR_BLEND_COEFF_REFS_BLEND_COLOR(COEFF) \ |
| 79 GrTBlendCoeffRefsBlendColor<COEFF>::value |
| 80 |
| 81 |
| 82 inline bool GrBlendCoeffRefsSrc2(GrBlendCoeff coeff) { |
| 83 switch (coeff) { |
| 84 case kS2C_GrBlendCoeff: |
| 85 case kIS2C_GrBlendCoeff: |
| 86 case kS2A_GrBlendCoeff: |
| 87 case kIS2A_GrBlendCoeff: |
| 88 return true; |
| 89 default: |
| 90 return false; |
| 91 } |
| 92 } |
| 93 |
| 94 template<GrBlendCoeff Coeff> |
| 95 struct GrTBlendCoeffRefsSrc2 : SkTBool<kS2C_GrBlendCoeff == Coeff || |
| 96 kIS2C_GrBlendCoeff == Coeff || |
| 97 kS2A_GrBlendCoeff == Coeff || |
| 98 kIS2A_GrBlendCoeff == Coeff> {}; |
| 99 |
| 100 #define GR_BLEND_COEFF_REFS_SRC2(COEFF) \ |
| 101 GrTBlendCoeffRefsSrc2<COEFF>::value |
| 102 |
| 103 |
| 104 inline bool GrBlendCoeffsUseSrcColor(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoef
f) { |
| 105 return kZero_GrBlendCoeff != srcCoeff || GrBlendCoeffRefsSrc(dstCoeff); |
| 106 } |
| 107 |
| 108 template<GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff> |
| 109 struct GrTBlendCoeffsUseSrcColor : SkTBool<kZero_GrBlendCoeff != SrcCoeff || |
| 110 GR_BLEND_COEFF_REFS_SRC(DstCoeff)> {}
; |
| 111 |
| 112 #define GR_BLEND_COEFFS_USE_SRC_COLOR(SRC_COEFF, DST_COEFF) \ |
| 113 GrTBlendCoeffsUseSrcColor<SRC_COEFF, DST_COEFF>::value |
| 114 |
| 115 |
| 116 inline bool GrBlendCoeffsUseDstColor(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoef
f) { |
| 117 return GrBlendCoeffRefsDst(srcCoeff) || kZero_GrBlendCoeff != dstCoeff; |
| 118 } |
| 119 |
| 120 template<GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff> |
| 121 struct GrTBlendCoeffsUseDstColor : SkTBool<GR_BLEND_COEFF_REFS_DST(SrcCoeff) || |
| 122 kZero_GrBlendCoeff != DstCoeff> {}; |
| 123 |
| 124 #define GR_BLEND_COEFFS_USE_DST_COLOR(SRC_COEFF, DST_COEFF) \ |
| 125 GrTBlendCoeffsUseDstColor<SRC_COEFF, DST_COEFF>::value |
| 126 |
| 127 |
| 128 inline bool GrBlendEquationIsAdvanced(GrBlendEquation equation) { |
| 129 return equation >= kFirstAdvancedGrBlendEquation; |
| 130 } |
| 131 |
| 132 template<GrBlendEquation Equation> |
| 133 struct GrTBlendEquationIsAdvanced : SkTBool<Equation >= kFirstAdvancedGrBlendEqu
ation> {}; |
| 134 |
| 135 #define GR_BLEND_EQUATION_IS_ADVANCED(EQUATION) \ |
| 136 GrTBlendEquationIsAdvanced<EQUATION>::value |
| 137 |
| 138 |
| 139 inline bool GrBlendModifiesDst(GrBlendEquation equation, |
| 140 GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { |
| 141 if (kAdd_GrBlendEquation != equation && kReverseSubtract_GrBlendEquation !=
equation) { |
| 142 return true; |
| 143 } |
| 144 return kZero_GrBlendCoeff != srcCoeff || kOne_GrBlendCoeff != dstCoeff; |
| 145 } |
| 146 |
| 147 template<GrBlendEquation BlendEquation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstC
oeff> |
| 148 struct GrTBlendModifiesDst : SkTBool<(kAdd_GrBlendEquation != BlendEquation && |
| 149 kReverseSubtract_GrBlendEquation != BlendE
quation) || |
| 150 kZero_GrBlendCoeff != SrcCoeff || |
| 151 kOne_GrBlendCoeff != DstCoeff> {}; |
| 152 |
| 153 #define GR_BLEND_MODIFIES_DST(EQUATION, SRC_COEFF, DST_COEFF) \ |
| 154 GrTBlendModifiesDst<EQUATION, SRC_COEFF, DST_COEFF>::value |
| 155 |
| 156 |
| 157 inline bool GrBlendCanTweakAlphaForCoverage(GrBlendEquation equation, |
| 158 GrBlendCoeff srcCoeff, GrBlendCoeff
dstCoeff) { |
| 159 if (GrBlendEquationIsAdvanced(equation)) { |
| 160 return true; // See GrCustomXfermode.cpp for an explanation on why this
works. |
| 161 } |
| 162 if (kSubtract_GrBlendEquation == equation) { |
| 163 return false; |
| 164 } |
| 165 |
| 166 SkASSERT(kAdd_GrBlendEquation == equation || kReverseSubtract_GrBlendEquatio
n == equation); |
| 167 |
| 168 /* |
| 169 The blend equation at this point with f=coverage is: |
| 170 |
| 171 D' = f * (S * srcCoeff + D * dstCoeff) + (1-f) * D |
| 172 = f * S * srcCoeff + D * (f * dstCoeff + (1 - f)) |
| 173 |
| 174 (Let srcCoeff be negative for reverse subtract.) We can tweak alpha for cove
rage when the |
| 175 following relationship holds: |
| 176 |
| 177 (f*S) * srcCoeff' + D * dstCoeff' == f * S * srcCoeff + D * (f * dstCoeff
+ (1 - f)) |
| 178 |
| 179 (Where srcCoeff' and dstCoeff' have any reference to S pre-multiplied by f.) |
| 180 |
| 181 It's easy to see this works for the src term as long as srcCoeff' == srcCoef
f (meaning srcCoeff |
| 182 does not reference S). For the dst term, the test can be rewritten as follow
s: |
| 183 |
| 184 D * dstCoeff' == D * (1 - f * (1 - dstCoeff)) |
| 185 |
| 186 By inspection we can see this will work as long as dstCoeff has a 1, and any
other term in |
| 187 dstCoeff references S. |
| 188 */ |
| 189 |
| 190 if (GrBlendCoeffRefsSrc(srcCoeff)) { |
| 191 return false; |
| 192 } |
| 193 |
| 194 switch (dstCoeff) { |
| 195 case kOne_GrBlendCoeff: |
| 196 case kISC_GrBlendCoeff: |
| 197 case kISA_GrBlendCoeff: |
| 198 return true; |
| 199 default: |
| 200 return false; |
| 201 } |
| 202 } |
| 203 |
| 204 template<GrBlendEquation Equation, GrBlendCoeff SrcCoeff, GrBlendCoeff DstCoeff> |
| 205 struct GrTBlendCanTweakAlphaForCoverage : SkTBool<GR_BLEND_EQUATION_IS_ADVANCED(
Equation) || |
| 206 ((kAdd_GrBlendEquation == Equa
tion || |
| 207 kReverseSubtract_GrBlendEqua
tion == Equation) && |
| 208 !GR_BLEND_COEFF_REFS_SRC(SrcC
oeff) && |
| 209 (kOne_GrBlendCoeff == DstCoef
f || |
| 210 kISC_GrBlendCoeff == DstCoef
f || |
| 211 kISA_GrBlendCoeff == DstCoef
f))> {}; |
| 212 |
| 213 #define GR_BLEND_CAN_TWEAK_ALPHA_FOR_COVERAGE(EQUATION, SRC_COEFF, DST_COEFF) \ |
| 214 GrTBlendCanTweakAlphaForCoverage<EQUATION, SRC_COEFF, DST_COEFF>::value |
45 | 215 |
46 #endif | 216 #endif |
OLD | NEW |