OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkArithmeticMode.h" | 8 #include "SkArithmeticMode.h" |
9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
10 #include "SkReadBuffer.h" | 10 #include "SkReadBuffer.h" |
11 #include "SkWriteBuffer.h" | 11 #include "SkWriteBuffer.h" |
12 #include "SkString.h" | 12 #include "SkString.h" |
13 #include "SkUnPreMultiply.h" | 13 #include "SkUnPreMultiply.h" |
14 #if SK_SUPPORT_GPU | 14 #if SK_SUPPORT_GPU |
15 #include "SkArithmeticMode_gpu.h" | 15 #include "SkArithmeticMode_gpu.h" |
16 #endif | 16 #endif |
17 | 17 |
18 static const bool gUseUnpremul = false; | |
19 | |
20 class SkArithmeticMode_scalar : public SkXfermode { | 18 class SkArithmeticMode_scalar : public SkXfermode { |
21 public: | 19 public: |
22 static SkXfermode* Create(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4
, | 20 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, |
23 bool enforcePMColor) { | 21 bool enforcePMColor) { |
24 if (SkScalarNearlyZero(k1) && SkScalarNearlyEqual(k2, SK_Scalar1) && | 22 fK[0] = k1; |
25 SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) { | 23 fK[1] = k2; |
26 return SkXfermode::Create(SkXfermode::kSrc_Mode); | 24 fK[2] = k3; |
27 } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) && | 25 fK[3] = k4; |
28 SkScalarNearlyEqual(k3, SK_Scalar1) && SkScalarNearlyZero(k4)
) { | 26 fEnforcePMColor = enforcePMColor; |
29 return SkXfermode::Create(SkXfermode::kDst_Mode); | |
30 } | |
31 | |
32 return new SkArithmeticMode_scalar(k1, k2, k3, k4, enforcePMColor); | |
33 } | 27 } |
34 | 28 |
35 void xfer32(SkPMColor dst[], const SkPMColor src[], int count, | 29 void xfer32(SkPMColor[], const SkPMColor[], int count, const SkAlpha[]) cons
t override; |
36 const SkAlpha aa[]) const override; | |
37 | 30 |
38 SK_TO_STRING_OVERRIDE() | 31 SK_TO_STRING_OVERRIDE() |
39 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) | 32 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) |
40 | 33 |
41 #if SK_SUPPORT_GPU | 34 #if SK_SUPPORT_GPU |
42 const GrFragmentProcessor* getFragmentProcessorForImageFilter( | 35 const GrFragmentProcessor* getFragmentProcessorForImageFilter( |
43 const GrFragmentProcessor* dst)
const override; | 36 const GrFragmentProcessor* dst)
const override; |
44 GrXPFactory* asXPFactory() const override; | 37 GrXPFactory* asXPFactory() const override; |
45 #endif | 38 #endif |
46 | 39 |
47 private: | 40 private: |
48 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
bool enforcePMColor) { | |
49 fK[0] = k1; | |
50 fK[1] = k2; | |
51 fK[2] = k3; | |
52 fK[3] = k4; | |
53 fEnforcePMColor = enforcePMColor; | |
54 } | |
55 | |
56 void flatten(SkWriteBuffer& buffer) const override { | 41 void flatten(SkWriteBuffer& buffer) const override { |
57 buffer.writeScalar(fK[0]); | 42 buffer.writeScalar(fK[0]); |
58 buffer.writeScalar(fK[1]); | 43 buffer.writeScalar(fK[1]); |
59 buffer.writeScalar(fK[2]); | 44 buffer.writeScalar(fK[2]); |
60 buffer.writeScalar(fK[3]); | 45 buffer.writeScalar(fK[3]); |
61 buffer.writeBool(fEnforcePMColor); | 46 buffer.writeBool(fEnforcePMColor); |
62 } | 47 } |
63 | 48 |
64 SkScalar fK[4]; | 49 SkScalar fK[4]; |
65 bool fEnforcePMColor; | 50 bool fEnforcePMColor; |
66 | 51 |
67 friend class SkArithmeticMode; | 52 friend class SkArithmeticMode; |
68 | 53 |
69 typedef SkXfermode INHERITED; | 54 typedef SkXfermode INHERITED; |
70 }; | 55 }; |
71 | 56 |
72 SkFlattenable* SkArithmeticMode_scalar::CreateProc(SkReadBuffer& buffer) { | 57 SkFlattenable* SkArithmeticMode_scalar::CreateProc(SkReadBuffer& buffer) { |
73 const SkScalar k1 = buffer.readScalar(); | 58 const SkScalar k1 = buffer.readScalar(); |
74 const SkScalar k2 = buffer.readScalar(); | 59 const SkScalar k2 = buffer.readScalar(); |
75 const SkScalar k3 = buffer.readScalar(); | 60 const SkScalar k3 = buffer.readScalar(); |
76 const SkScalar k4 = buffer.readScalar(); | 61 const SkScalar k4 = buffer.readScalar(); |
77 const bool enforcePMColor = buffer.readBool(); | 62 const bool enforcePMColor = buffer.readBool(); |
78 return Create(k1, k2, k3, k4, enforcePMColor); | 63 return SkArithmeticMode::Create(k1, k2, k3, k4, enforcePMColor); |
79 } | 64 } |
80 | 65 |
81 static int pinToByte(int value) { | 66 static int pinToByte(int value) { |
82 if (value < 0) { | 67 if (value < 0) { |
83 value = 0; | 68 value = 0; |
84 } else if (value > 255) { | 69 } else if (value > 255) { |
85 value = 255; | 70 value = 255; |
86 } | 71 } |
87 return value; | 72 return value; |
88 } | 73 } |
89 | 74 |
90 static int arith(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, | 75 static int arith(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, |
91 int src, int dst) { | 76 int src, int dst) { |
92 SkScalar result = SkScalarMul(k1, src * dst) + | 77 SkScalar result = SkScalarMul(k1, src * dst) + |
93 SkScalarMul(k2, src) + | 78 SkScalarMul(k2, src) + |
94 SkScalarMul(k3, dst) + | 79 SkScalarMul(k3, dst) + |
95 k4; | 80 k4; |
96 int res = SkScalarRoundToInt(result); | 81 int res = SkScalarRoundToInt(result); |
97 return pinToByte(res); | 82 return pinToByte(res); |
98 } | 83 } |
99 | 84 |
100 static int blend(int src, int dst, int scale) { | 85 static int blend(int src, int dst, int scale) { |
101 return dst + ((src - dst) * scale >> 8); | 86 return dst + ((src - dst) * scale >> 8); |
102 } | 87 } |
103 | 88 |
104 static bool needsUnpremul(int alpha) { | |
105 return 0 != alpha && 0xFF != alpha; | |
106 } | |
107 | |
108 void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[], | 89 void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[], |
109 int count, const SkAlpha aaCoverage[]) const { | 90 int count, const SkAlpha aaCoverage[]) const { |
110 SkScalar k1 = fK[0] / 255; | 91 SkScalar k1 = fK[0] / 255; |
111 SkScalar k2 = fK[1]; | 92 SkScalar k2 = fK[1]; |
112 SkScalar k3 = fK[2]; | 93 SkScalar k3 = fK[2]; |
113 SkScalar k4 = fK[3] * 255; | 94 SkScalar k4 = fK[3] * 255; |
114 | 95 |
115 for (int i = 0; i < count; ++i) { | 96 for (int i = 0; i < count; ++i) { |
116 if ((nullptr == aaCoverage) || aaCoverage[i]) { | 97 if ((nullptr == aaCoverage) || aaCoverage[i]) { |
117 SkPMColor sc = src[i]; | 98 SkPMColor sc = src[i]; |
118 SkPMColor dc = dst[i]; | 99 SkPMColor dc = dst[i]; |
119 | 100 |
120 int a, r, g, b; | 101 int a, r, g, b; |
121 | 102 |
122 if (gUseUnpremul) { | 103 a = arith(k1, k2, k3, k4, SkGetPackedA32(sc), SkGetPackedA32(dc)); |
123 int sa = SkGetPackedA32(sc); | 104 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc)); |
124 int da = SkGetPackedA32(dc); | 105 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc)); |
125 | 106 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc)); |
126 int srcNeedsUnpremul = needsUnpremul(sa); | 107 if (fEnforcePMColor) { |
127 int dstNeedsUnpremul = needsUnpremul(da); | 108 r = SkMin32(r, a); |
128 | 109 g = SkMin32(g, a); |
129 if (!srcNeedsUnpremul && !dstNeedsUnpremul) { | 110 b = SkMin32(b, a); |
130 a = arith(k1, k2, k3, k4, sa, da); | |
131 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32
(dc)); | |
132 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32
(dc)); | |
133 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32
(dc)); | |
134 } else { | |
135 int sr = SkGetPackedR32(sc); | |
136 int sg = SkGetPackedG32(sc); | |
137 int sb = SkGetPackedB32(sc); | |
138 if (srcNeedsUnpremul) { | |
139 SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale
(sa); | |
140 sr = SkUnPreMultiply::ApplyScale(scale, sr); | |
141 sg = SkUnPreMultiply::ApplyScale(scale, sg); | |
142 sb = SkUnPreMultiply::ApplyScale(scale, sb); | |
143 } | |
144 | |
145 int dr = SkGetPackedR32(dc); | |
146 int dg = SkGetPackedG32(dc); | |
147 int db = SkGetPackedB32(dc); | |
148 if (dstNeedsUnpremul) { | |
149 SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale
(da); | |
150 dr = SkUnPreMultiply::ApplyScale(scale, dr); | |
151 dg = SkUnPreMultiply::ApplyScale(scale, dg); | |
152 db = SkUnPreMultiply::ApplyScale(scale, db); | |
153 } | |
154 | |
155 a = arith(k1, k2, k3, k4, sa, da); | |
156 r = arith(k1, k2, k3, k4, sr, dr); | |
157 g = arith(k1, k2, k3, k4, sg, dg); | |
158 b = arith(k1, k2, k3, k4, sb, db); | |
159 } | |
160 } else { | |
161 a = arith(k1, k2, k3, k4, SkGetPackedA32(sc), SkGetPackedA32(dc)
); | |
162 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc)
); | |
163 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc)
); | |
164 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc)
); | |
165 if (fEnforcePMColor) { | |
166 r = SkMin32(r, a); | |
167 g = SkMin32(g, a); | |
168 b = SkMin32(b, a); | |
169 } | |
170 } | 111 } |
171 | 112 |
172 // apply antialias coverage if necessary | 113 // apply antialias coverage if necessary |
173 if (aaCoverage && 0xFF != aaCoverage[i]) { | 114 if (aaCoverage && 0xFF != aaCoverage[i]) { |
174 int scale = aaCoverage[i] + (aaCoverage[i] >> 7); | 115 int scale = aaCoverage[i] + (aaCoverage[i] >> 7); |
175 a = blend(a, SkGetPackedA32(sc), scale); | 116 a = blend(a, SkGetPackedA32(sc), scale); |
176 r = blend(r, SkGetPackedR32(sc), scale); | 117 r = blend(r, SkGetPackedR32(sc), scale); |
177 g = blend(g, SkGetPackedG32(sc), scale); | 118 g = blend(g, SkGetPackedG32(sc), scale); |
178 b = blend(b, SkGetPackedB32(sc), scale); | 119 b = blend(b, SkGetPackedB32(sc), scale); |
179 } | 120 } |
180 | 121 |
181 // turn the result back into premul | |
182 if (gUseUnpremul && (0xFF != a)) { | |
183 int scale = a + (a >> 7); | |
184 r = SkAlphaMul(r, scale); | |
185 g = SkAlphaMul(g, scale); | |
186 b = SkAlphaMul(b, scale); | |
187 } | |
188 dst[i] = fEnforcePMColor ? SkPackARGB32(a, r, g, b) : SkPackARGB32No
Check(a, r, g, b); | 122 dst[i] = fEnforcePMColor ? SkPackARGB32(a, r, g, b) : SkPackARGB32No
Check(a, r, g, b); |
189 } | 123 } |
190 } | 124 } |
191 } | 125 } |
192 | 126 |
193 #ifndef SK_IGNORE_TO_STRING | 127 #ifndef SK_IGNORE_TO_STRING |
194 void SkArithmeticMode_scalar::toString(SkString* str) const { | 128 void SkArithmeticMode_scalar::toString(SkString* str) const { |
195 str->append("SkArithmeticMode_scalar: "); | 129 str->append("SkArithmeticMode_scalar: "); |
196 for (int i = 0; i < 4; ++i) { | 130 for (int i = 0; i < 4; ++i) { |
197 str->appendScalar(fK[i]); | 131 str->appendScalar(fK[i]); |
198 str->append(" "); | 132 str->append(" "); |
199 } | 133 } |
200 str->appendS32(fEnforcePMColor ? 1 : 0); | 134 str->appendS32(fEnforcePMColor ? 1 : 0); |
201 } | 135 } |
202 #endif | 136 #endif |
203 | 137 |
204 /////////////////////////////////////////////////////////////////////////////// | 138 /////////////////////////////////////////////////////////////////////////////// |
205 | 139 |
206 static bool fitsInBits(SkScalar x, int bits) { | |
207 return SkScalarAbs(x) < (1 << (bits - 1)); | |
208 } | |
209 | |
210 #if 0 // UNUSED | |
211 static int32_t toDot8(SkScalar x) { | |
212 return (int32_t)(x * 256); | |
213 } | |
214 #endif | |
215 | |
216 SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, | 140 SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, |
217 SkScalar k3, SkScalar k4, | 141 SkScalar k3, SkScalar k4, |
218 bool enforcePMColor) { | 142 bool enforcePMColor) { |
219 if (fitsInBits(k1, 8) && fitsInBits(k2, 16) && | 143 if (SkScalarNearlyZero(k1) && SkScalarNearlyEqual(k2, SK_Scalar1) && |
220 fitsInBits(k2, 16) && fitsInBits(k2, 24)) { | 144 SkScalarNearlyZero(k3) && SkScalarNearlyZero(k4)) { |
221 | 145 return SkXfermode::Create(SkXfermode::kSrc_Mode); |
222 #if 0 // UNUSED | 146 } else if (SkScalarNearlyZero(k1) && SkScalarNearlyZero(k2) && |
223 int32_t i1 = toDot8(k1); | 147 SkScalarNearlyEqual(k3, SK_Scalar1) && SkScalarNearlyZero(k4)) { |
224 int32_t i2 = toDot8(k2); | 148 return SkXfermode::Create(SkXfermode::kDst_Mode); |
225 int32_t i3 = toDot8(k3); | |
226 int32_t i4 = toDot8(k4); | |
227 if (i1) { | |
228 return new SkArithmeticMode_quad (i1, i2, i3, i4); | |
229 } | |
230 if (0 == i2) { | |
231 return new SkArithmeticMode_dst (i3, i4); | |
232 } | |
233 if (0 == i3) { | |
234 return new SkArithmeticMode_src (i2, i4); | |
235 } | |
236 return new SkArithmeticMode_linear (i2, i3, i4); | |
237 #endif | |
238 } | 149 } |
239 return SkArithmeticMode_scalar::Create(k1, k2, k3, k4, enforcePMColor); | 150 |
| 151 return new SkArithmeticMode_scalar(k1, k2, k3, k4, enforcePMColor); |
240 } | 152 } |
241 | 153 |
242 | 154 |
243 ////////////////////////////////////////////////////////////////////////////// | 155 ////////////////////////////////////////////////////////////////////////////// |
244 | 156 |
245 #if SK_SUPPORT_GPU | 157 #if SK_SUPPORT_GPU |
246 const GrFragmentProcessor* SkArithmeticMode_scalar::getFragmentProcessorForImage
Filter( | 158 const GrFragmentProcessor* SkArithmeticMode_scalar::getFragmentProcessorForImage
Filter( |
247 const GrFragmentProc
essor* dst) const { | 159 const GrFragmentProc
essor* dst) const { |
248 return GrArithmeticFP::Create(SkScalarToFloat(fK[0]), | 160 return GrArithmeticFP::Create(SkScalarToFloat(fK[0]), |
249 SkScalarToFloat(fK[1]), | 161 SkScalarToFloat(fK[1]), |
250 SkScalarToFloat(fK[2]), | 162 SkScalarToFloat(fK[2]), |
251 SkScalarToFloat(fK[3]), | 163 SkScalarToFloat(fK[3]), |
252 fEnforcePMColor, | 164 fEnforcePMColor, |
253 dst); | 165 dst); |
254 } | 166 } |
255 | 167 |
256 GrXPFactory* SkArithmeticMode_scalar::asXPFactory() const { | 168 GrXPFactory* SkArithmeticMode_scalar::asXPFactory() const { |
257 return GrArithmeticXPFactory::Create(SkScalarToFloat(fK[0]), | 169 return GrArithmeticXPFactory::Create(SkScalarToFloat(fK[0]), |
258 SkScalarToFloat(fK[1]), | 170 SkScalarToFloat(fK[1]), |
259 SkScalarToFloat(fK[2]), | 171 SkScalarToFloat(fK[2]), |
260 SkScalarToFloat(fK[3]), | 172 SkScalarToFloat(fK[3]), |
261 fEnforcePMColor); | 173 fEnforcePMColor); |
262 } | 174 } |
263 | 175 |
264 #endif | 176 #endif |
265 | 177 |
266 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) | 178 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) |
267 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) | 179 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) |
268 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 180 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |