OLD | NEW |
| (Empty) |
1 | |
2 /* | |
3 * Copyright 2013 Google Inc. | |
4 * | |
5 * Use of this source code is governed by a BSD-style license that can be | |
6 * found in the LICENSE file. | |
7 */ | |
8 | |
9 #include "GrBlend.h" | |
10 | |
11 static inline GrBlendCoeff swap_coeff_src_dst(GrBlendCoeff coeff) { | |
12 switch (coeff) { | |
13 case kDC_GrBlendCoeff: | |
14 return kSC_GrBlendCoeff; | |
15 case kIDC_GrBlendCoeff: | |
16 return kISC_GrBlendCoeff; | |
17 case kDA_GrBlendCoeff: | |
18 return kSA_GrBlendCoeff; | |
19 case kIDA_GrBlendCoeff: | |
20 return kISA_GrBlendCoeff; | |
21 case kSC_GrBlendCoeff: | |
22 return kDC_GrBlendCoeff; | |
23 case kISC_GrBlendCoeff: | |
24 return kIDC_GrBlendCoeff; | |
25 case kSA_GrBlendCoeff: | |
26 return kDA_GrBlendCoeff; | |
27 case kISA_GrBlendCoeff: | |
28 return kIDA_GrBlendCoeff; | |
29 default: | |
30 return coeff; | |
31 } | |
32 } | |
33 | |
34 static inline unsigned saturated_add(unsigned a, unsigned b) { | |
35 SkASSERT(a <= 255); | |
36 SkASSERT(b <= 255); | |
37 unsigned sum = a + b; | |
38 if (sum > 255) { | |
39 sum = 255; | |
40 } | |
41 return sum; | |
42 } | |
43 | |
44 static GrColor add_colors(GrColor src, GrColor dst) { | |
45 unsigned r = saturated_add(GrColorUnpackR(src), GrColorUnpackR(dst)); | |
46 unsigned g = saturated_add(GrColorUnpackG(src), GrColorUnpackG(dst)); | |
47 unsigned b = saturated_add(GrColorUnpackB(src), GrColorUnpackB(dst)); | |
48 unsigned a = saturated_add(GrColorUnpackA(src), GrColorUnpackA(dst)); | |
49 return GrColorPackRGBA(r, g, b, a); | |
50 } | |
51 | |
52 static inline bool valid_color(uint32_t compFlags) { | |
53 return (kRGBA_GrColorComponentFlags & compFlags) == kRGBA_GrColorComponentF
lags; | |
54 } | |
55 | |
56 static GrColor simplify_blend_term(GrBlendCoeff* srcCoeff, | |
57 GrColor srcColor, uint32_t srcCompFlags, | |
58 GrColor dstColor, uint32_t dstCompFlags, | |
59 GrColor constantColor) { | |
60 | |
61 SkASSERT(!GrBlendCoeffRefsSrc(*srcCoeff)); | |
62 SkASSERT(srcCoeff); | |
63 | |
64 // Check whether srcCoeff can be reduced to kOne or kZero based on known col
or inputs. | |
65 // We could pick out the coeff r,g,b,a values here and use them to compute t
he blend term color, | |
66 // if possible, below but that is not implemented now. | |
67 switch (*srcCoeff) { | |
68 case kIDC_GrBlendCoeff: | |
69 dstColor = ~dstColor; // fallthrough | |
70 case kDC_GrBlendCoeff: | |
71 if (valid_color(dstCompFlags)) { | |
72 if (0xffffffff == dstColor) { | |
73 *srcCoeff = kOne_GrBlendCoeff; | |
74 } else if (0 == dstColor) { | |
75 *srcCoeff = kZero_GrBlendCoeff; | |
76 } | |
77 } | |
78 break; | |
79 | |
80 case kIDA_GrBlendCoeff: | |
81 dstColor = ~dstColor; // fallthrough | |
82 case kDA_GrBlendCoeff: | |
83 if (kA_GrColorComponentFlag & dstCompFlags) { | |
84 if (0xff == GrColorUnpackA(dstColor)) { | |
85 *srcCoeff = kOne_GrBlendCoeff; | |
86 } else if (0 == GrColorUnpackA(dstColor)) { | |
87 *srcCoeff = kZero_GrBlendCoeff; | |
88 } | |
89 } | |
90 break; | |
91 | |
92 case kIConstC_GrBlendCoeff: | |
93 constantColor = ~constantColor; // fallthrough | |
94 case kConstC_GrBlendCoeff: | |
95 if (0xffffffff == constantColor) { | |
96 *srcCoeff = kOne_GrBlendCoeff; | |
97 } else if (0 == constantColor) { | |
98 *srcCoeff = kZero_GrBlendCoeff; | |
99 } | |
100 break; | |
101 | |
102 case kIConstA_GrBlendCoeff: | |
103 constantColor = ~constantColor; // fallthrough | |
104 case kConstA_GrBlendCoeff: | |
105 if (0xff == GrColorUnpackA(constantColor)) { | |
106 *srcCoeff = kOne_GrBlendCoeff; | |
107 } else if (0 == GrColorUnpackA(constantColor)) { | |
108 *srcCoeff = kZero_GrBlendCoeff; | |
109 } | |
110 break; | |
111 | |
112 default: | |
113 break; | |
114 } | |
115 // We may have invalidated these above and shouldn't read them again. | |
116 SkDEBUGCODE(dstColor = constantColor = GrColor_ILLEGAL;) | |
117 | |
118 if (kZero_GrBlendCoeff == *srcCoeff || (valid_color(srcCompFlags) && 0 == sr
cColor)) { | |
119 *srcCoeff = kZero_GrBlendCoeff; | |
120 return 0; | |
121 } | |
122 | |
123 if (kOne_GrBlendCoeff == *srcCoeff && valid_color(srcCompFlags)) { | |
124 return srcColor; | |
125 } else { | |
126 return GrColor_ILLEGAL; | |
127 } | |
128 } | |
129 | |
130 GrColor GrSimplifyBlend(GrBlendCoeff* srcCoeff, | |
131 GrBlendCoeff* dstCoeff, | |
132 GrColor srcColor, uint32_t srcCompFlags, | |
133 GrColor dstColor, uint32_t dstCompFlags, | |
134 GrColor constantColor) { | |
135 GrColor srcTermColor = simplify_blend_term(srcCoeff, | |
136 srcColor, srcCompFlags, | |
137 dstColor, dstCompFlags, | |
138 constantColor); | |
139 | |
140 // We call the same function to simplify the dst blend coeff. We trick it ou
t by swapping the | |
141 // src and dst. | |
142 GrBlendCoeff spoofedCoeff = swap_coeff_src_dst(*dstCoeff); | |
143 GrColor dstTermColor = simplify_blend_term(&spoofedCoeff, | |
144 dstColor, dstCompFlags, | |
145 srcColor, srcCompFlags, | |
146 constantColor); | |
147 *dstCoeff = swap_coeff_src_dst(spoofedCoeff); | |
148 | |
149 if (GrColor_ILLEGAL != srcTermColor && GrColor_ILLEGAL != dstTermColor) { | |
150 return add_colors(srcTermColor, dstTermColor); | |
151 } else { | |
152 return GrColor_ILLEGAL; | |
153 } | |
154 } | |
OLD | NEW |