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