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