Upstream version 5.34.104.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 #ifdef SK_DEVELOPER
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 #ifdef SK_DEVELOPER
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     SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {}
1448
1449     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1450     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1451
1452     SK_DEVELOPER_TO_STRING()
1453     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkClearXfermode)
1454
1455 private:
1456     SkClearXfermode(SkReadBuffer& buffer)
1457         : SkProcCoeffXfermode(buffer) {}
1458
1459     typedef SkProcCoeffXfermode INHERITED;
1460 };
1461
1462 void SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1463                              const SkPMColor* SK_RESTRICT, int count,
1464                              const SkAlpha* SK_RESTRICT aa) const {
1465     SkASSERT(dst && count >= 0);
1466
1467     if (NULL == aa) {
1468         memset(dst, 0, count << 2);
1469     } else {
1470         for (int i = count - 1; i >= 0; --i) {
1471             unsigned a = aa[i];
1472             if (0xFF == a) {
1473                 dst[i] = 0;
1474             } else if (a != 0) {
1475                 dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a));
1476             }
1477         }
1478     }
1479 }
1480 void SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
1481                              const SkPMColor* SK_RESTRICT, int count,
1482                              const SkAlpha* SK_RESTRICT aa) const {
1483     SkASSERT(dst && count >= 0);
1484
1485     if (NULL == aa) {
1486         memset(dst, 0, count);
1487     } else {
1488         for (int i = count - 1; i >= 0; --i) {
1489             unsigned a = aa[i];
1490             if (0xFF == a) {
1491                 dst[i] = 0;
1492             } else if (0 != a) {
1493                 dst[i] = SkAlphaMulAlpha(dst[i], 255 - a);
1494             }
1495         }
1496     }
1497 }
1498
1499 #ifdef SK_DEVELOPER
1500 void SkClearXfermode::toString(SkString* str) const {
1501     this->INHERITED::toString(str);
1502 }
1503 #endif
1504
1505 ///////////////////////////////////////////////////////////////////////////////
1506
1507 class SkSrcXfermode : public SkProcCoeffXfermode {
1508 public:
1509     SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {}
1510
1511     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1512     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1513
1514     SK_DEVELOPER_TO_STRING()
1515     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSrcXfermode)
1516
1517 private:
1518     SkSrcXfermode(SkReadBuffer& buffer)
1519         : SkProcCoeffXfermode(buffer) {}
1520
1521     typedef SkProcCoeffXfermode INHERITED;
1522 };
1523
1524 void SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1525                            const SkPMColor* SK_RESTRICT src, int count,
1526                            const SkAlpha* SK_RESTRICT aa) const {
1527     SkASSERT(dst && src && count >= 0);
1528
1529     if (NULL == aa) {
1530         memcpy(dst, src, count << 2);
1531     } else {
1532         for (int i = count - 1; i >= 0; --i) {
1533             unsigned a = aa[i];
1534             if (a == 0xFF) {
1535                 dst[i] = src[i];
1536             } else if (a != 0) {
1537                 dst[i] = SkFourByteInterp(src[i], dst[i], a);
1538             }
1539         }
1540     }
1541 }
1542
1543 void SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
1544                            const SkPMColor* SK_RESTRICT src, int count,
1545                            const SkAlpha* SK_RESTRICT aa) const {
1546     SkASSERT(dst && src && count >= 0);
1547
1548     if (NULL == aa) {
1549         for (int i = count - 1; i >= 0; --i) {
1550             dst[i] = SkToU8(SkGetPackedA32(src[i]));
1551         }
1552     } else {
1553         for (int i = count - 1; i >= 0; --i) {
1554             unsigned a = aa[i];
1555             if (0 != a) {
1556                 unsigned srcA = SkGetPackedA32(src[i]);
1557                 if (a == 0xFF) {
1558                     dst[i] = SkToU8(srcA);
1559                 } else {
1560                     dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a));
1561                 }
1562             }
1563         }
1564     }
1565 }
1566 #ifdef SK_DEVELOPER
1567 void SkSrcXfermode::toString(SkString* str) const {
1568     this->INHERITED::toString(str);
1569 }
1570 #endif
1571
1572 ///////////////////////////////////////////////////////////////////////////////
1573
1574 class SkDstInXfermode : public SkProcCoeffXfermode {
1575 public:
1576     SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {}
1577
1578     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1579
1580     SK_DEVELOPER_TO_STRING()
1581     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstInXfermode)
1582
1583 private:
1584     SkDstInXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {}
1585
1586     typedef SkProcCoeffXfermode INHERITED;
1587 };
1588
1589 void SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1590                              const SkPMColor* SK_RESTRICT src, int count,
1591                              const SkAlpha* SK_RESTRICT aa) const {
1592     SkASSERT(dst && src);
1593
1594     if (count <= 0) {
1595         return;
1596     }
1597     if (NULL != aa) {
1598         return this->INHERITED::xfer32(dst, src, count, aa);
1599     }
1600
1601     do {
1602         unsigned a = SkGetPackedA32(*src);
1603         *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a));
1604         dst++;
1605         src++;
1606     } while (--count != 0);
1607 }
1608
1609 #ifdef SK_DEVELOPER
1610 void SkDstInXfermode::toString(SkString* str) const {
1611     this->INHERITED::toString(str);
1612 }
1613 #endif
1614
1615 ///////////////////////////////////////////////////////////////////////////////
1616
1617 class SkDstOutXfermode : public SkProcCoeffXfermode {
1618 public:
1619     SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {}
1620
1621     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1622
1623     SK_DEVELOPER_TO_STRING()
1624     SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDstOutXfermode)
1625
1626 private:
1627     SkDstOutXfermode(SkReadBuffer& buffer)
1628         : INHERITED(buffer) {}
1629
1630     typedef SkProcCoeffXfermode INHERITED;
1631 };
1632
1633 void SkDstOutXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1634                               const SkPMColor* SK_RESTRICT src, int count,
1635                               const SkAlpha* SK_RESTRICT aa) const {
1636     SkASSERT(dst && src);
1637
1638     if (count <= 0) {
1639         return;
1640     }
1641     if (NULL != aa) {
1642         return this->INHERITED::xfer32(dst, src, count, aa);
1643     }
1644
1645     do {
1646         unsigned a = SkGetPackedA32(*src);
1647         *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a));
1648         dst++;
1649         src++;
1650     } while (--count != 0);
1651 }
1652
1653 #ifdef SK_DEVELOPER
1654 void SkDstOutXfermode::toString(SkString* str) const {
1655     this->INHERITED::toString(str);
1656 }
1657 #endif
1658
1659 ///////////////////////////////////////////////////////////////////////////////
1660
1661 SK_DECLARE_STATIC_MUTEX(gCachedXfermodesMutex);
1662 static SkXfermode* gCachedXfermodes[SkXfermode::kLastMode + 1];
1663
1664 void SkXfermode::Term() {
1665     SkAutoMutexAcquire ac(gCachedXfermodesMutex);
1666
1667     for (size_t i = 0; i < SK_ARRAY_COUNT(gCachedXfermodes); ++i) {
1668         SkSafeUnref(gCachedXfermodes[i]);
1669         gCachedXfermodes[i] = NULL;
1670     }
1671 }
1672
1673 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec,
1674                                                       SkXfermode::Mode mode);
1675 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode);
1676
1677 SkXfermode* SkXfermode::Create(Mode mode) {
1678     SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
1679     SkASSERT(SK_ARRAY_COUNT(gCachedXfermodes) == kModeCount);
1680
1681     if ((unsigned)mode >= kModeCount) {
1682         // report error
1683         return NULL;
1684     }
1685
1686     // Skia's "defaut" mode is srcover. NULL in SkPaint is interpreted as srcover
1687     // so we can just return NULL from the factory.
1688     if (kSrcOver_Mode == mode) {
1689         return NULL;
1690     }
1691
1692     // guard our access to gCachedXfermodes, since we may write into it
1693     SkAutoMutexAcquire ac(gCachedXfermodesMutex);
1694
1695     SkXfermode* xfer = gCachedXfermodes[mode];
1696     if (NULL == xfer) {
1697         ProcCoeff rec = gProcCoeffs[mode];
1698
1699         SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode);
1700
1701         if (pp != NULL) {
1702             rec.fProc = pp;
1703         }
1704
1705         // check if we have a platform optim for that
1706         SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode);
1707         if (xfm != NULL) {
1708             xfer = xfm;
1709         } else {
1710             // All modes can in theory be represented by the ProcCoeff rec, since
1711             // it contains function ptrs. However, a few modes are both simple and
1712             // commonly used, so we call those out for their own subclasses here.
1713             switch (mode) {
1714                 case kClear_Mode:
1715                     xfer = SkNEW_ARGS(SkClearXfermode, (rec));
1716                     break;
1717                 case kSrc_Mode:
1718                     xfer = SkNEW_ARGS(SkSrcXfermode, (rec));
1719                     break;
1720                 case kSrcOver_Mode:
1721                     SkASSERT(false);    // should not land here
1722                     break;
1723                 case kDstIn_Mode:
1724                     xfer = SkNEW_ARGS(SkDstInXfermode, (rec));
1725                     break;
1726                 case kDstOut_Mode:
1727                     xfer = SkNEW_ARGS(SkDstOutXfermode, (rec));
1728                     break;
1729                 default:
1730                     // no special-case, just rely in the rec and its function-ptrs
1731                     xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode));
1732                     break;
1733             }
1734         }
1735         gCachedXfermodes[mode] = xfer;
1736     }
1737     return SkSafeRef(xfer);
1738 }
1739
1740 SkXfermodeProc SkXfermode::GetProc(Mode mode) {
1741     SkXfermodeProc  proc = NULL;
1742     if ((unsigned)mode < kModeCount) {
1743         proc = gProcCoeffs[mode].fProc;
1744     }
1745     return proc;
1746 }
1747
1748 bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) {
1749     SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
1750
1751     if ((unsigned)mode >= (unsigned)kModeCount) {
1752         // illegal mode parameter
1753         return false;
1754     }
1755
1756     const ProcCoeff& rec = gProcCoeffs[mode];
1757
1758     if (CANNOT_USE_COEFF == rec.fSC) {
1759         return false;
1760     }
1761
1762     SkASSERT(CANNOT_USE_COEFF != rec.fDC);
1763     if (src) {
1764         *src = rec.fSC;
1765     }
1766     if (dst) {
1767         *dst = rec.fDC;
1768     }
1769     return true;
1770 }
1771
1772 bool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) {
1773     if (NULL == xfer) {
1774         if (mode) {
1775             *mode = kSrcOver_Mode;
1776         }
1777         return true;
1778     }
1779     return xfer->asMode(mode);
1780 }
1781
1782 bool SkXfermode::AsCoeff(const SkXfermode* xfer, Coeff* src, Coeff* dst) {
1783     if (NULL == xfer) {
1784         return ModeAsCoeff(kSrcOver_Mode, src, dst);
1785     }
1786     return xfer->asCoeff(src, dst);
1787 }
1788
1789 bool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) {
1790     // if xfer==null then the mode is srcover
1791     Mode m = kSrcOver_Mode;
1792     if (xfer && !xfer->asMode(&m)) {
1793         return false;
1794     }
1795     return mode == m;
1796 }
1797
1798 ///////////////////////////////////////////////////////////////////////////////
1799 //////////// 16bit xfermode procs
1800
1801 #ifdef SK_DEBUG
1802 static bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; }
1803 static bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; }
1804 #endif
1805
1806 static uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) {
1807     SkASSERT(require_255(src));
1808     return SkPixel32ToPixel16(src);
1809 }
1810
1811 static uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) {
1812     return dst;
1813 }
1814
1815 static uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) {
1816     SkASSERT(require_0(src));
1817     return dst;
1818 }
1819
1820 static uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) {
1821     SkASSERT(require_255(src));
1822     return SkPixel32ToPixel16(src);
1823 }
1824
1825 static uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) {
1826     SkASSERT(require_0(src));
1827     return dst;
1828 }
1829
1830 static uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) {
1831     SkASSERT(require_255(src));
1832     return dst;
1833 }
1834
1835 static uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) {
1836     SkASSERT(require_255(src));
1837     return SkPixel32ToPixel16(src);
1838 }
1839
1840 static uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) {
1841     SkASSERT(require_255(src));
1842     return dst;
1843 }
1844
1845 static uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) {
1846     SkASSERT(require_0(src));
1847     return dst;
1848 }
1849
1850 static uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) {
1851     unsigned isa = 255 - SkGetPackedA32(src);
1852
1853     return SkPackRGB16(
1854            SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa),
1855            SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa),
1856            SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa));
1857 }
1858
1859 static uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) {
1860     SkASSERT(require_0(src));
1861     return dst;
1862 }
1863
1864 static uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) {
1865     SkASSERT(require_255(src));
1866     return SkPixel32ToPixel16(src);
1867 }
1868
1869 static uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) {
1870     SkASSERT(require_255(src));
1871     return dst;
1872 }
1873
1874 /*********
1875     darken and lighten boil down to this.
1876
1877     darken  = (1 - Sa) * Dc + min(Sc, Dc)
1878     lighten = (1 - Sa) * Dc + max(Sc, Dc)
1879
1880     if (Sa == 0) these become
1881         darken  = Dc + min(0, Dc) = 0
1882         lighten = Dc + max(0, Dc) = Dc
1883
1884     if (Sa == 1) these become
1885         darken  = min(Sc, Dc)
1886         lighten = max(Sc, Dc)
1887 */
1888
1889 static uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) {
1890     SkASSERT(require_0(src));
1891     return 0;
1892 }
1893
1894 static uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) {
1895     SkASSERT(require_255(src));
1896     unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst));
1897     unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst));
1898     unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst));
1899     return SkPackRGB16(r, g, b);
1900 }
1901
1902 static uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) {
1903     SkASSERT(require_0(src));
1904     return dst;
1905 }
1906
1907 static uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) {
1908     SkASSERT(require_255(src));
1909     unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst));
1910     unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst));
1911     unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst));
1912     return SkPackRGB16(r, g, b);
1913 }
1914
1915 struct Proc16Rec {
1916     SkXfermodeProc16    fProc16_0;
1917     SkXfermodeProc16    fProc16_255;
1918     SkXfermodeProc16    fProc16_General;
1919 };
1920
1921 static const Proc16Rec gModeProcs16[] = {
1922     { NULL,                 NULL,                   NULL            }, // CLEAR
1923     { NULL,                 src_modeproc16_255,     NULL            },
1924     { dst_modeproc16,       dst_modeproc16,         dst_modeproc16  },
1925     { srcover_modeproc16_0, srcover_modeproc16_255, NULL            },
1926     { dstover_modeproc16_0, dstover_modeproc16_255, NULL            },
1927     { NULL,                 srcin_modeproc16_255,   NULL            },
1928     { NULL,                 dstin_modeproc16_255,   NULL            },
1929     { NULL,                 NULL,                   NULL            },// SRC_OUT
1930     { dstout_modeproc16_0,  NULL,                   NULL            },
1931     { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16  },
1932     { NULL,                 dstatop_modeproc16_255, NULL            },
1933     { NULL,                 NULL,                   NULL            }, // XOR
1934
1935     { NULL,                 NULL,                   NULL            }, // plus
1936     { NULL,                 NULL,                   NULL            }, // modulate
1937     { NULL,                 NULL,                   NULL            }, // screen
1938     { NULL,                 NULL,                   NULL            }, // overlay
1939     { darken_modeproc16_0,  darken_modeproc16_255,  NULL            }, // darken
1940     { lighten_modeproc16_0, lighten_modeproc16_255, NULL            }, // lighten
1941     { NULL,                 NULL,                   NULL            }, // colordodge
1942     { NULL,                 NULL,                   NULL            }, // colorburn
1943     { NULL,                 NULL,                   NULL            }, // hardlight
1944     { NULL,                 NULL,                   NULL            }, // softlight
1945     { NULL,                 NULL,                   NULL            }, // difference
1946     { NULL,                 NULL,                   NULL            }, // exclusion
1947     { NULL,                 NULL,                   NULL            }, // multiply
1948     { NULL,                 NULL,                   NULL            }, // hue
1949     { NULL,                 NULL,                   NULL            }, // saturation
1950     { NULL,                 NULL,                   NULL            }, // color
1951     { NULL,                 NULL,                   NULL            }, // luminosity
1952 };
1953
1954 SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) {
1955     SkXfermodeProc16  proc16 = NULL;
1956     if ((unsigned)mode < kModeCount) {
1957         const Proc16Rec& rec = gModeProcs16[mode];
1958         unsigned a = SkColorGetA(srcColor);
1959
1960         if (0 == a) {
1961             proc16 = rec.fProc16_0;
1962         } else if (255 == a) {
1963             proc16 = rec.fProc16_255;
1964         } else {
1965             proc16 = rec.fProc16_General;
1966         }
1967     }
1968     return proc16;
1969 }
1970
1971 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
1972     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
1973     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkClearXfermode)
1974     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSrcXfermode)
1975     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstInXfermode)
1976     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDstOutXfermode)
1977 #if !SK_ARM_NEON_IS_NONE
1978     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkNEONProcCoeffXfermode)
1979 #endif
1980 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END