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