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 "GrContext.h" | 15 #include "GrContext.h" |
16 #include "GrCoordTransform.h" | 16 #include "GrCoordTransform.h" |
17 #include "gl/GrGLEffect.h" | 17 #include "gl/GrGLEffect.h" |
18 #include "GrTBackendEffectFactory.h" | 18 #include "GrTBackendEffectFactory.h" |
19 #endif | 19 #endif |
20 | 20 |
21 static const bool gUseUnpremul = false; | 21 static const bool gUseUnpremul = false; |
22 | 22 |
23 class SkArithmeticMode_scalar : public SkXfermode { | 23 class SkArithmeticMode_scalar : public SkXfermode { |
24 public: | 24 public: |
25 static SkArithmeticMode_scalar* Create(SkScalar k1, SkScalar k2, SkScalar k3 , SkScalar k4) { | 25 static SkArithmeticMode_scalar* Create(SkScalar k1, SkScalar k2, SkScalar k3 , SkScalar k4, |
26 return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4)); | 26 bool validatePMColor) { |
27 return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4, validatePMCo lor)); | |
27 } | 28 } |
28 | 29 |
29 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, | 30 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, |
30 const SkAlpha aa[]) const SK_OVERRIDE; | 31 const SkAlpha aa[]) const SK_OVERRIDE; |
31 | 32 |
32 SK_TO_STRING_OVERRIDE() | 33 SK_TO_STRING_OVERRIDE() |
33 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) | 34 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) |
34 | 35 |
35 #if SK_SUPPORT_GPU | 36 #if SK_SUPPORT_GPU |
36 virtual bool asNewEffect(GrEffectRef** effect, GrTexture* background) const SK_OVERRIDE; | 37 virtual bool asNewEffect(GrEffectRef** effect, GrTexture* background) const SK_OVERRIDE; |
37 #endif | 38 #endif |
38 | 39 |
39 private: | 40 private: |
40 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) { | 41 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4, bool validatePMColor) { |
41 fK[0] = k1; | 42 fK[0] = k1; |
42 fK[1] = k2; | 43 fK[1] = k2; |
43 fK[2] = k3; | 44 fK[2] = k3; |
44 fK[3] = k4; | 45 fK[3] = k4; |
46 fValidatePMColor = validatePMColor; | |
45 } | 47 } |
46 | 48 |
47 SkArithmeticMode_scalar(SkReadBuffer& buffer) : INHERITED(buffer) { | 49 SkArithmeticMode_scalar(SkReadBuffer& buffer) : INHERITED(buffer) { |
48 fK[0] = buffer.readScalar(); | 50 fK[0] = buffer.readScalar(); |
49 fK[1] = buffer.readScalar(); | 51 fK[1] = buffer.readScalar(); |
50 fK[2] = buffer.readScalar(); | 52 fK[2] = buffer.readScalar(); |
51 fK[3] = buffer.readScalar(); | 53 fK[3] = buffer.readScalar(); |
54 fValidatePMColor = buffer.readBool(); | |
52 } | 55 } |
53 | 56 |
54 virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE { | 57 virtual void flatten(SkWriteBuffer& buffer) const SK_OVERRIDE { |
55 INHERITED::flatten(buffer); | 58 INHERITED::flatten(buffer); |
56 buffer.writeScalar(fK[0]); | 59 buffer.writeScalar(fK[0]); |
57 buffer.writeScalar(fK[1]); | 60 buffer.writeScalar(fK[1]); |
58 buffer.writeScalar(fK[2]); | 61 buffer.writeScalar(fK[2]); |
59 buffer.writeScalar(fK[3]); | 62 buffer.writeScalar(fK[3]); |
63 buffer.writeBool(fValidatePMColor); | |
60 } | 64 } |
61 SkScalar fK[4]; | 65 SkScalar fK[4]; |
66 bool fValidatePMColor; | |
62 | 67 |
63 typedef SkXfermode INHERITED; | 68 typedef SkXfermode INHERITED; |
64 }; | 69 }; |
65 | 70 |
66 static int pinToByte(int value) { | 71 static int pinToByte(int value) { |
67 if (value < 0) { | 72 if (value < 0) { |
68 value = 0; | 73 value = 0; |
69 } else if (value > 255) { | 74 } else if (value > 255) { |
70 value = 255; | 75 value = 255; |
71 } | 76 } |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
138 } | 143 } |
139 | 144 |
140 a = arith(k1, k2, k3, k4, sa, da); | 145 a = arith(k1, k2, k3, k4, sa, da); |
141 r = arith(k1, k2, k3, k4, sr, dr); | 146 r = arith(k1, k2, k3, k4, sr, dr); |
142 g = arith(k1, k2, k3, k4, sg, dg); | 147 g = arith(k1, k2, k3, k4, sg, dg); |
143 b = arith(k1, k2, k3, k4, sb, db); | 148 b = arith(k1, k2, k3, k4, sb, db); |
144 } | 149 } |
145 } else { | 150 } else { |
146 a = arith(k1, k2, k3, k4, SkGetPackedA32(sc), SkGetPackedA32(dc) ); | 151 a = arith(k1, k2, k3, k4, SkGetPackedA32(sc), SkGetPackedA32(dc) ); |
147 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc) ); | 152 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc) ); |
148 r = SkMin32(r, a); | |
149 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc) ); | 153 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc) ); |
150 g = SkMin32(g, a); | |
151 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc) ); | 154 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc) ); |
152 b = SkMin32(b, a); | 155 if (fValidatePMColor) { |
156 r = SkMin32(r, a); | |
157 g = SkMin32(g, a); | |
158 b = SkMin32(b, a); | |
159 } | |
153 } | 160 } |
154 | 161 |
155 // apply antialias coverage if necessary | 162 // apply antialias coverage if necessary |
156 if (aaCoverage && 0xFF != aaCoverage[i]) { | 163 if (aaCoverage && 0xFF != aaCoverage[i]) { |
157 int scale = aaCoverage[i] + (aaCoverage[i] >> 7); | 164 int scale = aaCoverage[i] + (aaCoverage[i] >> 7); |
158 a = blend(a, SkGetPackedA32(sc), scale); | 165 a = blend(a, SkGetPackedA32(sc), scale); |
159 r = blend(r, SkGetPackedR32(sc), scale); | 166 r = blend(r, SkGetPackedR32(sc), scale); |
160 g = blend(g, SkGetPackedG32(sc), scale); | 167 g = blend(g, SkGetPackedG32(sc), scale); |
161 b = blend(b, SkGetPackedB32(sc), scale); | 168 b = blend(b, SkGetPackedB32(sc), scale); |
162 } | 169 } |
163 | 170 |
164 // turn the result back into premul | 171 // turn the result back into premul |
165 if (gUseUnpremul && (0xFF != a)) { | 172 if (gUseUnpremul && (0xFF != a)) { |
166 int scale = a + (a >> 7); | 173 int scale = a + (a >> 7); |
167 r = SkAlphaMul(r, scale); | 174 r = SkAlphaMul(r, scale); |
168 g = SkAlphaMul(g, scale); | 175 g = SkAlphaMul(g, scale); |
169 b = SkAlphaMul(b, scale); | 176 b = SkAlphaMul(b, scale); |
170 } | 177 } |
171 dst[i] = SkPackARGB32(a, r, g, b); | 178 dst[i] = SkPackARGB32NoCheck(a, r, g, b); |
sugoi1
2014/03/27 19:07:36
Is this ok or should I still call SkPackARGB32() w
Stephen White
2014/03/27 19:38:16
Hmm, that's a good point. I guess just to make sur
sugoi1
2014/04/01 13:42:10
Done.
| |
172 } | 179 } |
173 } | 180 } |
174 } | 181 } |
175 | 182 |
176 #ifndef SK_IGNORE_TO_STRING | 183 #ifndef SK_IGNORE_TO_STRING |
177 void SkArithmeticMode_scalar::toString(SkString* str) const { | 184 void SkArithmeticMode_scalar::toString(SkString* str) const { |
178 str->append("SkArithmeticMode_scalar: "); | 185 str->append("SkArithmeticMode_scalar: "); |
179 for (int i = 0; i < 4; ++i) { | 186 for (int i = 0; i < 4; ++i) { |
180 str->appendScalar(fK[i]); | 187 str->appendScalar(fK[i]); |
181 if (i < 3) { | 188 str->append(" "); |
182 str->append(" "); | |
183 } | |
184 } | 189 } |
190 str->appendS32(fValidatePMColor ? 1 : 0); | |
185 } | 191 } |
186 #endif | 192 #endif |
187 | 193 |
188 /////////////////////////////////////////////////////////////////////////////// | 194 /////////////////////////////////////////////////////////////////////////////// |
189 | 195 |
190 static bool fitsInBits(SkScalar x, int bits) { | 196 static bool fitsInBits(SkScalar x, int bits) { |
191 return SkScalarAbs(x) < (1 << (bits - 1)); | 197 return SkScalarAbs(x) < (1 << (bits - 1)); |
192 } | 198 } |
193 | 199 |
194 #if 0 // UNUSED | 200 #if 0 // UNUSED |
195 static int32_t toDot8(SkScalar x) { | 201 static int32_t toDot8(SkScalar x) { |
196 return (int32_t)(x * 256); | 202 return (int32_t)(x * 256); |
197 } | 203 } |
198 #endif | 204 #endif |
199 | 205 |
200 SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, | 206 SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, |
201 SkScalar k3, SkScalar k4) { | 207 SkScalar k3, SkScalar k4, |
208 bool validatePMColor) { | |
202 if (fitsInBits(k1, 8) && fitsInBits(k2, 16) && | 209 if (fitsInBits(k1, 8) && fitsInBits(k2, 16) && |
203 fitsInBits(k2, 16) && fitsInBits(k2, 24)) { | 210 fitsInBits(k2, 16) && fitsInBits(k2, 24)) { |
204 | 211 |
205 #if 0 // UNUSED | 212 #if 0 // UNUSED |
206 int32_t i1 = toDot8(k1); | 213 int32_t i1 = toDot8(k1); |
207 int32_t i2 = toDot8(k2); | 214 int32_t i2 = toDot8(k2); |
208 int32_t i3 = toDot8(k3); | 215 int32_t i3 = toDot8(k3); |
209 int32_t i4 = toDot8(k4); | 216 int32_t i4 = toDot8(k4); |
210 if (i1) { | 217 if (i1) { |
211 return SkNEW_ARGS(SkArithmeticMode_quad, (i1, i2, i3, i4)); | 218 return SkNEW_ARGS(SkArithmeticMode_quad, (i1, i2, i3, i4)); |
212 } | 219 } |
213 if (0 == i2) { | 220 if (0 == i2) { |
214 return SkNEW_ARGS(SkArithmeticMode_dst, (i3, i4)); | 221 return SkNEW_ARGS(SkArithmeticMode_dst, (i3, i4)); |
215 } | 222 } |
216 if (0 == i3) { | 223 if (0 == i3) { |
217 return SkNEW_ARGS(SkArithmeticMode_src, (i2, i4)); | 224 return SkNEW_ARGS(SkArithmeticMode_src, (i2, i4)); |
218 } | 225 } |
219 return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4)); | 226 return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4)); |
220 #endif | 227 #endif |
221 } | 228 } |
222 return SkArithmeticMode_scalar::Create(k1, k2, k3, k4); | 229 return SkArithmeticMode_scalar::Create(k1, k2, k3, k4, validatePMColor); |
223 } | 230 } |
224 | 231 |
225 | 232 |
226 ////////////////////////////////////////////////////////////////////////////// | 233 ////////////////////////////////////////////////////////////////////////////// |
227 | 234 |
228 #if SK_SUPPORT_GPU | 235 #if SK_SUPPORT_GPU |
229 | 236 |
230 class GrGLArithmeticEffect : public GrGLEffect { | 237 class GrGLArithmeticEffect : public GrGLEffect { |
231 public: | 238 public: |
232 GrGLArithmeticEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 239 GrGLArithmeticEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
233 virtual ~GrGLArithmeticEffect(); | 240 virtual ~GrGLArithmeticEffect(); |
234 | 241 |
235 virtual void emitCode(GrGLShaderBuilder*, | 242 virtual void emitCode(GrGLShaderBuilder*, |
236 const GrDrawEffect&, | 243 const GrDrawEffect&, |
237 EffectKey, | 244 EffectKey, |
238 const char* outputColor, | 245 const char* outputColor, |
239 const char* inputColor, | 246 const char* inputColor, |
240 const TransformedCoordsArray&, | 247 const TransformedCoordsArray&, |
241 const TextureSamplerArray&) SK_OVERRIDE; | 248 const TextureSamplerArray&) SK_OVERRIDE; |
242 | 249 |
243 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; | 250 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; |
244 | 251 |
245 private: | 252 private: |
246 GrGLUniformManager::UniformHandle fKUni; | 253 GrGLUniformManager::UniformHandle fKUni; |
254 bool fValidatePMColor; | |
247 | 255 |
248 typedef GrGLEffect INHERITED; | 256 typedef GrGLEffect INHERITED; |
249 }; | 257 }; |
250 | 258 |
251 /////////////////////////////////////////////////////////////////////////////// | 259 /////////////////////////////////////////////////////////////////////////////// |
252 | 260 |
253 class GrArithmeticEffect : public GrEffect { | 261 class GrArithmeticEffect : public GrEffect { |
254 public: | 262 public: |
255 static GrEffectRef* Create(float k1, float k2, float k3, float k4, GrTexture * background) { | 263 static GrEffectRef* Create(float k1, float k2, float k3, float k4, bool vali datePMColor, |
256 AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, b ackground))); | 264 GrTexture* background) { |
265 AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, v alidatePMColor, | |
266 background))); | |
257 return CreateEffectRef(effect); | 267 return CreateEffectRef(effect); |
258 } | 268 } |
259 | 269 |
260 virtual ~GrArithmeticEffect(); | 270 virtual ~GrArithmeticEffect(); |
261 | 271 |
262 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 272 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
263 | 273 |
264 typedef GrGLArithmeticEffect GLEffect; | 274 typedef GrGLArithmeticEffect GLEffect; |
265 static const char* Name() { return "Arithmetic"; } | 275 static const char* Name() { return "Arithmetic"; } |
266 GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture() ; } | 276 GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture() ; } |
267 | 277 |
268 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE; | 278 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE; |
269 | 279 |
270 float k1() const { return fK1; } | 280 float k1() const { return fK1; } |
271 float k2() const { return fK2; } | 281 float k2() const { return fK2; } |
272 float k3() const { return fK3; } | 282 float k3() const { return fK3; } |
273 float k4() const { return fK4; } | 283 float k4() const { return fK4; } |
284 bool validatePMColor() const { return fValidatePMColor; } | |
274 | 285 |
275 private: | 286 private: |
276 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 287 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
277 | 288 |
278 GrArithmeticEffect(float k1, float k2, float k3, float k4, GrTexture* backgr ound); | 289 GrArithmeticEffect(float k1, float k2, float k3, float k4, bool validatePMCo lor, |
290 GrTexture* background); | |
279 float fK1, fK2, fK3, fK4; | 291 float fK1, fK2, fK3, fK4; |
292 bool fValidatePMColor; | |
280 GrCoordTransform fBackgroundTransform; | 293 GrCoordTransform fBackgroundTransform; |
281 GrTextureAccess fBackgroundAccess; | 294 GrTextureAccess fBackgroundAccess; |
282 | 295 |
283 GR_DECLARE_EFFECT_TEST; | 296 GR_DECLARE_EFFECT_TEST; |
284 typedef GrEffect INHERITED; | 297 typedef GrEffect INHERITED; |
285 | 298 |
286 }; | 299 }; |
287 | 300 |
288 /////////////////////////////////////////////////////////////////////////////// | 301 /////////////////////////////////////////////////////////////////////////////// |
289 | 302 |
290 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4, | 303 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4, |
291 GrTexture* background) | 304 bool validatePMColor, GrTexture* backgrou nd) |
292 : fK1(k1), fK2(k2), fK3(k3), fK4(k4) { | 305 : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fValidatePMColor(validatePMColor) { |
293 if (background) { | 306 if (background) { |
294 fBackgroundTransform.reset(kLocal_GrCoordSet, background); | 307 fBackgroundTransform.reset(kLocal_GrCoordSet, background); |
295 this->addCoordTransform(&fBackgroundTransform); | 308 this->addCoordTransform(&fBackgroundTransform); |
296 fBackgroundAccess.reset(background); | 309 fBackgroundAccess.reset(background); |
297 this->addTextureAccess(&fBackgroundAccess); | 310 this->addTextureAccess(&fBackgroundAccess); |
298 } else { | 311 } else { |
299 this->setWillReadDstColor(); | 312 this->setWillReadDstColor(); |
300 } | 313 } |
301 } | 314 } |
302 | 315 |
303 GrArithmeticEffect::~GrArithmeticEffect() { | 316 GrArithmeticEffect::~GrArithmeticEffect() { |
304 } | 317 } |
305 | 318 |
306 bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const { | 319 bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const { |
307 const GrArithmeticEffect& s = CastEffect<GrArithmeticEffect>(sBase); | 320 const GrArithmeticEffect& s = CastEffect<GrArithmeticEffect>(sBase); |
308 return fK1 == s.fK1 && | 321 return fK1 == s.fK1 && |
309 fK2 == s.fK2 && | 322 fK2 == s.fK2 && |
310 fK3 == s.fK3 && | 323 fK3 == s.fK3 && |
311 fK4 == s.fK4 && | 324 fK4 == s.fK4 && |
325 fValidatePMColor == s.fValidatePMColor && | |
312 backgroundTexture() == s.backgroundTexture(); | 326 backgroundTexture() == s.backgroundTexture(); |
313 } | 327 } |
314 | 328 |
315 const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const { | 329 const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const { |
316 return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance(); | 330 return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance(); |
317 } | 331 } |
318 | 332 |
319 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const { | 333 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const { |
320 // TODO: optimize this | 334 // TODO: optimize this |
321 *validFlags = 0; | 335 *validFlags = 0; |
322 } | 336 } |
323 | 337 |
324 /////////////////////////////////////////////////////////////////////////////// | 338 /////////////////////////////////////////////////////////////////////////////// |
325 | 339 |
326 GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendEffectFactory& factory , | 340 GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendEffectFactory& factory , |
327 const GrDrawEffect& drawEffect) | 341 const GrDrawEffect& drawEffect) |
328 : INHERITED(factory) { | 342 : INHERITED(factory), |
343 fValidatePMColor(true) { | |
329 } | 344 } |
330 | 345 |
331 GrGLArithmeticEffect::~GrGLArithmeticEffect() { | 346 GrGLArithmeticEffect::~GrGLArithmeticEffect() { |
332 } | 347 } |
333 | 348 |
334 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder, | 349 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder, |
335 const GrDrawEffect& drawEffect, | 350 const GrDrawEffect& drawEffect, |
336 EffectKey key, | 351 EffectKey key, |
337 const char* outputColor, | 352 const char* outputColor, |
338 const char* inputColor, | 353 const char* inputColor, |
(...skipping 28 matching lines...) Expand all Loading... | |
367 | 382 |
368 builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor); | 383 builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor); |
369 if (gUseUnpremul) { | 384 if (gUseUnpremul) { |
370 builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\ n"); | 385 builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\ n"); |
371 } | 386 } |
372 | 387 |
373 builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni); | 388 builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni); |
374 builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu tColor); | 389 builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu tColor); |
375 if (gUseUnpremul) { | 390 if (gUseUnpremul) { |
376 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor ); | 391 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor ); |
377 } else { | 392 } else if (fValidatePMColor) { |
378 builder->fsCodeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor); | 393 builder->fsCodeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor); |
379 } | 394 } |
380 } | 395 } |
381 | 396 |
382 void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) { | 397 void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) { |
383 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>( ); | 398 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>( ); |
384 uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); | 399 uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); |
400 fValidatePMColor = arith.validatePMColor(); | |
385 } | 401 } |
386 | 402 |
387 GrEffectRef* GrArithmeticEffect::TestCreate(SkRandom* rand, | 403 GrEffectRef* GrArithmeticEffect::TestCreate(SkRandom* rand, |
388 GrContext*, | 404 GrContext*, |
389 const GrDrawTargetCaps&, | 405 const GrDrawTargetCaps&, |
390 GrTexture*[]) { | 406 GrTexture*[]) { |
391 float k1 = rand->nextF(); | 407 float k1 = rand->nextF(); |
392 float k2 = rand->nextF(); | 408 float k2 = rand->nextF(); |
393 float k3 = rand->nextF(); | 409 float k3 = rand->nextF(); |
394 float k4 = rand->nextF(); | 410 float k4 = rand->nextF(); |
411 bool validatePMColor = rand->nextBool(); | |
395 | 412 |
396 AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, NULL ))); | 413 AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, |
414 (k1, k2, k3, k4, validatePMColor, NULL))) ; | |
397 return CreateEffectRef(gEffect); | 415 return CreateEffectRef(gEffect); |
398 } | 416 } |
399 | 417 |
400 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect); | 418 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect); |
401 | 419 |
402 bool SkArithmeticMode_scalar::asNewEffect(GrEffectRef** effect, GrTexture* backg round) const { | 420 bool SkArithmeticMode_scalar::asNewEffect(GrEffectRef** effect, GrTexture* backg round) const { |
403 if (effect) { | 421 if (effect) { |
404 *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]), | 422 *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]), |
405 SkScalarToFloat(fK[1]), | 423 SkScalarToFloat(fK[1]), |
406 SkScalarToFloat(fK[2]), | 424 SkScalarToFloat(fK[2]), |
407 SkScalarToFloat(fK[3]), | 425 SkScalarToFloat(fK[3]), |
426 fValidatePMColor, | |
408 background); | 427 background); |
409 } | 428 } |
410 return true; | 429 return true; |
411 } | 430 } |
412 | 431 |
413 #endif | 432 #endif |
414 | 433 |
415 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) | 434 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) |
416 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) | 435 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) |
417 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 436 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |