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 "SkFlattenableBuffers.h" | 10 #include "SkFlattenableBuffers.h" |
11 #include "SkString.h" | 11 #include "SkString.h" |
12 #include "SkUnPreMultiply.h" | 12 #include "SkUnPreMultiply.h" |
13 #if SK_SUPPORT_GPU | 13 #if SK_SUPPORT_GPU |
14 #include "GrContext.h" | 14 #include "GrContext.h" |
15 #include "gl/GrGLEffect.h" | 15 #include "gl/GrGLEffect.h" |
16 #include "gl/GrGLEffectMatrix.h" | 16 #include "gl/GrGLEffectMatrix.h" |
17 #include "GrTBackendEffectFactory.h" | 17 #include "GrTBackendEffectFactory.h" |
18 #include "SkImageFilterUtils.h" | 18 #include "SkImageFilterUtils.h" |
19 #endif | 19 #endif |
20 | 20 |
21 class SkArithmeticMode_scalar : public SkXfermode { | 21 class SkArithmeticMode_scalar : public SkXfermode { |
22 public: | 22 public: |
23 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4)
{ | 23 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
bool unpremultiply) { |
24 fK[0] = k1; | 24 fK[0] = k1; |
25 fK[1] = k2; | 25 fK[1] = k2; |
26 fK[2] = k3; | 26 fK[2] = k3; |
27 fK[3] = k4; | 27 fK[3] = k4; |
| 28 fUnpremultiply = unpremultiply; |
28 } | 29 } |
29 | 30 |
30 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, | 31 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, |
31 const SkAlpha aa[]) const SK_OVERRIDE; | 32 const SkAlpha aa[]) const SK_OVERRIDE; |
32 | 33 |
33 SK_DEVELOPER_TO_STRING() | 34 SK_DEVELOPER_TO_STRING() |
34 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) | 35 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) |
35 | 36 |
36 #if SK_SUPPORT_GPU | 37 #if SK_SUPPORT_GPU |
37 virtual bool asNewEffectOrCoeff(GrContext*, GrEffectRef** effect, Coeff*, Co
eff*, GrTexture* background) const SK_OVERRIDE; | 38 virtual bool asNewEffectOrCoeff(GrContext*, GrEffectRef** effect, Coeff*, Co
eff*, GrTexture* background) const SK_OVERRIDE; |
38 #endif | 39 #endif |
39 | 40 |
40 private: | 41 private: |
41 SkArithmeticMode_scalar(SkFlattenableReadBuffer& buffer) : INHERITED(buffer)
{ | 42 SkArithmeticMode_scalar(SkFlattenableReadBuffer& buffer) : INHERITED(buffer)
{ |
42 fK[0] = buffer.readScalar(); | 43 fK[0] = buffer.readScalar(); |
43 fK[1] = buffer.readScalar(); | 44 fK[1] = buffer.readScalar(); |
44 fK[2] = buffer.readScalar(); | 45 fK[2] = buffer.readScalar(); |
45 fK[3] = buffer.readScalar(); | 46 fK[3] = buffer.readScalar(); |
| 47 fUnpremultiply = buffer.readBool(); |
46 } | 48 } |
47 | 49 |
48 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { | 50 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { |
49 INHERITED::flatten(buffer); | 51 INHERITED::flatten(buffer); |
50 buffer.writeScalar(fK[0]); | 52 buffer.writeScalar(fK[0]); |
51 buffer.writeScalar(fK[1]); | 53 buffer.writeScalar(fK[1]); |
52 buffer.writeScalar(fK[2]); | 54 buffer.writeScalar(fK[2]); |
53 buffer.writeScalar(fK[3]); | 55 buffer.writeScalar(fK[3]); |
| 56 buffer.writeBool(fUnpremultiply); |
54 } | 57 } |
55 SkScalar fK[4]; | 58 SkScalar fK[4]; |
| 59 bool fUnpremultiply; |
56 | 60 |
57 typedef SkXfermode INHERITED; | 61 typedef SkXfermode INHERITED; |
58 }; | 62 }; |
59 | 63 |
60 static int pinToByte(int value) { | 64 static int pinToByte(int value) { |
61 if (value < 0) { | 65 if (value < 0) { |
62 value = 0; | 66 value = 0; |
63 } else if (value > 255) { | 67 } else if (value > 255) { |
64 value = 255; | 68 value = 255; |
65 } | 69 } |
(...skipping 25 matching lines...) Expand all Loading... |
91 SkScalar k3 = fK[2]; | 95 SkScalar k3 = fK[2]; |
92 SkScalar k4 = fK[3] * 255; | 96 SkScalar k4 = fK[3] * 255; |
93 | 97 |
94 for (int i = 0; i < count; ++i) { | 98 for (int i = 0; i < count; ++i) { |
95 if ((NULL == aaCoverage) || aaCoverage[i]) { | 99 if ((NULL == aaCoverage) || aaCoverage[i]) { |
96 SkPMColor sc = src[i]; | 100 SkPMColor sc = src[i]; |
97 SkPMColor dc = dst[i]; | 101 SkPMColor dc = dst[i]; |
98 int sa = SkGetPackedA32(sc); | 102 int sa = SkGetPackedA32(sc); |
99 int da = SkGetPackedA32(dc); | 103 int da = SkGetPackedA32(dc); |
100 | 104 |
101 int srcNeedsUnpremul = needsUnpremul(sa); | 105 int srcNeedsUnpremul = fUnpremultiply && needsUnpremul(sa); |
102 int dstNeedsUnpremul = needsUnpremul(da); | 106 int dstNeedsUnpremul = fUnpremultiply && needsUnpremul(da); |
103 | 107 |
104 int a, r, g, b; | 108 int a, r, g, b; |
105 | 109 |
106 if (!srcNeedsUnpremul && !dstNeedsUnpremul) { | 110 if (!srcNeedsUnpremul && !dstNeedsUnpremul) { |
107 a = arith(k1, k2, k3, k4, sa, da); | 111 a = arith(k1, k2, k3, k4, sa, da); |
108 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc)
); | 112 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc)
); |
109 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc)
); | 113 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc)
); |
110 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc)
); | 114 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc)
); |
111 } else { | 115 } else { |
112 int sr = SkGetPackedR32(sc); | 116 int sr = SkGetPackedR32(sc); |
(...skipping 25 matching lines...) Expand all Loading... |
138 // apply antialias coverage if necessary | 142 // apply antialias coverage if necessary |
139 if (aaCoverage && 0xFF != aaCoverage[i]) { | 143 if (aaCoverage && 0xFF != aaCoverage[i]) { |
140 int scale = aaCoverage[i] + (aaCoverage[i] >> 7); | 144 int scale = aaCoverage[i] + (aaCoverage[i] >> 7); |
141 a = blend(a, SkGetPackedA32(sc), scale); | 145 a = blend(a, SkGetPackedA32(sc), scale); |
142 r = blend(r, SkGetPackedR32(sc), scale); | 146 r = blend(r, SkGetPackedR32(sc), scale); |
143 g = blend(g, SkGetPackedG32(sc), scale); | 147 g = blend(g, SkGetPackedG32(sc), scale); |
144 b = blend(b, SkGetPackedB32(sc), scale); | 148 b = blend(b, SkGetPackedB32(sc), scale); |
145 } | 149 } |
146 | 150 |
147 // turn the result back into premul | 151 // turn the result back into premul |
148 if (0xFF != a) { | 152 if (fUnpremultiply && 0xFF != a) { |
149 int scale = a + (a >> 7); | 153 int scale = a + (a >> 7); |
150 r = SkAlphaMul(r, scale); | 154 r = SkAlphaMul(r, scale); |
151 g = SkAlphaMul(g, scale); | 155 g = SkAlphaMul(g, scale); |
152 b = SkAlphaMul(b, scale); | 156 b = SkAlphaMul(b, scale); |
153 } | 157 } |
154 dst[i] = SkPackARGB32(a, r, g, b); | 158 dst[i] = SkPackARGB32(a, r, g, b); |
155 } | 159 } |
156 } | 160 } |
157 } | 161 } |
158 | 162 |
(...skipping 28 matching lines...) Expand all Loading... |
187 x += 1 << 7; | 191 x += 1 << 7; |
188 x >>= 8; | 192 x >>= 8; |
189 return x; | 193 return x; |
190 #else | 194 #else |
191 return (int32_t)(x * 256); | 195 return (int32_t)(x * 256); |
192 #endif | 196 #endif |
193 } | 197 } |
194 #endif | 198 #endif |
195 | 199 |
196 SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, | 200 SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, |
197 SkScalar k3, SkScalar k4) { | 201 SkScalar k3, SkScalar k4, bool unpremultipl
y) { |
198 if (fitsInBits(k1, 8) && fitsInBits(k2, 16) && | 202 if (fitsInBits(k1, 8) && fitsInBits(k2, 16) && |
199 fitsInBits(k2, 16) && fitsInBits(k2, 24)) { | 203 fitsInBits(k2, 16) && fitsInBits(k2, 24)) { |
200 | 204 |
201 #if 0 // UNUSED | 205 #if 0 // UNUSED |
202 int32_t i1 = toDot8(k1); | 206 int32_t i1 = toDot8(k1); |
203 int32_t i2 = toDot8(k2); | 207 int32_t i2 = toDot8(k2); |
204 int32_t i3 = toDot8(k3); | 208 int32_t i3 = toDot8(k3); |
205 int32_t i4 = toDot8(k4); | 209 int32_t i4 = toDot8(k4); |
206 if (i1) { | 210 if (i1) { |
207 return SkNEW_ARGS(SkArithmeticMode_quad, (i1, i2, i3, i4)); | 211 return SkNEW_ARGS(SkArithmeticMode_quad, (i1, i2, i3, i4)); |
208 } | 212 } |
209 if (0 == i2) { | 213 if (0 == i2) { |
210 return SkNEW_ARGS(SkArithmeticMode_dst, (i3, i4)); | 214 return SkNEW_ARGS(SkArithmeticMode_dst, (i3, i4)); |
211 } | 215 } |
212 if (0 == i3) { | 216 if (0 == i3) { |
213 return SkNEW_ARGS(SkArithmeticMode_src, (i2, i4)); | 217 return SkNEW_ARGS(SkArithmeticMode_src, (i2, i4)); |
214 } | 218 } |
215 return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4)); | 219 return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4)); |
216 #endif | 220 #endif |
217 } | 221 } |
218 return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4)); | 222 return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4, unpremultiply)); |
219 } | 223 } |
220 | 224 |
221 | 225 |
222 ////////////////////////////////////////////////////////////////////////////// | 226 ////////////////////////////////////////////////////////////////////////////// |
223 | 227 |
224 #if SK_SUPPORT_GPU | 228 #if SK_SUPPORT_GPU |
225 | 229 |
226 class GrGLArithmeticEffect : public GrGLEffect { | 230 class GrGLArithmeticEffect : public GrGLEffect { |
227 public: | 231 public: |
228 GrGLArithmeticEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 232 GrGLArithmeticEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
(...skipping 15 matching lines...) Expand all Loading... |
244 GrGLEffectMatrix fBackgroundEffectMatrix; | 248 GrGLEffectMatrix fBackgroundEffectMatrix; |
245 GrGLUniformManager::UniformHandle fKUni; | 249 GrGLUniformManager::UniformHandle fKUni; |
246 | 250 |
247 typedef GrGLEffect INHERITED; | 251 typedef GrGLEffect INHERITED; |
248 }; | 252 }; |
249 | 253 |
250 /////////////////////////////////////////////////////////////////////////////// | 254 /////////////////////////////////////////////////////////////////////////////// |
251 | 255 |
252 class GrArithmeticEffect : public GrEffect { | 256 class GrArithmeticEffect : public GrEffect { |
253 public: | 257 public: |
254 static GrEffectRef* Create(float k1, float k2, float k3, float k4, GrTexture
* background) { | 258 static GrEffectRef* Create(float k1, float k2, float k3, float k4, bool unpr
emultiply, GrTexture* background) { |
255 AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, b
ackground))); | 259 AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, u
npremultiply, background))); |
256 return CreateEffectRef(effect); | 260 return CreateEffectRef(effect); |
257 } | 261 } |
258 | 262 |
259 virtual ~GrArithmeticEffect(); | 263 virtual ~GrArithmeticEffect(); |
260 | 264 |
261 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 265 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
262 | 266 |
263 typedef GrGLArithmeticEffect GLEffect; | 267 typedef GrGLArithmeticEffect GLEffect; |
264 static const char* Name() { return "Arithmetic"; } | 268 static const char* Name() { return "Arithmetic"; } |
265 GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture()
; } | 269 GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture()
; } |
266 | 270 |
267 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 271 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
268 | 272 |
269 float k1() const { return fK1; } | 273 float k1() const { return fK1; } |
270 float k2() const { return fK2; } | 274 float k2() const { return fK2; } |
271 float k3() const { return fK3; } | 275 float k3() const { return fK3; } |
272 float k4() const { return fK4; } | 276 float k4() const { return fK4; } |
| 277 bool unpremultiply() const { return fUnpremultiply; } |
273 | 278 |
274 private: | 279 private: |
275 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 280 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
276 | 281 |
277 GrArithmeticEffect(float k1, float k2, float k3, float k4, GrTexture* backgr
ound); | 282 GrArithmeticEffect(float k1, float k2, float k3, float k4, bool unpremultipl
y, GrTexture* background); |
278 float fK1, fK2, fK3, fK4; | 283 float fK1, fK2, fK3, fK4; |
| 284 bool fUnpremultiply; |
279 GrTextureAccess fBackgroundAccess; | 285 GrTextureAccess fBackgroundAccess; |
280 | 286 |
281 GR_DECLARE_EFFECT_TEST; | 287 GR_DECLARE_EFFECT_TEST; |
282 typedef GrEffect INHERITED; | 288 typedef GrEffect INHERITED; |
283 | 289 |
284 }; | 290 }; |
285 | 291 |
286 /////////////////////////////////////////////////////////////////////////////// | 292 /////////////////////////////////////////////////////////////////////////////// |
287 | 293 |
288 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4, | 294 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4, |
289 GrTexture* background) | 295 bool unpremultiply, GrTexture* background
) |
290 : fK1(k1), fK2(k2), fK3(k3), fK4(k4) { | 296 : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fUnpremultiply(unpremultiply) { |
291 if (background) { | 297 if (background) { |
292 fBackgroundAccess.reset(background); | 298 fBackgroundAccess.reset(background); |
293 this->addTextureAccess(&fBackgroundAccess); | 299 this->addTextureAccess(&fBackgroundAccess); |
294 } else { | 300 } else { |
295 this->setWillReadDstColor(); | 301 this->setWillReadDstColor(); |
296 } | 302 } |
297 } | 303 } |
298 | 304 |
299 GrArithmeticEffect::~GrArithmeticEffect() { | 305 GrArithmeticEffect::~GrArithmeticEffect() { |
300 } | 306 } |
301 | 307 |
302 bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const { | 308 bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const { |
303 const GrArithmeticEffect& s = CastEffect<GrArithmeticEffect>(sBase); | 309 const GrArithmeticEffect& s = CastEffect<GrArithmeticEffect>(sBase); |
304 return fK1 == s.fK1 && | 310 return fK1 == s.fK1 && |
305 fK2 == s.fK2 && | 311 fK2 == s.fK2 && |
306 fK3 == s.fK3 && | 312 fK3 == s.fK3 && |
307 fK4 == s.fK4 && | 313 fK4 == s.fK4 && |
| 314 fUnpremultiply == s.fUnpremultiply && |
308 backgroundTexture() == s.backgroundTexture(); | 315 backgroundTexture() == s.backgroundTexture(); |
309 } | 316 } |
310 | 317 |
311 const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const { | 318 const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const { |
312 return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance(); | 319 return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance(); |
313 } | 320 } |
314 | 321 |
315 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va
lidFlags) const { | 322 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va
lidFlags) const { |
316 // TODO: optimize this | 323 // TODO: optimize this |
317 *validFlags = 0; | 324 *validFlags = 0; |
(...skipping 10 matching lines...) Expand all Loading... |
328 GrGLArithmeticEffect::~GrGLArithmeticEffect() { | 335 GrGLArithmeticEffect::~GrGLArithmeticEffect() { |
329 } | 336 } |
330 | 337 |
331 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder, | 338 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder, |
332 const GrDrawEffect& drawEffect, | 339 const GrDrawEffect& drawEffect, |
333 EffectKey key, | 340 EffectKey key, |
334 const char* outputColor, | 341 const char* outputColor, |
335 const char* inputColor, | 342 const char* inputColor, |
336 const TextureSamplerArray& samplers) { | 343 const TextureSamplerArray& samplers) { |
337 | 344 |
338 GrTexture* backgroundTex = drawEffect.castEffect<GrArithmeticEffect>().backg
roundTexture(); | 345 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>(
); |
| 346 GrTexture* backgroundTex = arith.backgroundTexture(); |
| 347 bool unpremultiply = arith.unpremultiply(); |
339 const char* dstColor; | 348 const char* dstColor; |
340 if (backgroundTex) { | 349 if (backgroundTex) { |
341 const char* bgCoords; | 350 const char* bgCoords; |
342 GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder, key, &
bgCoords, NULL, "BG"); | 351 GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder, key, &
bgCoords, NULL, "BG"); |
343 builder->fsCodeAppend("\t\tvec4 bgColor = "); | 352 builder->fsCodeAppend("\t\tvec4 bgColor = "); |
344 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, | 353 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, |
345 samplers[0], | 354 samplers[0], |
346 bgCoords, | 355 bgCoords, |
347 bgCoordsType); | 356 bgCoordsType); |
348 builder->fsCodeAppendf(";\n"); | 357 builder->fsCodeAppendf(";\n"); |
349 dstColor = "bgColor"; | 358 dstColor = "bgColor"; |
350 } else { | 359 } else { |
351 dstColor = builder->dstColor(); | 360 dstColor = builder->dstColor(); |
352 } | 361 } |
353 | 362 |
354 GrAssert(NULL != dstColor); | 363 GrAssert(NULL != dstColor); |
355 fKUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, | 364 fKUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, |
356 kVec4f_GrSLType, "k"); | 365 kVec4f_GrSLType, "k"); |
357 const char* kUni = builder->getUniformCStr(fKUni); | 366 const char* kUni = builder->getUniformCStr(fKUni); |
358 | 367 |
359 // We don't try to optimize for this case at all | 368 // We don't try to optimize for this case at all |
360 if (NULL == inputColor) { | 369 if (NULL == inputColor) { |
361 builder->fsCodeAppendf("\t\tconst vec4 src = %s;\n", GrGLSLOnesVecf(4)); | 370 builder->fsCodeAppendf("\t\tconst vec4 src = %s;\n", GrGLSLOnesVecf(4)); |
362 } else { | 371 } else { |
363 builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor); | 372 builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor); |
364 builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\
n"); | 373 if (unpremultiply) { |
| 374 builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.
0);\n"); |
| 375 } |
365 } | 376 } |
366 | 377 |
367 builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor); | 378 builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor); |
368 builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n"); | 379 if (unpremultiply) { |
| 380 builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\
n"); |
| 381 } |
369 | 382 |
370 builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst
+ %s.w;\n", outputColor, kUni, kUni, kUni, kUni); | 383 builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst
+ %s.w;\n", outputColor, kUni, kUni, kUni, kUni); |
371 builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu
tColor); | 384 builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu
tColor); |
372 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor); | 385 if (unpremultiply) { |
| 386 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor
); |
| 387 } else { |
| 388 builder->fsCodeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor,
outputColor, outputColor); |
| 389 } |
373 } | 390 } |
374 | 391 |
375 void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawE
ffect& drawEffect) { | 392 void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawE
ffect& drawEffect) { |
376 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>(
); | 393 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>(
); |
377 uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); | 394 uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); |
378 GrTexture* bgTex = arith.backgroundTexture(); | 395 GrTexture* bgTex = arith.backgroundTexture(); |
379 if (bgTex) { | 396 if (bgTex) { |
380 fBackgroundEffectMatrix.setData(uman, | 397 fBackgroundEffectMatrix.setData(uman, |
381 GrEffect::MakeDivByTextureWHMatrix(bgTex
), | 398 GrEffect::MakeDivByTextureWHMatrix(bgTex
), |
382 drawEffect, | 399 drawEffect, |
383 bgTex); | 400 bgTex); |
384 } | 401 } |
385 } | 402 } |
386 | 403 |
387 GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffec
t, const GrGLCaps&) { | 404 GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffec
t, const GrGLCaps&) { |
388 const GrArithmeticEffect& effect = drawEffect.castEffect<GrArithmeticEffect>
(); | 405 const GrArithmeticEffect& effect = drawEffect.castEffect<GrArithmeticEffect>
(); |
389 GrTexture* bgTex = effect.backgroundTexture(); | 406 GrTexture* bgTex = effect.backgroundTexture(); |
390 EffectKey bgKey = 0; | 407 EffectKey bgKey = 0; |
391 if (bgTex) { | 408 if (bgTex) { |
392 bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(bgTe
x), | 409 bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(bgTe
x), |
393 drawEffect, | 410 drawEffect, |
394 GrGLArithmeticEffect::kCoordsType, | 411 GrGLArithmeticEffect::kCoordsType, |
395 bgTex); | 412 bgTex); |
396 } | 413 } |
397 return bgKey; | 414 EffectKey unpremulKey = (effect.unpremultiply() ? 0x1 : 0x0) << GrGLEffectMa
trix::kKeyBits; |
| 415 return unpremulKey | bgKey; |
398 } | 416 } |
399 | 417 |
400 GrEffectRef* GrArithmeticEffect::TestCreate(SkMWCRandom* rand, | 418 GrEffectRef* GrArithmeticEffect::TestCreate(SkMWCRandom* rand, |
401 GrContext*, | 419 GrContext*, |
402 const GrDrawTargetCaps&, | 420 const GrDrawTargetCaps&, |
403 GrTexture*[]) { | 421 GrTexture*[]) { |
404 float k1 = rand->nextF(); | 422 float k1 = rand->nextF(); |
405 float k2 = rand->nextF(); | 423 float k2 = rand->nextF(); |
406 float k3 = rand->nextF(); | 424 float k3 = rand->nextF(); |
407 float k4 = rand->nextF(); | 425 float k4 = rand->nextF(); |
| 426 bool unpremultiply = rand->nextBool(); |
408 | 427 |
409 static AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k
4, NULL))); | 428 static AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k
4, unpremultiply, NULL))); |
410 return CreateEffectRef(gEffect); | 429 return CreateEffectRef(gEffect); |
411 } | 430 } |
412 | 431 |
413 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect); | 432 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect); |
414 | 433 |
415 bool SkArithmeticMode_scalar::asNewEffectOrCoeff(GrContext*, | 434 bool SkArithmeticMode_scalar::asNewEffectOrCoeff(GrContext*, |
416 GrEffectRef** effect, | 435 GrEffectRef** effect, |
417 Coeff*, | 436 Coeff*, |
418 Coeff*, | 437 Coeff*, |
419 GrTexture* background) const { | 438 GrTexture* background) const { |
420 if (effect) { | 439 if (effect) { |
421 *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]), | 440 *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]), |
422 SkScalarToFloat(fK[1]), | 441 SkScalarToFloat(fK[1]), |
423 SkScalarToFloat(fK[2]), | 442 SkScalarToFloat(fK[2]), |
424 SkScalarToFloat(fK[3]), | 443 SkScalarToFloat(fK[3]), |
| 444 fUnpremultiply, |
425 background); | 445 background); |
426 } | 446 } |
427 return true; | 447 return true; |
428 } | 448 } |
429 | 449 |
430 #endif | 450 #endif |
431 | 451 |
432 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) | 452 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) |
433 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) | 453 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) |
434 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 454 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |