Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkXfermode.cpp
1
2 /*
3  * Copyright 2006 The Android Open Source Project
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
10 #include "SkXfermode.h"
11 #include "SkXfermode_opts_SSE2.h"
12 #include "SkXfermode_proccoeff.h"
13 #include "SkColorPriv.h"
14 #include "SkMathPriv.h"
15 #include "SkOnce.h"
16 #include "SkReadBuffer.h"
17 #include "SkString.h"
18 #include "SkUtilsArm.h"
19 #include "SkWriteBuffer.h"
20
21 #if !SK_ARM_NEON_IS_NONE
22 #include "SkXfermode_opts_arm_neon.h"
23 #endif
24
25 #define SkAlphaMulAlpha(a, b)   SkMulDiv255Round(a, b)
26
27 #if 0
28 // idea for higher precision blends in xfer procs (and slightly faster)
29 // see DstATop as a probable caller
30 static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) {
31     SkASSERT(a <= 255);
32     SkASSERT(b <= 255);
33     SkASSERT(c <= 255);
34     SkASSERT(d <= 255);
35     unsigned prod = SkMulS16(a, b) + SkMulS16(c, d) + 128;
36     unsigned result = (prod + (prod >> 8)) >> 8;
37     SkASSERT(result <= 255);
38     return result;
39 }
40 #endif
41
42 static inline unsigned saturated_add(unsigned a, unsigned b) {
43     SkASSERT(a <= 255);
44     SkASSERT(b <= 255);
45     unsigned sum = a + b;
46     if (sum > 255) {
47         sum = 255;
48     }
49     return sum;
50 }
51
52 static inline int clamp_signed_byte(int n) {
53     if (n < 0) {
54         n = 0;
55     } else if (n > 255) {
56         n = 255;
57     }
58     return n;
59 }
60
61 static inline int clamp_div255round(int prod) {
62     if (prod <= 0) {
63         return 0;
64     } else if (prod >= 255*255) {
65         return 255;
66     } else {
67         return SkDiv255Round(prod);
68     }
69 }
70
71 ///////////////////////////////////////////////////////////////////////////////
72
73 //  kClear_Mode,    //!< [0, 0]
74 static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) {
75     return 0;
76 }
77
78 //  kSrc_Mode,      //!< [Sa, Sc]
79 static SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) {
80     return src;
81 }
82
83 //  kDst_Mode,      //!< [Da, Dc]
84 static SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) {
85     return dst;
86 }
87
88 //  kSrcOver_Mode,  //!< [Sa + Da - Sa*Da, Sc + (1 - Sa)*Dc]
89 static SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) {
90 #if 0
91     // this is the old, more-correct way, but it doesn't guarantee that dst==255
92     // will always stay opaque
93     return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
94 #else
95     // this is slightly faster, but more importantly guarantees that dst==255
96     // will always stay opaque
97     return src + SkAlphaMulQ(dst, 256 - SkGetPackedA32(src));
98 #endif
99 }
100
101 //  kDstOver_Mode,  //!< [Sa + Da - Sa*Da, Dc + (1 - Da)*Sc]
102 static SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) {
103     // this is the reverse of srcover, just flipping src and dst
104     // see srcover's comment about the 256 for opaqueness guarantees
105     return dst + SkAlphaMulQ(src, 256 - SkGetPackedA32(dst));
106 }
107
108 //  kSrcIn_Mode,    //!< [Sa * Da, Sc * Da]
109 static SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) {
110     return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst)));
111 }
112
113 //  kDstIn_Mode,    //!< [Sa * Da, Sa * Dc]
114 static SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) {
115     return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src)));
116 }
117
118 //  kSrcOut_Mode,   //!< [Sa * (1 - Da), Sc * (1 - Da)]
119 static SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) {
120     return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst)));
121 }
122
123 //  kDstOut_Mode,   //!< [Da * (1 - Sa), Dc * (1 - Sa)]
124 static SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) {
125     return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
126 }
127
128 //  kSrcATop_Mode,  //!< [Da, Sc * Da + (1 - Sa) * Dc]
129 static SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) {
130     unsigned sa = SkGetPackedA32(src);
131     unsigned da = SkGetPackedA32(dst);
132     unsigned isa = 255 - sa;
133
134     return SkPackARGB32(da,
135                         SkAlphaMulAlpha(da, SkGetPackedR32(src)) +
136                             SkAlphaMulAlpha(isa, SkGetPackedR32(dst)),
137                         SkAlphaMulAlpha(da, SkGetPackedG32(src)) +
138                             SkAlphaMulAlpha(isa, SkGetPackedG32(dst)),
139                         SkAlphaMulAlpha(da, SkGetPackedB32(src)) +
140                             SkAlphaMulAlpha(isa, SkGetPackedB32(dst)));
141 }
142
143 //  kDstATop_Mode,  //!< [Sa, Sa * Dc + Sc * (1 - Da)]
144 static SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) {
145     unsigned sa = SkGetPackedA32(src);
146     unsigned da = SkGetPackedA32(dst);
147     unsigned ida = 255 - da;
148
149     return SkPackARGB32(sa,
150                         SkAlphaMulAlpha(ida, SkGetPackedR32(src)) +
151                             SkAlphaMulAlpha(sa, SkGetPackedR32(dst)),
152                         SkAlphaMulAlpha(ida, SkGetPackedG32(src)) +
153                             SkAlphaMulAlpha(sa, SkGetPackedG32(dst)),
154                         SkAlphaMulAlpha(ida, SkGetPackedB32(src)) +
155                             SkAlphaMulAlpha(sa, SkGetPackedB32(dst)));
156 }
157
158 //  kXor_Mode   [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
159 static SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) {
160     unsigned sa = SkGetPackedA32(src);
161     unsigned da = SkGetPackedA32(dst);
162     unsigned isa = 255 - sa;
163     unsigned ida = 255 - da;
164
165     return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1),
166                         SkAlphaMulAlpha(ida, SkGetPackedR32(src)) +
167                             SkAlphaMulAlpha(isa, SkGetPackedR32(dst)),
168                         SkAlphaMulAlpha(ida, SkGetPackedG32(src)) +
169                             SkAlphaMulAlpha(isa, SkGetPackedG32(dst)),
170                         SkAlphaMulAlpha(ida, SkGetPackedB32(src)) +
171                             SkAlphaMulAlpha(isa, SkGetPackedB32(dst)));
172 }
173
174 ///////////////////////////////////////////////////////////////////////////////
175
176 // kPlus_Mode
177 static SkPMColor plus_modeproc(SkPMColor src, SkPMColor dst) {
178     unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst));
179     unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst));
180     unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst));
181     unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst));
182     return SkPackARGB32(a, r, g, b);
183 }
184
185 // kModulate_Mode
186 static SkPMColor modulate_modeproc(SkPMColor src, SkPMColor dst) {
187     int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst));
188     int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst));
189     int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst));
190     int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst));
191     return SkPackARGB32(a, r, g, b);
192 }
193
194 static inline int srcover_byte(int a, int b) {
195     return a + b - SkAlphaMulAlpha(a, b);
196 }
197
198 // kMultiply_Mode
199 // B(Cb, Cs) = Cb x Cs
200 // multiply uses its own version of blendfunc_byte because sa and da are not needed
201 static int blendfunc_multiply_byte(int sc, int dc, int sa, int da) {
202     return clamp_div255round(sc * (255 - da)  + dc * (255 - sa)  + sc * dc);
203 }
204
205 static SkPMColor multiply_modeproc(SkPMColor src, SkPMColor dst) {
206     int sa = SkGetPackedA32(src);
207     int da = SkGetPackedA32(dst);
208     int a = srcover_byte(sa, da);
209     int r = blendfunc_multiply_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
210     int g = blendfunc_multiply_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
211     int b = blendfunc_multiply_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
212     return SkPackARGB32(a, r, g, b);
213 }
214
215 // kScreen_Mode
216 static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) {
217     int a = srcover_byte(SkGetPackedA32(src), SkGetPackedA32(dst));
218     int r = srcover_byte(SkGetPackedR32(src), SkGetPackedR32(dst));
219     int g = srcover_byte(SkGetPackedG32(src), SkGetPackedG32(dst));
220     int b = srcover_byte(SkGetPackedB32(src), SkGetPackedB32(dst));
221     return SkPackARGB32(a, r, g, b);
222 }
223
224 // kOverlay_Mode
225 static inline int overlay_byte(int sc, int dc, int sa, int da) {
226     int tmp = sc * (255 - da) + dc * (255 - sa);
227     int rc;
228     if (2 * dc <= da) {
229         rc = 2 * sc * dc;
230     } else {
231         rc = sa * da - 2 * (da - dc) * (sa - sc);
232     }
233     return clamp_div255round(rc + tmp);
234 }
235 static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) {
236     int sa = SkGetPackedA32(src);
237     int da = SkGetPackedA32(dst);
238     int a = srcover_byte(sa, da);
239     int r = overlay_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
240     int g = overlay_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
241     int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
242     return SkPackARGB32(a, r, g, b);
243 }
244
245 // kDarken_Mode
246 static inline int darken_byte(int sc, int dc, int sa, int da) {
247     int sd = sc * da;
248     int ds = dc * sa;
249     if (sd < ds) {
250         // srcover
251         return sc + dc - SkDiv255Round(ds);
252     } else {
253         // dstover
254         return dc + sc - SkDiv255Round(sd);
255     }
256 }
257 static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) {
258     int sa = SkGetPackedA32(src);
259     int da = SkGetPackedA32(dst);
260     int a = srcover_byte(sa, da);
261     int r = darken_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
262     int g = darken_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
263     int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
264     return SkPackARGB32(a, r, g, b);
265 }
266
267 // kLighten_Mode
268 static inline int lighten_byte(int sc, int dc, int sa, int da) {
269     int sd = sc * da;
270     int ds = dc * sa;
271     if (sd > ds) {
272         // srcover
273         return sc + dc - SkDiv255Round(ds);
274     } else {
275         // dstover
276         return dc + sc - SkDiv255Round(sd);
277     }
278 }
279 static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) {
280     int sa = SkGetPackedA32(src);
281     int da = SkGetPackedA32(dst);
282     int a = srcover_byte(sa, da);
283     int r = lighten_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
284     int g = lighten_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
285     int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
286     return SkPackARGB32(a, r, g, b);
287 }
288
289 // kColorDodge_Mode
290 static inline int colordodge_byte(int sc, int dc, int sa, int da) {
291     int diff = sa - sc;
292     int rc;
293     if (0 == dc) {
294         return SkAlphaMulAlpha(sc, 255 - da);
295     } else if (0 == diff) {
296         rc = sa * da + sc * (255 - da) + dc * (255 - sa);
297     } else {
298         diff = dc * sa / diff;
299         rc = sa * ((da < diff) ? da : diff) + sc * (255 - da) + dc * (255 - sa);
300     }
301     return clamp_div255round(rc);
302 }
303 static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) {
304     int sa = SkGetPackedA32(src);
305     int da = SkGetPackedA32(dst);
306     int a = srcover_byte(sa, da);
307     int r = colordodge_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
308     int g = colordodge_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
309     int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
310     return SkPackARGB32(a, r, g, b);
311 }
312
313 // kColorBurn_Mode
314 static inline int colorburn_byte(int sc, int dc, int sa, int da) {
315     int rc;
316     if (dc == da) {
317         rc = sa * da + sc * (255 - da) + dc * (255 - sa);
318     } else if (0 == sc) {
319         return SkAlphaMulAlpha(dc, 255 - sa);
320     } else {
321         int tmp = (da - dc) * sa / sc;
322         rc = sa * (da - ((da < tmp) ? da : tmp))
323             + sc * (255 - da) + dc * (255 - sa);
324     }
325     return clamp_div255round(rc);
326 }
327 static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) {
328     int sa = SkGetPackedA32(src);
329     int da = SkGetPackedA32(dst);
330     int a = srcover_byte(sa, da);
331     int r = colorburn_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
332     int g = colorburn_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
333     int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
334     return SkPackARGB32(a, r, g, b);
335 }
336
337 // kHardLight_Mode
338 static inline int hardlight_byte(int sc, int dc, int sa, int da) {
339     int rc;
340     if (2 * sc <= sa) {
341         rc = 2 * sc * dc;
342     } else {
343         rc = sa * da - 2 * (da - dc) * (sa - sc);
344     }
345     return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa));
346 }
347 static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) {
348     int sa = SkGetPackedA32(src);
349     int da = SkGetPackedA32(dst);
350     int a = srcover_byte(sa, da);
351     int r = hardlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
352     int g = hardlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
353     int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
354     return SkPackARGB32(a, r, g, b);
355 }
356
357 // returns 255 * sqrt(n/255)
358 static U8CPU sqrt_unit_byte(U8CPU n) {
359     return SkSqrtBits(n, 15+4);
360 }
361
362 // kSoftLight_Mode
363 static inline int softlight_byte(int sc, int dc, int sa, int da) {
364     int m = da ? dc * 256 / da : 0;
365     int rc;
366     if (2 * sc <= sa) {
367         rc = dc * (sa + ((2 * sc - sa) * (256 - m) >> 8));
368     } else if (4 * dc <= da) {
369         int tmp = (4 * m * (4 * m + 256) * (m - 256) >> 16) + 7 * m;
370         rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8);
371     } else {
372         int tmp = sqrt_unit_byte(m) - m;
373         rc = dc * sa + (da * (2 * sc - sa) * tmp >> 8);
374     }
375     return clamp_div255round(rc + sc * (255 - da) + dc * (255 - sa));
376 }
377 static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) {
378     int sa = SkGetPackedA32(src);
379     int da = SkGetPackedA32(dst);
380     int a = srcover_byte(sa, da);
381     int r = softlight_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
382     int g = softlight_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
383     int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
384     return SkPackARGB32(a, r, g, b);
385 }
386
387 // kDifference_Mode
388 static inline int difference_byte(int sc, int dc, int sa, int da) {
389     int tmp = SkMin32(sc * da, dc * sa);
390     return clamp_signed_byte(sc + dc - 2 * SkDiv255Round(tmp));
391 }
392 static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) {
393     int sa = SkGetPackedA32(src);
394     int da = SkGetPackedA32(dst);
395     int a = srcover_byte(sa, da);
396     int r = difference_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
397     int g = difference_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
398     int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
399     return SkPackARGB32(a, r, g, b);
400 }
401
402 // kExclusion_Mode
403 static inline int exclusion_byte(int sc, int dc, int, int) {
404     // this equations is wacky, wait for SVG to confirm it
405     //int r = sc * da + dc * sa - 2 * sc * dc + sc * (255 - da) + dc * (255 - sa);
406
407     // The above equation can be simplified as follows
408     int r = 255*(sc + dc) - 2 * sc * dc;
409     return clamp_div255round(r);
410 }
411 static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) {
412     int sa = SkGetPackedA32(src);
413     int da = SkGetPackedA32(dst);
414     int a = srcover_byte(sa, da);
415     int r = exclusion_byte(SkGetPackedR32(src), SkGetPackedR32(dst), sa, da);
416     int g = exclusion_byte(SkGetPackedG32(src), SkGetPackedG32(dst), sa, da);
417     int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
418     return SkPackARGB32(a, r, g, b);
419 }
420
421 // The CSS compositing spec introduces the following formulas:
422 // (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable)
423 // SkComputeLuminance is similar to this formula but it uses the new definition from Rec. 709
424 // while PDF and CG uses the one from Rec. Rec. 601
425 // See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm
426 static inline int Lum(int r, int g, int b)
427 {
428     return SkDiv255Round(r * 77 + g * 150 + b * 28);
429 }
430
431 static inline int min2(int a, int b) { return a < b ? a : b; }
432 static inline int max2(int a, int b) { return a > b ? a : b; }
433 #define minimum(a, b, c) min2(min2(a, b), c)
434 #define maximum(a, b, c) max2(max2(a, b), c)
435
436 static inline int Sat(int r, int g, int b) {
437     return maximum(r, g, b) - minimum(r, g, b);
438 }
439
440 static inline void setSaturationComponents(int* Cmin, int* Cmid, int* Cmax, int s) {
441     if(*Cmax > *Cmin) {
442         *Cmid =  SkMulDiv(*Cmid - *Cmin, s, *Cmax - *Cmin);
443         *Cmax = s;
444     } else {
445         *Cmax = 0;
446         *Cmid = 0;
447     }
448
449     *Cmin = 0;
450 }
451
452 static inline void SetSat(int* r, int* g, int* b, int s) {
453     if(*r <= *g) {
454         if(*g <= *b) {
455             setSaturationComponents(r, g, b, s);
456         } else if(*r <= *b) {
457             setSaturationComponents(r, b, g, s);
458         } else {
459             setSaturationComponents(b, r, g, s);
460         }
461     } else if(*r <= *b) {
462         setSaturationComponents(g, r, b, s);
463     } else if(*g <= *b) {
464         setSaturationComponents(g, b, r, s);
465     } else {
466         setSaturationComponents(b, g, r, s);
467     }
468 }
469
470 static inline void clipColor(int* r, int* g, int* b, int a) {
471     int L = Lum(*r, *g, *b);
472     int n = minimum(*r, *g, *b);
473     int x = maximum(*r, *g, *b);
474     int denom;
475     if ((n < 0) && (denom = L - n)) { // Compute denom and make sure it's non zero
476        *r = L + SkMulDiv(*r - L, L, denom);
477        *g = L + SkMulDiv(*g - L, L, denom);
478        *b = L + SkMulDiv(*b - L, L, denom);
479     }
480
481     if ((x > a) && (denom = x - L)) { // Compute denom and make sure it's non zero
482        int numer = a - L;
483        *r = L + SkMulDiv(*r - L, numer, denom);
484        *g = L + SkMulDiv(*g - L, numer, denom);
485        *b = L + SkMulDiv(*b - L, numer, denom);
486     }
487 }
488
489 static inline void SetLum(int* r, int* g, int* b, int a, int l) {
490   int d = l - Lum(*r, *g, *b);
491   *r +=  d;
492   *g +=  d;
493   *b +=  d;
494
495   clipColor(r, g, b, a);
496 }
497
498 // non-separable blend modes are done in non-premultiplied alpha
499 #define  blendfunc_nonsep_byte(sc, dc, sa, da, blendval) \
500   clamp_div255round(sc * (255 - da) +  dc * (255 - sa) + blendval)
501
502 // kHue_Mode
503 // B(Cb, Cs) = SetLum(SetSat(Cs, Sat(Cb)), Lum(Cb))
504 // Create a color with the hue of the source color and the saturation and luminosity of the backdrop color.
505 static SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) {
506     int sr = SkGetPackedR32(src);
507     int sg = SkGetPackedG32(src);
508     int sb = SkGetPackedB32(src);
509     int sa = SkGetPackedA32(src);
510
511     int dr = SkGetPackedR32(dst);
512     int dg = SkGetPackedG32(dst);
513     int db = SkGetPackedB32(dst);
514     int da = SkGetPackedA32(dst);
515     int Sr, Sg, Sb;
516
517     if(sa && da) {
518         Sr = sr * sa;
519         Sg = sg * sa;
520         Sb = sb * sa;
521         SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa);
522         SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa);
523     } else {
524         Sr = 0;
525         Sg = 0;
526         Sb = 0;
527     }
528
529     int a = srcover_byte(sa, da);
530     int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr);
531     int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg);
532     int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb);
533     return SkPackARGB32(a, r, g, b);
534 }
535
536 // kSaturation_Mode
537 // B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb))
538 // Create a color with the saturation of the source color and the hue and luminosity of the backdrop color.
539 static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) {
540     int sr = SkGetPackedR32(src);
541     int sg = SkGetPackedG32(src);
542     int sb = SkGetPackedB32(src);
543     int sa = SkGetPackedA32(src);
544
545     int dr = SkGetPackedR32(dst);
546     int dg = SkGetPackedG32(dst);
547     int db = SkGetPackedB32(dst);
548     int da = SkGetPackedA32(dst);
549     int Dr, Dg, Db;
550
551     if(sa && da) {
552         Dr = dr * sa;
553         Dg = dg * sa;
554         Db = db * sa;
555         SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da);
556         SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa);
557     } else {
558         Dr = 0;
559         Dg = 0;
560         Db = 0;
561     }
562
563     int a = srcover_byte(sa, da);
564     int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr);
565     int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg);
566     int b = blendfunc_nonsep_byte(sb, db, sa, da, Db);
567     return SkPackARGB32(a, r, g, b);
568 }
569
570 // kColor_Mode
571 // B(Cb, Cs) = SetLum(Cs, Lum(Cb))
572 // Create a color with the hue and saturation of the source color and the luminosity of the backdrop color.
573 static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) {
574     int sr = SkGetPackedR32(src);
575     int sg = SkGetPackedG32(src);
576     int sb = SkGetPackedB32(src);
577     int sa = SkGetPackedA32(src);
578
579     int dr = SkGetPackedR32(dst);
580     int dg = SkGetPackedG32(dst);
581     int db = SkGetPackedB32(dst);
582     int da = SkGetPackedA32(dst);
583     int Sr, Sg, Sb;
584
585     if(sa && da) {
586         Sr = sr * da;
587         Sg = sg * da;
588         Sb = sb * da;
589         SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa);
590     } else {
591         Sr = 0;
592         Sg = 0;
593         Sb = 0;
594     }
595
596     int a = srcover_byte(sa, da);
597     int r = blendfunc_nonsep_byte(sr, dr, sa, da, Sr);
598     int g = blendfunc_nonsep_byte(sg, dg, sa, da, Sg);
599     int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb);
600     return SkPackARGB32(a, r, g, b);
601 }
602
603 // kLuminosity_Mode
604 // B(Cb, Cs) = SetLum(Cb, Lum(Cs))
605 // Create a color with the luminosity of the source color and the hue and saturation of the backdrop color.
606 static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) {
607     int sr = SkGetPackedR32(src);
608     int sg = SkGetPackedG32(src);
609     int sb = SkGetPackedB32(src);
610     int sa = SkGetPackedA32(src);
611
612     int dr = SkGetPackedR32(dst);
613     int dg = SkGetPackedG32(dst);
614     int db = SkGetPackedB32(dst);
615     int da = SkGetPackedA32(dst);
616     int Dr, Dg, Db;
617
618     if(sa && da) {
619         Dr = dr * sa;
620         Dg = dg * sa;
621         Db = db * sa;
622         SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da);
623     } else {
624         Dr = 0;
625         Dg = 0;
626         Db = 0;
627     }
628
629     int a = srcover_byte(sa, da);
630     int r = blendfunc_nonsep_byte(sr, dr, sa, da, Dr);
631     int g = blendfunc_nonsep_byte(sg, dg, sa, da, Dg);
632     int b = blendfunc_nonsep_byte(sb, db, sa, da, Db);
633     return SkPackARGB32(a, r, g, b);
634 }
635
636 const ProcCoeff gProcCoeffs[] = {
637     { clear_modeproc,   SkXfermode::kZero_Coeff,    SkXfermode::kZero_Coeff },
638     { src_modeproc,     SkXfermode::kOne_Coeff,     SkXfermode::kZero_Coeff },
639     { dst_modeproc,     SkXfermode::kZero_Coeff,    SkXfermode::kOne_Coeff },
640     { srcover_modeproc, SkXfermode::kOne_Coeff,     SkXfermode::kISA_Coeff },
641     { dstover_modeproc, SkXfermode::kIDA_Coeff,     SkXfermode::kOne_Coeff },
642     { srcin_modeproc,   SkXfermode::kDA_Coeff,      SkXfermode::kZero_Coeff },
643     { dstin_modeproc,   SkXfermode::kZero_Coeff,    SkXfermode::kSA_Coeff },
644     { srcout_modeproc,  SkXfermode::kIDA_Coeff,     SkXfermode::kZero_Coeff },
645     { dstout_modeproc,  SkXfermode::kZero_Coeff,    SkXfermode::kISA_Coeff },
646     { srcatop_modeproc, SkXfermode::kDA_Coeff,      SkXfermode::kISA_Coeff },
647     { dstatop_modeproc, SkXfermode::kIDA_Coeff,     SkXfermode::kSA_Coeff },
648     { xor_modeproc,     SkXfermode::kIDA_Coeff,     SkXfermode::kISA_Coeff },
649
650     { plus_modeproc,    SkXfermode::kOne_Coeff,     SkXfermode::kOne_Coeff },
651     { modulate_modeproc,SkXfermode::kZero_Coeff,    SkXfermode::kSC_Coeff },
652     { screen_modeproc,  SkXfermode::kOne_Coeff,     SkXfermode::kISC_Coeff },
653     { overlay_modeproc,     CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
654     { darken_modeproc,      CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
655     { lighten_modeproc,     CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
656     { colordodge_modeproc,  CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
657     { colorburn_modeproc,   CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
658     { hardlight_modeproc,   CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
659     { softlight_modeproc,   CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
660     { difference_modeproc,  CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
661     { exclusion_modeproc,   CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
662     { multiply_modeproc,    CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
663     { hue_modeproc,         CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
664     { saturation_modeproc,  CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
665     { color_modeproc,       CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
666     { luminosity_modeproc,  CANNOT_USE_COEFF,       CANNOT_USE_COEFF },
667 };
668
669 ///////////////////////////////////////////////////////////////////////////////
670
671 bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) const {
672     return false;
673 }
674
675 bool SkXfermode::asMode(Mode* mode) const {
676     return false;
677 }
678
679 bool SkXfermode::asNewEffect(GrEffectRef** effect, GrTexture* background) const {
680     return false;
681 }
682
683 bool SkXfermode::AsNewEffectOrCoeff(SkXfermode* xfermode,
684                                     GrEffectRef** effect,
685                                     Coeff* src,
686                                     Coeff* dst,
687                                     GrTexture* background) {
688     if (NULL == xfermode) {
689         return ModeAsCoeff(kSrcOver_Mode, src, dst);
690     } else if (xfermode->asCoeff(src, dst)) {
691         return true;
692     } else {
693         return xfermode->asNewEffect(effect, background);
694     }
695 }
696
697 SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{
698     // no-op. subclasses should override this
699     return dst;
700 }
701
702 void SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
703                         const SkPMColor* SK_RESTRICT src, int count,
704                         const SkAlpha* SK_RESTRICT aa) const {
705     SkASSERT(dst && src && count >= 0);
706
707     if (NULL == aa) {
708         for (int i = count - 1; i >= 0; --i) {
709             dst[i] = this->xferColor(src[i], dst[i]);
710         }
711     } else {
712         for (int i = count - 1; i >= 0; --i) {
713             unsigned a = aa[i];
714             if (0 != a) {
715                 SkPMColor dstC = dst[i];
716                 SkPMColor C = this->xferColor(src[i], dstC);
717                 if (0xFF != a) {
718                     C = SkFourByteInterp(C, dstC, a);
719                 }
720                 dst[i] = C;
721             }
722         }
723     }
724 }
725
726 void SkXfermode::xfer16(uint16_t* dst,
727                         const SkPMColor* SK_RESTRICT src, int count,
728                         const SkAlpha* SK_RESTRICT aa) const {
729     SkASSERT(dst && src && count >= 0);
730
731     if (NULL == aa) {
732         for (int i = count - 1; i >= 0; --i) {
733             SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
734             dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC));
735         }
736     } else {
737         for (int i = count - 1; i >= 0; --i) {
738             unsigned a = aa[i];
739             if (0 != a) {
740                 SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
741                 SkPMColor C = this->xferColor(src[i], dstC);
742                 if (0xFF != a) {
743                     C = SkFourByteInterp(C, dstC, a);
744                 }
745                 dst[i] = SkPixel32ToPixel16_ToU16(C);
746             }
747         }
748     }
749 }
750
751 void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
752                         const SkPMColor src[], int count,
753                         const SkAlpha* SK_RESTRICT aa) const {
754     SkASSERT(dst && src && count >= 0);
755
756     if (NULL == aa) {
757         for (int i = count - 1; i >= 0; --i) {
758             SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT));
759             dst[i] = SkToU8(SkGetPackedA32(res));
760         }
761     } else {
762         for (int i = count - 1; i >= 0; --i) {
763             unsigned a = aa[i];
764             if (0 != a) {
765                 SkAlpha dstA = dst[i];
766                 unsigned A = SkGetPackedA32(this->xferColor(src[i],
767                                             (SkPMColor)(dstA << SK_A32_SHIFT)));
768                 if (0xFF != a) {
769                     A = SkAlphaBlend(A, dstA, SkAlpha255To256(a));
770                 }
771                 dst[i] = SkToU8(A);
772             }
773         }
774     }
775 }
776
777 //////////////////////////////////////////////////////////////////////////////
778
779 #if SK_SUPPORT_GPU
780
781 #include "GrEffect.h"
782 #include "GrCoordTransform.h"
783 #include "GrEffectUnitTest.h"
784 #include "GrTBackendEffectFactory.h"
785 #include "gl/GrGLEffect.h"
786
787 /**
788  * GrEffect that implements the all the separable xfer modes that cannot be expressed as Coeffs.
789  */
790 class XferEffect : public GrEffect {
791 public:
792     static bool IsSupportedMode(SkXfermode::Mode mode) {
793         return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMode;
794     }
795
796     static GrEffectRef* Create(SkXfermode::Mode mode, GrTexture* background) {
797         if (!IsSupportedMode(mode)) {
798             return NULL;
799         } else {
800             AutoEffectUnref effect(SkNEW_ARGS(XferEffect, (mode, background)));
801             return CreateEffectRef(effect);
802         }
803     }
804
805     virtual void getConstantColorComponents(GrColor* color,
806                                             uint32_t* validFlags) const SK_OVERRIDE {
807         *validFlags = 0;
808     }
809
810     virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE {
811         return GrTBackendEffectFactory<XferEffect>::getInstance();
812     }
813
814     static const char* Name() { return "XferEffect"; }
815
816     SkXfermode::Mode mode() const { return fMode; }
817     const GrTextureAccess&  backgroundAccess() const { return fBackgroundAccess; }
818
819     class GLEffect : public GrGLEffect {
820     public:
821         GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&)
822             : GrGLEffect(factory) {
823         }
824         virtual void emitCode(GrGLShaderBuilder* builder,
825                               const GrDrawEffect& drawEffect,
826                               EffectKey key,
827                               const char* outputColor,
828                               const char* inputColor,
829                               const TransformedCoordsArray& coords,
830                               const TextureSamplerArray& samplers) SK_OVERRIDE {
831             SkXfermode::Mode mode = drawEffect.castEffect<XferEffect>().mode();
832             const GrTexture* backgroundTex = drawEffect.castEffect<XferEffect>().backgroundAccess().getTexture();
833             const char* dstColor;
834             if (backgroundTex) {
835                 dstColor = "bgColor";
836                 builder->fsCodeAppendf("\t\tvec4 %s = ", dstColor);
837                 builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].type());
838                 builder->fsCodeAppendf(";\n");
839             } else {
840                 dstColor = builder->dstColor();
841             }
842             SkASSERT(NULL != dstColor);
843
844             // We don't try to optimize for this case at all
845             if (NULL == inputColor) {
846                 builder->fsCodeAppendf("\t\tconst vec4 ones = vec4(1);\n");
847                 inputColor = "ones";
848             }
849             builder->fsCodeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode));
850
851             // These all perform src-over on the alpha channel.
852             builder->fsCodeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n",
853                                     outputColor, inputColor, inputColor, dstColor);
854
855             switch (mode) {
856                 case SkXfermode::kOverlay_Mode:
857                     // Overlay is Hard-Light with the src and dst reversed
858                     HardLight(builder, outputColor, dstColor, inputColor);
859                     break;
860                 case SkXfermode::kDarken_Mode:
861                     builder->fsCodeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, "
862                                                             "(1.0 - %s.a) * %s.rgb + %s.rgb);\n",
863                                             outputColor,
864                                             inputColor, dstColor, inputColor,
865                                             dstColor, inputColor, dstColor);
866                     break;
867                 case SkXfermode::kLighten_Mode:
868                     builder->fsCodeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, "
869                                                             "(1.0 - %s.a) * %s.rgb + %s.rgb);\n",
870                                             outputColor,
871                                             inputColor, dstColor, inputColor,
872                                             dstColor, inputColor, dstColor);
873                     break;
874                 case SkXfermode::kColorDodge_Mode:
875                     ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'r');
876                     ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'g');
877                     ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'b');
878                     break;
879                 case SkXfermode::kColorBurn_Mode:
880                     ColorBurnComponent(builder, outputColor, inputColor, dstColor, 'r');
881                     ColorBurnComponent(builder, outputColor, inputColor, dstColor, 'g');
882                     ColorBurnComponent(builder, outputColor, inputColor, dstColor, 'b');
883                     break;
884                 case SkXfermode::kHardLight_Mode:
885                     HardLight(builder, outputColor, inputColor, dstColor);
886                     break;
887                 case SkXfermode::kSoftLight_Mode:
888                     builder->fsCodeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor);
889                     builder->fsCodeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor);
890                     builder->fsCodeAppendf("\t\t} else {\n");
891                     SoftLightComponentPosDstAlpha(builder, outputColor, inputColor, dstColor, 'r');
892                     SoftLightComponentPosDstAlpha(builder, outputColor, inputColor, dstColor, 'g');
893                     SoftLightComponentPosDstAlpha(builder, outputColor, inputColor, dstColor, 'b');
894                     builder->fsCodeAppendf("\t\t}\n");
895                     break;
896                 case SkXfermode::kDifference_Mode:
897                     builder->fsCodeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -"
898                                                        "2.0 * min(%s.rgb * %s.a, %s.rgb * %s.a);\n",
899                                            outputColor, inputColor, dstColor, inputColor, dstColor,
900                                            dstColor, inputColor);
901                     break;
902                 case SkXfermode::kExclusion_Mode:
903                     builder->fsCodeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - "
904                                                         "2.0 * %s.rgb * %s.rgb;\n",
905                                            outputColor, dstColor, inputColor, dstColor, inputColor);
906                     break;
907                 case SkXfermode::kMultiply_Mode:
908                     builder->fsCodeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + "
909                                                         "(1.0 - %s.a) * %s.rgb + "
910                                                          "%s.rgb * %s.rgb;\n",
911                                            outputColor, inputColor, dstColor, dstColor, inputColor,
912                                            inputColor, dstColor);
913                     break;
914                 case SkXfermode::kHue_Mode: {
915                     //  SetLum(SetSat(S * Da, Sat(D * Sa)), Sa*Da, D*Sa) + (1 - Sa) * D + (1 - Da) * S
916                     SkString setSat, setLum;
917                     AddSatFunction(builder, &setSat);
918                     AddLumFunction(builder, &setLum);
919                     builder->fsCodeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
920                                            dstColor, inputColor);
921                     builder->fsCodeAppendf("\t\t%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
922                                            outputColor, setLum.c_str(), setSat.c_str(), inputColor,
923                                            dstColor);
924                     builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
925                                            outputColor, inputColor, dstColor, dstColor, inputColor);
926                     break;
927                 }
928                 case SkXfermode::kSaturation_Mode: {
929                     // SetLum(SetSat(D * Sa, Sat(S * Da)), Sa*Da, D*Sa)) + (1 - Sa) * D + (1 - Da) * S
930                     SkString setSat, setLum;
931                     AddSatFunction(builder, &setSat);
932                     AddLumFunction(builder, &setLum);
933                     builder->fsCodeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
934                                            dstColor, inputColor);
935                     builder->fsCodeAppendf("\t\t%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
936                                            outputColor, setLum.c_str(), setSat.c_str(), inputColor,
937                                            dstColor);
938                     builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
939                                            outputColor, inputColor, dstColor, dstColor, inputColor);
940                     break;
941                 }
942                 case SkXfermode::kColor_Mode: {
943                     //  SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S
944                     SkString setLum;
945                     AddLumFunction(builder, &setLum);
946                     builder->fsCodeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
947                                            inputColor, dstColor);
948                     builder->fsCodeAppendf("\t\t%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);\n",
949                                            outputColor, setLum.c_str(), dstColor, inputColor);
950                     builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
951                                            outputColor, inputColor, dstColor, dstColor, inputColor);
952                     break;
953                 }
954                 case SkXfermode::kLuminosity_Mode: {
955                     //  SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S
956                     SkString setLum;
957                     AddLumFunction(builder, &setLum);
958                     builder->fsCodeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
959                                            inputColor, dstColor);
960                     builder->fsCodeAppendf("\t\t%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);\n",
961                                            outputColor, setLum.c_str(), dstColor, inputColor);
962                     builder->fsCodeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
963                                            outputColor, inputColor, dstColor, dstColor, inputColor);
964                     break;
965                 }
966                 default:
967                     SkFAIL("Unknown XferEffect mode.");
968                     break;
969             }
970         }
971
972         static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) {
973             // The background may come from the dst or from a texture.
974             int numTextures = (*drawEffect.effect())->numTextures();
975             SkASSERT(numTextures <= 1);
976             return (drawEffect.castEffect<XferEffect>().mode() << 1) | numTextures;
977         }
978
979     private:
980         static void HardLight(GrGLShaderBuilder* builder,
981                               const char* final,
982                               const char* src,
983                               const char* dst) {
984             static const char kComponents[] = {'r', 'g', 'b'};
985             for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) {
986                 char component = kComponents[i];
987                 builder->fsCodeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
988                 builder->fsCodeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", final, component, src, component, dst, component);
989                 builder->fsCodeAppend("\t\t} else {\n");
990                 builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s.a - %s.%c);\n",
991                                        final, component, src, dst, dst, dst, component, src, src, component);
992                 builder->fsCodeAppend("\t\t}\n");
993             }
994             builder->fsCodeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n",
995                                    final, src, dst, dst, src);
996         }
997
998         // Does one component of color-dodge
999         static void ColorDodgeComponent(GrGLShaderBuilder* builder,
1000                                         const char* final,
1001                                         const char* src,
1002                                         const char* dst,
1003                                         const char component) {
1004             builder->fsCodeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component);
1005             builder->fsCodeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
1006                                    final, component, src, component, dst);
1007             builder->fsCodeAppend("\t\t} else {\n");
1008             builder->fsCodeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component);
1009             builder->fsCodeAppend("\t\t\tif (0.0 == d) {\n");
1010             builder->fsCodeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
1011                                    final, component, src, dst, src, component, dst, dst, component,
1012                                    src);
1013             builder->fsCodeAppend("\t\t\t} else {\n");
1014             builder->fsCodeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n",
1015                                    dst, dst, component, src);
1016             builder->fsCodeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
1017                                    final, component, src, src, component, dst, dst, component, src);
1018             builder->fsCodeAppend("\t\t\t}\n");
1019             builder->fsCodeAppend("\t\t}\n");
1020         }
1021
1022         // Does one component of color-burn
1023         static void ColorBurnComponent(GrGLShaderBuilder* builder,
1024                                        const char* final,
1025                                        const char* src,
1026                                        const char* dst,
1027                                        const char component) {
1028             builder->fsCodeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, component);
1029             builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
1030                                    final, component, src, dst, src, component, dst, dst, component,
1031                                    src);
1032             builder->fsCodeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, component);
1033             builder->fsCodeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
1034                                    final, component, dst, component, src);
1035             builder->fsCodeAppend("\t\t} else {\n");
1036             builder->fsCodeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / %s.%c);\n",
1037                                    dst, dst, dst, component, src, src, component);
1038             builder->fsCodeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
1039                                    final, component, src, src, component, dst, dst, component, src);
1040             builder->fsCodeAppend("\t\t}\n");
1041         }
1042
1043         // Does one component of soft-light. Caller should have already checked that dst alpha > 0.
1044         static void SoftLightComponentPosDstAlpha(GrGLShaderBuilder* builder,
1045                                                   const char* final,
1046                                                   const char* src,
1047                                                   const char* dst,
1048                                                   const char component) {
1049             // if (2S < Sa)
1050             builder->fsCodeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
1051             // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1)
1052             builder->fsCodeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.%c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n",
1053                                    final, component, dst, component, dst, component, src, src,
1054                                    component, dst, dst, src, component, dst, component, src, src,
1055                                    component);
1056             // else if (4D < Da)
1057             builder->fsCodeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n",
1058                                    dst, component, dst);
1059             builder->fsCodeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n",
1060                                    dst, component, dst, component);
1061             builder->fsCodeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component);
1062             builder->fsCodeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst);
1063             builder->fsCodeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst);
1064             // (Da^3 (-S)+Da^2 (S-D (3 Sa-6 S-1))+12 Da D^2 (Sa-2 S)-16 D^3 (Sa-2 S))/Da^2
1065             builder->fsCodeAppendf("\t\t\t\t%s.%c = (-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) + 12.0*%s.a*DSqd*(%s.a - 2.0*%s.%c) - 16.0*DCub * (%s.a - 2.0*%s.%c)) / DaSqd;\n",
1066                                    final, component, src, component, src, component, dst, component,
1067                                    src, src, component, dst, src, src, component, src, src,
1068                                    component);
1069             builder->fsCodeAppendf("\t\t\t} else {\n");
1070             // -sqrt(Da * D) (Sa-2 S)-Da S+D (Sa-2 S+1)+S
1071             builder->fsCodeAppendf("\t\t\t\t%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2.0*%s.%c) - %s.a*%s.%c + %s.%c*(%s.a - 2.0*%s.%c + 1.0) + %s.%c;\n",
1072                                     final, component, dst, dst, component, src, src, component, dst,
1073                                     src, component, dst, component, src, src, component, src,
1074                                     component);
1075             builder->fsCodeAppendf("\t\t\t}\n");
1076         }
1077
1078         // Adds a function that takes two colors and an alpha as input. It produces a color with the
1079         // hue and saturation of the first color, the luminosity of the second color, and the input
1080         // alpha. It has this signature:
1081         //      vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor).
1082         static void AddLumFunction(GrGLShaderBuilder* builder, SkString* setLumFunction) {
1083             // Emit a helper that gets the luminance of a color.
1084             SkString getFunction;
1085             GrGLShaderVar getLumArgs[] = {
1086                 GrGLShaderVar("color", kVec3f_GrSLType),
1087             };
1088             SkString getLumBody("\treturn dot(vec3(0.3, 0.59, 0.11), color);\n");
1089             builder->fsEmitFunction(kFloat_GrSLType,
1090                                     "luminance",
1091                                     SK_ARRAY_COUNT(getLumArgs), getLumArgs,
1092                                     getLumBody.c_str(),
1093                                     &getFunction);
1094
1095             // Emit the set luminance function.
1096             GrGLShaderVar setLumArgs[] = {
1097                 GrGLShaderVar("hueSat", kVec3f_GrSLType),
1098                 GrGLShaderVar("alpha", kFloat_GrSLType),
1099                 GrGLShaderVar("lumColor", kVec3f_GrSLType),
1100             };
1101             SkString setLumBody;
1102             setLumBody.printf("\tfloat diff = %s(lumColor - hueSat);\n", getFunction.c_str());
1103             setLumBody.append("\tvec3 outColor = hueSat + diff;\n");
1104             setLumBody.appendf("\tfloat outLum = %s(outColor);\n", getFunction.c_str());
1105             setLumBody.append("\tfloat minComp = min(min(outColor.r, outColor.g), outColor.b);\n"
1106                               "\tfloat maxComp = max(max(outColor.r, outColor.g), outColor.b);\n"
1107                               "\tif (minComp < 0.0) {\n"
1108                               "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * outLum) / (outLum - minComp);\n"
1109                               "\t}\n"
1110                               "\tif (maxComp > alpha) {\n"
1111                               "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) / (maxComp - outLum);\n"
1112                               "\t}\n"
1113                               "\treturn outColor;\n");
1114             builder->fsEmitFunction(kVec3f_GrSLType,
1115                                     "set_luminance",
1116                                     SK_ARRAY_COUNT(setLumArgs), setLumArgs,
1117                                     setLumBody.c_str(),
1118                                     setLumFunction);
1119         }
1120
1121         // Adds a function that creates a color with the hue and luminosity of one input color and
1122         // the saturation of another color. It will have this signature:
1123         //      float set_saturation(vec3 hueLumColor, vec3 satColor)
1124         static void AddSatFunction(GrGLShaderBuilder* builder, SkString* setSatFunction) {
1125             // Emit a helper that gets the saturation of a color
1126             SkString getFunction;
1127             GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLType) };
1128             SkString getSatBody;
1129             getSatBody.printf("\treturn max(max(color.r, color.g), color.b) - "
1130                               "min(min(color.r, color.g), color.b);\n");
1131             builder->fsEmitFunction(kFloat_GrSLType,
1132                                     "saturation",
1133                                     SK_ARRAY_COUNT(getSatArgs), getSatArgs,
1134                                     getSatBody.c_str(),
1135                                     &getFunction);
1136
1137             // Emit a helper that sets the saturation given sorted input channels. This used
1138             // to use inout params for min, mid, and max components but that seems to cause
1139             // problems on PowerVR drivers. So instead it returns a vec3 where r, g ,b are the
1140             // adjusted min, mid, and max inputs, respectively.
1141             SkString helperFunction;
1142             GrGLShaderVar helperArgs[] = {
1143                 GrGLShaderVar("minComp", kFloat_GrSLType),
1144                 GrGLShaderVar("midComp", kFloat_GrSLType),
1145                 GrGLShaderVar("maxComp", kFloat_GrSLType),
1146                 GrGLShaderVar("sat", kFloat_GrSLType),
1147             };
1148             static const char kHelperBody[] = "\tif (minComp < maxComp) {\n"
1149                                               "\t\tvec3 result;\n"
1150                                               "\t\tresult.r = 0.0;\n"
1151                                               "\t\tresult.g = sat * (midComp - minComp) / (maxComp - minComp);\n"
1152                                               "\t\tresult.b = sat;\n"
1153                                               "\t\treturn result;\n"
1154                                               "\t} else {\n"
1155                                               "\t\treturn vec3(0, 0, 0);\n"
1156                                               "\t}\n";
1157             builder->fsEmitFunction(kVec3f_GrSLType,
1158                                     "set_saturation_helper",
1159                                     SK_ARRAY_COUNT(helperArgs), helperArgs,
1160                                     kHelperBody,
1161                                     &helperFunction);
1162
1163             GrGLShaderVar setSatArgs[] = {
1164                 GrGLShaderVar("hueLumColor", kVec3f_GrSLType),
1165                 GrGLShaderVar("satColor", kVec3f_GrSLType),
1166             };
1167             const char* helpFunc = helperFunction.c_str();
1168             SkString setSatBody;
1169             setSatBody.appendf("\tfloat sat = %s(satColor);\n"
1170                                "\tif (hueLumColor.r <= hueLumColor.g) {\n"
1171                                "\t\tif (hueLumColor.g <= hueLumColor.b) {\n"
1172                                "\t\t\thueLumColor.rgb = %s(hueLumColor.r, hueLumColor.g, hueLumColor.b, sat);\n"
1173                                "\t\t} else if (hueLumColor.r <= hueLumColor.b) {\n"
1174                                "\t\t\thueLumColor.rbg = %s(hueLumColor.r, hueLumColor.b, hueLumColor.g, sat);\n"
1175                                "\t\t} else {\n"
1176                                "\t\t\thueLumColor.brg = %s(hueLumColor.b, hueLumColor.r, hueLumColor.g, sat);\n"
1177                                "\t\t}\n"
1178                                "\t} else if (hueLumColor.r <= hueLumColor.b) {\n"
1179                                "\t\thueLumColor.grb = %s(hueLumColor.g, hueLumColor.r, hueLumColor.b, sat);\n"
1180                                "\t} else if (hueLumColor.g <= hueLumColor.b) {\n"
1181                                "\t\thueLumColor.gbr = %s(hueLumColor.g, hueLumColor.b, hueLumColor.r, sat);\n"
1182                                "\t} else {\n"
1183                                "\t\thueLumColor.bgr = %s(hueLumColor.b, hueLumColor.g, hueLumColor.r, sat);\n"
1184                                "\t}\n"
1185                                "\treturn hueLumColor;\n",
1186                                getFunction.c_str(), helpFunc, helpFunc, helpFunc, helpFunc,
1187                                helpFunc, helpFunc);
1188             builder->fsEmitFunction(kVec3f_GrSLType,
1189                                     "set_saturation",
1190                                     SK_ARRAY_COUNT(setSatArgs), setSatArgs,
1191                                     setSatBody.c_str(),
1192                                     setSatFunction);
1193
1194         }
1195
1196         typedef GrGLEffect INHERITED;
1197     };
1198
1199     GR_DECLARE_EFFECT_TEST;
1200
1201 private:
1202     XferEffect(SkXfermode::Mode mode, GrTexture* background)
1203         : fMode(mode) {
1204         if (background) {
1205             fBackgroundTransform.reset(kLocal_GrCoordSet, background);
1206             this->addCoordTransform(&fBackgroundTransform);
1207             fBackgroundAccess.reset(background);
1208             this->addTextureAccess(&fBackgroundAccess);
1209         } else {
1210             this->setWillReadDstColor();
1211         }
1212     }
1213     virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE {
1214         const XferEffect& s = CastEffect<XferEffect>(other);
1215         return fMode == s.fMode &&
1216                fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture();
1217     }
1218
1219     SkXfermode::Mode fMode;
1220     GrCoordTransform fBackgroundTransform;
1221     GrTextureAccess  fBackgroundAccess;
1222
1223     typedef GrEffect INHERITED;
1224 };
1225
1226 GR_DEFINE_EFFECT_TEST(XferEffect);
1227 GrEffectRef* XferEffect::TestCreate(SkRandom* rand,
1228                                     GrContext*,
1229                                     const GrDrawTargetCaps&,
1230                                     GrTexture*[]) {
1231     int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLastSeparableMode);
1232
1233     AutoEffectUnref gEffect(SkNEW_ARGS(XferEffect, (static_cast<SkXfermode::Mode>(mode), NULL)));
1234     return CreateEffectRef(gEffect);
1235 }
1236
1237 #endif
1238
1239 ///////////////////////////////////////////////////////////////////////////////
1240 ///////////////////////////////////////////////////////////////////////////////
1241
1242 SkProcCoeffXfermode::SkProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
1243     uint32_t mode32 = buffer.read32() % SK_ARRAY_COUNT(gProcCoeffs);
1244     if (mode32 >= SK_ARRAY_COUNT(gProcCoeffs)) {
1245         // out of range, just set to something harmless
1246         mode32 = SkXfermode::kSrcOut_Mode;
1247     }
1248     fMode = (SkXfermode::Mode)mode32;
1249
1250     const ProcCoeff& rec = gProcCoeffs[fMode];
1251     fProc = rec.fProc;
1252     // these may be valid, or may be CANNOT_USE_COEFF
1253     fSrcCoeff = rec.fSC;
1254     fDstCoeff = rec.fDC;
1255 }
1256
1257 bool SkProcCoeffXfermode::asMode(Mode* mode) const {
1258     if (mode) {
1259         *mode = fMode;
1260     }
1261     return true;
1262 }
1263
1264 bool SkProcCoeffXfermode::asCoeff(Coeff* sc, Coeff* dc) const {
1265     if (CANNOT_USE_COEFF == fSrcCoeff) {
1266         return false;
1267     }
1268
1269     if (sc) {
1270         *sc = fSrcCoeff;
1271     }
1272     if (dc) {
1273         *dc = fDstCoeff;
1274     }
1275     return true;
1276 }
1277
1278 void SkProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1279                                  const SkPMColor* SK_RESTRICT src, int count,
1280                                  const SkAlpha* SK_RESTRICT aa) const {
1281     SkASSERT(dst && src && count >= 0);
1282
1283     SkXfermodeProc proc = fProc;
1284
1285     if (NULL != proc) {
1286         if (NULL == aa) {
1287             for (int i = count - 1; i >= 0; --i) {
1288                 dst[i] = proc(src[i], dst[i]);
1289             }
1290         } else {
1291             for (int i = count - 1; i >= 0; --i) {
1292                 unsigned a = aa[i];
1293                 if (0 != a) {
1294                     SkPMColor dstC = dst[i];
1295                     SkPMColor C = proc(src[i], dstC);
1296                     if (a != 0xFF) {
1297                         C = SkFourByteInterp(C, dstC, a);
1298                     }
1299                     dst[i] = C;
1300                 }
1301             }
1302         }
1303     }
1304 }
1305
1306 void SkProcCoeffXfermode::xfer16(uint16_t* SK_RESTRICT dst,
1307                                  const SkPMColor* SK_RESTRICT src, int count,
1308                                  const SkAlpha* SK_RESTRICT aa) const {
1309     SkASSERT(dst && src && count >= 0);
1310
1311     SkXfermodeProc proc = fProc;
1312
1313     if (NULL != proc) {
1314         if (NULL == aa) {
1315             for (int i = count - 1; i >= 0; --i) {
1316                 SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
1317                 dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC));
1318             }
1319         } else {
1320             for (int i = count - 1; i >= 0; --i) {
1321                 unsigned a = aa[i];
1322                 if (0 != a) {
1323                     SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
1324                     SkPMColor C = proc(src[i], dstC);
1325                     if (0xFF != a) {
1326                         C = SkFourByteInterp(C, dstC, a);
1327                     }
1328                     dst[i] = SkPixel32ToPixel16_ToU16(C);
1329                 }
1330             }
1331         }
1332     }
1333 }
1334
1335 void SkProcCoeffXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
1336                                  const SkPMColor* SK_RESTRICT src, int count,
1337                                  const SkAlpha* SK_RESTRICT aa) const {
1338     SkASSERT(dst && src && count >= 0);
1339
1340     SkXfermodeProc proc = fProc;
1341
1342     if (NULL != proc) {
1343         if (NULL == aa) {
1344             for (int i = count - 1; i >= 0; --i) {
1345                 SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT);
1346                 dst[i] = SkToU8(SkGetPackedA32(res));
1347             }
1348         } else {
1349             for (int i = count - 1; i >= 0; --i) {
1350                 unsigned a = aa[i];
1351                 if (0 != a) {
1352                     SkAlpha dstA = dst[i];
1353                     SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT);
1354                     unsigned A = SkGetPackedA32(res);
1355                     if (0xFF != a) {
1356                         A = SkAlphaBlend(A, dstA, SkAlpha255To256(a));
1357                     }
1358                     dst[i] = SkToU8(A);
1359                 }
1360             }
1361         }
1362     }
1363 }
1364
1365 #if SK_SUPPORT_GPU
1366 bool SkProcCoeffXfermode::asNewEffect(GrEffectRef** effect,
1367                                       GrTexture* background) const {
1368     if (XferEffect::IsSupportedMode(fMode)) {
1369         if (NULL != effect) {
1370             *effect = XferEffect::Create(fMode, background);
1371             SkASSERT(NULL != *effect);
1372         }
1373         return true;
1374     }
1375     return false;
1376 }
1377 #endif
1378
1379 void SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const {
1380     this->INHERITED::flatten(buffer);
1381     buffer.write32(fMode);
1382 }
1383
1384 const char* SkXfermode::ModeName(Mode mode) {
1385     SkASSERT((unsigned) mode <= (unsigned)kLastMode);
1386     const char* gModeStrings[] = {
1387         "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn",
1388         "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus",
1389         "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge",
1390         "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion",
1391         "Multiply", "Hue", "Saturation", "Color",  "Luminosity"
1392     };
1393     return gModeStrings[mode];
1394     SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gModeStrings) == kLastMode + 1, mode_count);
1395 }
1396
1397 #ifndef SK_IGNORE_TO_STRING
1398 void SkProcCoeffXfermode::toString(SkString* str) const {
1399     str->append("SkProcCoeffXfermode: ");
1400
1401     str->append("mode: ");
1402     str->append(ModeName(fMode));
1403
1404     static const char* gCoeffStrings[kCoeffCount] = {
1405         "Zero", "One", "SC", "ISC", "DC", "IDC", "SA", "ISA", "DA", "IDA"
1406     };
1407
1408     str->append(" src: ");
1409     if (CANNOT_USE_COEFF == fSrcCoeff) {
1410         str->append("can't use");
1411     } else {
1412         str->append(gCoeffStrings[fSrcCoeff]);
1413     }
1414
1415     str->append(" dst: ");
1416     if (CANNOT_USE_COEFF == fDstCoeff) {
1417         str->append("can't use");
1418     } else {
1419         str->append(gCoeffStrings[fDstCoeff]);
1420     }
1421 }
1422 #endif
1423
1424 ///////////////////////////////////////////////////////////////////////////////
1425
1426 class SkClearXfermode : public SkProcCoeffXfermode {
1427 public:
1428     static SkClearXfermode* Create(const ProcCoeff& rec) {
1429         return SkNEW_ARGS(SkClearXfermode, (rec));
1430     }
1431
1432     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1433     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1434
1435     SK_TO_STRING_OVERRIDE()
1436     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkClearXfermode)
1437
1438 private:
1439     SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {}
1440     SkClearXfermode(SkReadBuffer& buffer)
1441         : SkProcCoeffXfermode(buffer) {}
1442
1443     typedef SkProcCoeffXfermode INHERITED;
1444 };
1445
1446 void SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1447                              const SkPMColor* SK_RESTRICT, int count,
1448                              const SkAlpha* SK_RESTRICT aa) const {
1449     SkASSERT(dst && count >= 0);
1450
1451     if (NULL == aa) {
1452         memset(dst, 0, count << 2);
1453     } else {
1454         for (int i = count - 1; i >= 0; --i) {
1455             unsigned a = aa[i];
1456             if (0xFF == a) {
1457                 dst[i] = 0;
1458             } else if (a != 0) {
1459                 dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a));
1460             }
1461         }
1462     }
1463 }
1464 void SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
1465                              const SkPMColor* SK_RESTRICT, int count,
1466                              const SkAlpha* SK_RESTRICT aa) const {
1467     SkASSERT(dst && count >= 0);
1468
1469     if (NULL == aa) {
1470         memset(dst, 0, count);
1471     } else {
1472         for (int i = count - 1; i >= 0; --i) {
1473             unsigned a = aa[i];
1474             if (0xFF == a) {
1475                 dst[i] = 0;
1476             } else if (0 != a) {
1477                 dst[i] = SkAlphaMulAlpha(dst[i], 255 - a);
1478             }
1479         }
1480     }
1481 }
1482
1483 #ifndef SK_IGNORE_TO_STRING
1484 void SkClearXfermode::toString(SkString* str) const {
1485     this->INHERITED::toString(str);
1486 }
1487 #endif
1488
1489 ///////////////////////////////////////////////////////////////////////////////
1490
1491 class SkSrcXfermode : public SkProcCoeffXfermode {
1492 public:
1493     static SkSrcXfermode* Create(const ProcCoeff& rec) {
1494         return SkNEW_ARGS(SkSrcXfermode, (rec));
1495     }
1496
1497     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1498     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1499
1500     SK_TO_STRING_OVERRIDE()
1501     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSrcXfermode)
1502
1503 private:
1504     SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {}
1505     SkSrcXfermode(SkReadBuffer& buffer)
1506         : SkProcCoeffXfermode(buffer) {}
1507
1508     typedef SkProcCoeffXfermode INHERITED;
1509 };
1510
1511 void SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1512                            const SkPMColor* SK_RESTRICT src, int count,
1513                            const SkAlpha* SK_RESTRICT aa) const {
1514     SkASSERT(dst && src && count >= 0);
1515
1516     if (NULL == aa) {
1517         memcpy(dst, src, count << 2);
1518     } else {
1519         for (int i = count - 1; i >= 0; --i) {
1520             unsigned a = aa[i];
1521             if (a == 0xFF) {
1522                 dst[i] = src[i];
1523             } else if (a != 0) {
1524                 dst[i] = SkFourByteInterp(src[i], dst[i], a);
1525             }
1526         }
1527     }
1528 }
1529
1530 void SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
1531                            const SkPMColor* SK_RESTRICT src, int count,
1532                            const SkAlpha* SK_RESTRICT aa) const {
1533     SkASSERT(dst && src && count >= 0);
1534
1535     if (NULL == aa) {
1536         for (int i = count - 1; i >= 0; --i) {
1537             dst[i] = SkToU8(SkGetPackedA32(src[i]));
1538         }
1539     } else {
1540         for (int i = count - 1; i >= 0; --i) {
1541             unsigned a = aa[i];
1542             if (0 != a) {
1543                 unsigned srcA = SkGetPackedA32(src[i]);
1544                 if (a == 0xFF) {
1545                     dst[i] = SkToU8(srcA);
1546                 } else {
1547                     dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a));
1548                 }
1549             }
1550         }
1551     }
1552 }
1553 #ifndef SK_IGNORE_TO_STRING
1554 void SkSrcXfermode::toString(SkString* str) const {
1555     this->INHERITED::toString(str);
1556 }
1557 #endif
1558
1559 ///////////////////////////////////////////////////////////////////////////////
1560
1561 class SkDstInXfermode : public SkProcCoeffXfermode {
1562 public:
1563     static SkDstInXfermode* Create(const ProcCoeff& rec) {
1564         return SkNEW_ARGS(SkDstInXfermode, (rec));
1565     }
1566
1567     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1568
1569     SK_TO_STRING_OVERRIDE()
1570     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstInXfermode)
1571
1572 private:
1573     SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {}
1574     SkDstInXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {}
1575
1576     typedef SkProcCoeffXfermode INHERITED;
1577 };
1578
1579 void SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1580                              const SkPMColor* SK_RESTRICT src, int count,
1581                              const SkAlpha* SK_RESTRICT aa) const {
1582     SkASSERT(dst && src);
1583
1584     if (count <= 0) {
1585         return;
1586     }
1587     if (NULL != aa) {
1588         return this->INHERITED::xfer32(dst, src, count, aa);
1589     }
1590
1591     do {
1592         unsigned a = SkGetPackedA32(*src);
1593         *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a));
1594         dst++;
1595         src++;
1596     } while (--count != 0);
1597 }
1598
1599 #ifndef SK_IGNORE_TO_STRING
1600 void SkDstInXfermode::toString(SkString* str) const {
1601     this->INHERITED::toString(str);
1602 }
1603 #endif
1604
1605 ///////////////////////////////////////////////////////////////////////////////
1606
1607 class SkDstOutXfermode : public SkProcCoeffXfermode {
1608 public:
1609     static SkDstOutXfermode* Create(const ProcCoeff& rec) {
1610         return SkNEW_ARGS(SkDstOutXfermode, (rec));
1611     }
1612
1613     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1614
1615     SK_TO_STRING_OVERRIDE()
1616     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstOutXfermode)
1617
1618 private:
1619     SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {}
1620     SkDstOutXfermode(SkReadBuffer& buffer)
1621         : INHERITED(buffer) {}
1622
1623     typedef SkProcCoeffXfermode INHERITED;
1624 };
1625
1626 void SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1627                               const SkPMColor* SK_RESTRICT src, int count,
1628                               const SkAlpha* SK_RESTRICT aa) const {
1629     SkASSERT(dst && src);
1630
1631     if (count <= 0) {
1632         return;
1633     }
1634     if (NULL != aa) {
1635         return this->INHERITED::xfer32(dst, src, count, aa);
1636     }
1637
1638     do {
1639         unsigned a = SkGetPackedA32(*src);
1640         *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a));
1641         dst++;
1642         src++;
1643     } while (--count != 0);
1644 }
1645
1646 #ifndef SK_IGNORE_TO_STRING
1647 void SkDstOutXfermode::toString(SkString* str) const {
1648     this->INHERITED::toString(str);
1649 }
1650 #endif
1651
1652 ///////////////////////////////////////////////////////////////////////////////
1653
1654 SK_DECLARE_STATIC_MUTEX(gCachedXfermodesMutex);
1655 static SkXfermode* gCachedXfermodes[SkXfermode::kLastMode + 1];  // All NULL to start.
1656 static bool gXfermodeCached[SK_ARRAY_COUNT(gCachedXfermodes)];  // All false to start.
1657
1658 void SkXfermode::Term() {
1659     SkAutoMutexAcquire ac(gCachedXfermodesMutex);
1660
1661     for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) {
1662         SkSafeUnref(gCachedXfermodes[i]);
1663         gCachedXfermodes[i] = NULL;
1664     }
1665 }
1666
1667 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec,
1668                                                       SkXfermode::Mode mode);
1669 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode);
1670
1671
1672 static void create_mode(SkXfermode::Mode mode) {
1673     SkASSERT(NULL == gCachedXfermodes[mode]);
1674
1675     ProcCoeff rec = gProcCoeffs[mode];
1676     SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode);
1677     if (pp != NULL) {
1678         rec.fProc = pp;
1679     }
1680
1681     SkXfermode* xfer = NULL;
1682     // check if we have a platform optim for that
1683     SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode);
1684     if (xfm != NULL) {
1685         xfer = xfm;
1686     } else {
1687         // All modes can in theory be represented by the ProcCoeff rec, since
1688         // it contains function ptrs. However, a few modes are both simple and
1689         // commonly used, so we call those out for their own subclasses here.
1690         switch (mode) {
1691             case SkXfermode::kClear_Mode:
1692                 xfer = SkClearXfermode::Create(rec);
1693                 break;
1694             case SkXfermode::kSrc_Mode:
1695                 xfer = SkSrcXfermode::Create(rec);
1696                 break;
1697             case SkXfermode::kSrcOver_Mode:
1698                 SkASSERT(false);    // should not land here
1699                 break;
1700             case SkXfermode::kDstIn_Mode:
1701                 xfer = SkDstInXfermode::Create(rec);
1702                 break;
1703             case SkXfermode::kDstOut_Mode:
1704                 xfer = SkDstOutXfermode::Create(rec);
1705                 break;
1706             default:
1707                 // no special-case, just rely in the rec and its function-ptrs
1708                 xfer = SkProcCoeffXfermode::Create(rec, mode);
1709                 break;
1710         }
1711     }
1712     gCachedXfermodes[mode] = xfer;
1713 }
1714
1715 SkXfermode* SkXfermode::Create(Mode mode) {
1716     SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
1717     SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount);
1718
1719     if ((unsigned)mode >= kModeCount) {
1720         // report error
1721         return NULL;
1722     }
1723
1724     // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcover
1725     // so we can just return NULL from the factory.
1726     if (kSrcOver_Mode == mode) {
1727         return NULL;
1728     }
1729
1730     SkOnce(&gXfermodeCached[mode], &gCachedXfermodesMutex, create_mode, mode);
1731     SkXfermode* xfer = gCachedXfermodes[mode];
1732     SkASSERT(xfer != NULL);
1733     return SkSafeRef(xfer);
1734 }
1735
1736 SkXfermodeProc SkXfermode::GetProc(Mode mode) {
1737     SkXfermodeProc  proc = NULL;
1738     if ((unsigned)mode < kModeCount) {
1739         proc = gProcCoeffs[mode].fProc;
1740     }
1741     return proc;
1742 }
1743
1744 bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) {
1745     SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
1746
1747     if ((unsigned)mode >= (unsigned)kModeCount) {
1748         // illegal mode parameter
1749         return false;
1750     }
1751
1752     const ProcCoeff& rec = gProcCoeffs[mode];
1753
1754     if (CANNOT_USE_COEFF == rec.fSC) {
1755         return false;
1756     }
1757
1758     SkASSERT(CANNOT_USE_COEFF != rec.fDC);
1759     if (src) {
1760         *src = rec.fSC;
1761     }
1762     if (dst) {
1763         *dst = rec.fDC;
1764     }
1765     return true;
1766 }
1767
1768 bool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) {
1769     if (NULL == xfer) {
1770         if (mode) {
1771             *mode = kSrcOver_Mode;
1772         }
1773         return true;
1774     }
1775     return xfer->asMode(mode);
1776 }
1777
1778 bool SkXfermode::AsCoeff(const SkXfermode* xfer, Coeff* src, Coeff* dst) {
1779     if (NULL == xfer) {
1780         return ModeAsCoeff(kSrcOver_Mode, src, dst);
1781     }
1782     return xfer->asCoeff(src, dst);
1783 }
1784
1785 bool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) {
1786     // if xfer==null then the mode is srcover
1787     Mode m = kSrcOver_Mode;
1788     if (xfer && !xfer->asMode(&m)) {
1789         return false;
1790     }
1791     return mode == m;
1792 }
1793
1794 ///////////////////////////////////////////////////////////////////////////////
1795 //////////// 16bit xfermode procs
1796
1797 #ifdef SK_DEBUG
1798 static bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; }
1799 static bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; }
1800 #endif
1801
1802 static uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) {
1803     SkASSERT(require_255(src));
1804     return SkPixel32ToPixel16(src);
1805 }
1806
1807 static uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) {
1808     return dst;
1809 }
1810
1811 static uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) {
1812     SkASSERT(require_0(src));
1813     return dst;
1814 }
1815
1816 static uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) {
1817     SkASSERT(require_255(src));
1818     return SkPixel32ToPixel16(src);
1819 }
1820
1821 static uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) {
1822     SkASSERT(require_0(src));
1823     return dst;
1824 }
1825
1826 static uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) {
1827     SkASSERT(require_255(src));
1828     return dst;
1829 }
1830
1831 static uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) {
1832     SkASSERT(require_255(src));
1833     return SkPixel32ToPixel16(src);
1834 }
1835
1836 static uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) {
1837     SkASSERT(require_255(src));
1838     return dst;
1839 }
1840
1841 static uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) {
1842     SkASSERT(require_0(src));
1843     return dst;
1844 }
1845
1846 static uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) {
1847     unsigned isa = 255 - SkGetPackedA32(src);
1848
1849     return SkPackRGB16(
1850            SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa),
1851            SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa),
1852            SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa));
1853 }
1854
1855 static uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) {
1856     SkASSERT(require_0(src));
1857     return dst;
1858 }
1859
1860 static uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) {
1861     SkASSERT(require_255(src));
1862     return SkPixel32ToPixel16(src);
1863 }
1864
1865 static uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) {
1866     SkASSERT(require_255(src));
1867     return dst;
1868 }
1869
1870 /*********
1871     darken and lighten boil down to this.
1872
1873     darken  = (1 - Sa) * Dc + min(Sc, Dc)
1874     lighten = (1 - Sa) * Dc + max(Sc, Dc)
1875
1876     if (Sa == 0) these become
1877         darken  = Dc + min(0, Dc) = 0
1878         lighten = Dc + max(0, Dc) = Dc
1879
1880     if (Sa == 1) these become
1881         darken  = min(Sc, Dc)
1882         lighten = max(Sc, Dc)
1883 */
1884
1885 static uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) {
1886     SkASSERT(require_0(src));
1887     return 0;
1888 }
1889
1890 static uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) {
1891     SkASSERT(require_255(src));
1892     unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst));
1893     unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst));
1894     unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst));
1895     return SkPackRGB16(r, g, b);
1896 }
1897
1898 static uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) {
1899     SkASSERT(require_0(src));
1900     return dst;
1901 }
1902
1903 static uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) {
1904     SkASSERT(require_255(src));
1905     unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst));
1906     unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst));
1907     unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst));
1908     return SkPackRGB16(r, g, b);
1909 }
1910
1911 struct Proc16Rec {
1912     SkXfermodeProc16    fProc16_0;
1913     SkXfermodeProc16    fProc16_255;
1914     SkXfermodeProc16    fProc16_General;
1915 };
1916
1917 static const Proc16Rec gModeProcs16[] = {
1918     { NULL,                 NULL,                   NULL            }, // CLEAR
1919     { NULL,                 src_modeproc16_255,     NULL            },
1920     { dst_modeproc16,       dst_modeproc16,         dst_modeproc16  },
1921     { srcover_modeproc16_0, srcover_modeproc16_255, NULL            },
1922     { dstover_modeproc16_0, dstover_modeproc16_255, NULL            },
1923     { NULL,                 srcin_modeproc16_255,   NULL            },
1924     { NULL,                 dstin_modeproc16_255,   NULL            },
1925     { NULL,                 NULL,                   NULL            },// SRC_OUT
1926     { dstout_modeproc16_0,  NULL,                   NULL            },
1927     { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16  },
1928     { NULL,                 dstatop_modeproc16_255, NULL            },
1929     { NULL,                 NULL,                   NULL            }, // XOR
1930
1931     { NULL,                 NULL,                   NULL            }, // plus
1932     { NULL,                 NULL,                   NULL            }, // modulate
1933     { NULL,                 NULL,                   NULL            }, // screen
1934     { NULL,                 NULL,                   NULL            }, // overlay
1935     { darken_modeproc16_0,  darken_modeproc16_255,  NULL            }, // darken
1936     { lighten_modeproc16_0, lighten_modeproc16_255, NULL            }, // lighten
1937     { NULL,                 NULL,                   NULL            }, // colordodge
1938     { NULL,                 NULL,                   NULL            }, // colorburn
1939     { NULL,                 NULL,                   NULL            }, // hardlight
1940     { NULL,                 NULL,                   NULL            }, // softlight
1941     { NULL,                 NULL,                   NULL            }, // difference
1942     { NULL,                 NULL,                   NULL            }, // exclusion
1943     { NULL,                 NULL,                   NULL            }, // multiply
1944     { NULL,                 NULL,                   NULL            }, // hue
1945     { NULL,                 NULL,                   NULL            }, // saturation
1946     { NULL,                 NULL,                   NULL            }, // color
1947     { NULL,                 NULL,                   NULL            }, // luminosity
1948 };
1949
1950 SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) {
1951     SkXfermodeProc16  proc16 = NULL;
1952     if ((unsigned)mode < kModeCount) {
1953         const Proc16Rec& rec = gModeProcs16[mode];
1954         unsigned a = SkColorGetA(srcColor);
1955
1956         if (0 == a) {
1957             proc16 = rec.fProc16_0;
1958         } else if (255 == a) {
1959             proc16 = rec.fProc16_255;
1960         } else {
1961             proc16 = rec.fProc16_General;
1962         }
1963     }
1964     return proc16;
1965 }
1966
1967 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
1968     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
1969     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode)
1970     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode)
1971     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode)
1972     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode)
1973 #if !SK_ARM_NEON_IS_NONE
1974     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNEONProcCoeffXfermode)
1975 #endif
1976 #if defined(SK_CPU_X86) && !defined(SK_BUILD_FOR_IOS)
1977     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSSE2ProcCoeffXfermode)
1978 #endif
1979 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END