Update To 11.40.268.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::asFragmentProcessor(GrFragmentProcessor**, GrTexture*) const {
680     return false;
681 }
682
683 bool SkXfermode::asFragmentProcessorOrCoeff(SkXfermode* xfermode, GrFragmentProcessor** fp,
684                                             Coeff* src, Coeff* dst, GrTexture* background) {
685     if (NULL == xfermode) {
686         return ModeAsCoeff(kSrcOver_Mode, src, dst);
687     } else if (xfermode->asCoeff(src, dst)) {
688         return true;
689     } else {
690         return xfermode->asFragmentProcessor(fp, background);
691     }
692 }
693
694 SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) const{
695     // no-op. subclasses should override this
696     return dst;
697 }
698
699 void SkXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
700                         const SkPMColor* SK_RESTRICT src, int count,
701                         const SkAlpha* SK_RESTRICT aa) const {
702     SkASSERT(dst && src && count >= 0);
703
704     if (NULL == aa) {
705         for (int i = count - 1; i >= 0; --i) {
706             dst[i] = this->xferColor(src[i], dst[i]);
707         }
708     } else {
709         for (int i = count - 1; i >= 0; --i) {
710             unsigned a = aa[i];
711             if (0 != a) {
712                 SkPMColor dstC = dst[i];
713                 SkPMColor C = this->xferColor(src[i], dstC);
714                 if (0xFF != a) {
715                     C = SkFourByteInterp(C, dstC, a);
716                 }
717                 dst[i] = C;
718             }
719         }
720     }
721 }
722
723 void SkXfermode::xfer16(uint16_t* dst,
724                         const SkPMColor* SK_RESTRICT src, int count,
725                         const SkAlpha* SK_RESTRICT aa) const {
726     SkASSERT(dst && src && count >= 0);
727
728     if (NULL == aa) {
729         for (int i = count - 1; i >= 0; --i) {
730             SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
731             dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC));
732         }
733     } else {
734         for (int i = count - 1; i >= 0; --i) {
735             unsigned a = aa[i];
736             if (0 != a) {
737                 SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
738                 SkPMColor C = this->xferColor(src[i], dstC);
739                 if (0xFF != a) {
740                     C = SkFourByteInterp(C, dstC, a);
741                 }
742                 dst[i] = SkPixel32ToPixel16_ToU16(C);
743             }
744         }
745     }
746 }
747
748 void SkXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
749                         const SkPMColor src[], int count,
750                         const SkAlpha* SK_RESTRICT aa) const {
751     SkASSERT(dst && src && count >= 0);
752
753     if (NULL == aa) {
754         for (int i = count - 1; i >= 0; --i) {
755             SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT));
756             dst[i] = SkToU8(SkGetPackedA32(res));
757         }
758     } else {
759         for (int i = count - 1; i >= 0; --i) {
760             unsigned a = aa[i];
761             if (0 != a) {
762                 SkAlpha dstA = dst[i];
763                 unsigned A = SkGetPackedA32(this->xferColor(src[i],
764                                             (SkPMColor)(dstA << SK_A32_SHIFT)));
765                 if (0xFF != a) {
766                     A = SkAlphaBlend(A, dstA, SkAlpha255To256(a));
767                 }
768                 dst[i] = SkToU8(A);
769             }
770         }
771     }
772 }
773
774 //////////////////////////////////////////////////////////////////////////////
775
776 #if SK_SUPPORT_GPU
777
778 #include "GrFragmentProcessor.h"
779 #include "GrCoordTransform.h"
780 #include "GrProcessorUnitTest.h"
781 #include "GrTBackendProcessorFactory.h"
782 #include "gl/GrGLProcessor.h"
783 #include "gl/builders/GrGLProgramBuilder.h"
784
785 /**
786  * GrProcessor that implements the all the separable xfer modes that cannot be expressed as Coeffs.
787  */
788 class XferEffect : public GrFragmentProcessor {
789 public:
790     static bool IsSupportedMode(SkXfermode::Mode mode) {
791         return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMode;
792     }
793
794     static GrFragmentProcessor* Create(SkXfermode::Mode mode, GrTexture* background) {
795         if (!IsSupportedMode(mode)) {
796             return NULL;
797         } else {
798             return SkNEW_ARGS(XferEffect, (mode, background));
799         }
800     }
801
802     virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERRIDE {
803         return GrTBackendFragmentProcessorFactory<XferEffect>::getInstance();
804     }
805
806     static const char* Name() { return "XferEffect"; }
807
808     SkXfermode::Mode mode() const { return fMode; }
809     const GrTextureAccess&  backgroundAccess() const { return fBackgroundAccess; }
810
811     class GLProcessor : public GrGLFragmentProcessor {
812     public:
813         GLProcessor(const GrBackendProcessorFactory& factory, const GrProcessor&)
814             : INHERITED(factory) {
815         }
816         virtual void emitCode(GrGLFPBuilder* builder,
817                               const GrFragmentProcessor& fp,
818                               const GrProcessorKey& key,
819                               const char* outputColor,
820                               const char* inputColor,
821                               const TransformedCoordsArray& coords,
822                               const TextureSamplerArray& samplers) SK_OVERRIDE {
823             SkXfermode::Mode mode = fp.cast<XferEffect>().mode();
824             const GrTexture* backgroundTex =
825                     fp.cast<XferEffect>().backgroundAccess().getTexture();
826             GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
827             const char* dstColor;
828             if (backgroundTex) {
829                 dstColor = "bgColor";
830                 fsBuilder->codeAppendf("\t\tvec4 %s = ", dstColor);
831                 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0].getType());
832                 fsBuilder->codeAppendf(";\n");
833             } else {
834                 dstColor = fsBuilder->dstColor();
835             }
836             SkASSERT(dstColor);
837
838             // We don't try to optimize for this case at all
839             if (NULL == inputColor) {
840                 fsBuilder->codeAppendf("\t\tconst vec4 ones = vec4(1);\n");
841                 inputColor = "ones";
842             }
843             fsBuilder->codeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode));
844
845             // These all perform src-over on the alpha channel.
846             fsBuilder->codeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n",
847                                     outputColor, inputColor, inputColor, dstColor);
848
849             switch (mode) {
850                 case SkXfermode::kOverlay_Mode:
851                     // Overlay is Hard-Light with the src and dst reversed
852                     HardLight(fsBuilder, outputColor, dstColor, inputColor);
853                     break;
854                 case SkXfermode::kDarken_Mode:
855                     fsBuilder->codeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, "
856                                                             "(1.0 - %s.a) * %s.rgb + %s.rgb);\n",
857                                             outputColor,
858                                             inputColor, dstColor, inputColor,
859                                             dstColor, inputColor, dstColor);
860                     break;
861                 case SkXfermode::kLighten_Mode:
862                     fsBuilder->codeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, "
863                                                             "(1.0 - %s.a) * %s.rgb + %s.rgb);\n",
864                                             outputColor,
865                                             inputColor, dstColor, inputColor,
866                                             dstColor, inputColor, dstColor);
867                     break;
868                 case SkXfermode::kColorDodge_Mode:
869                     ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'r');
870                     ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'g');
871                     ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstColor, 'b');
872                     break;
873                 case SkXfermode::kColorBurn_Mode:
874                     ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'r');
875                     ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'g');
876                     ColorBurnComponent(fsBuilder, outputColor, inputColor, dstColor, 'b');
877                     break;
878                 case SkXfermode::kHardLight_Mode:
879                     HardLight(fsBuilder, outputColor, inputColor, dstColor);
880                     break;
881                 case SkXfermode::kSoftLight_Mode:
882                     fsBuilder->codeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor);
883                     fsBuilder->codeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor);
884                     fsBuilder->codeAppendf("\t\t} else {\n");
885                     SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'r');
886                     SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'g');
887                     SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputColor, dstColor, 'b');
888                     fsBuilder->codeAppendf("\t\t}\n");
889                     break;
890                 case SkXfermode::kDifference_Mode:
891                     fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -"
892                                                        "2.0 * min(%s.rgb * %s.a, %s.rgb * %s.a);\n",
893                                            outputColor, inputColor, dstColor, inputColor, dstColor,
894                                            dstColor, inputColor);
895                     break;
896                 case SkXfermode::kExclusion_Mode:
897                     fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - "
898                                                         "2.0 * %s.rgb * %s.rgb;\n",
899                                            outputColor, dstColor, inputColor, dstColor, inputColor);
900                     break;
901                 case SkXfermode::kMultiply_Mode:
902                     fsBuilder->codeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + "
903                                                         "(1.0 - %s.a) * %s.rgb + "
904                                                          "%s.rgb * %s.rgb;\n",
905                                            outputColor, inputColor, dstColor, dstColor, inputColor,
906                                            inputColor, dstColor);
907                     break;
908                 case SkXfermode::kHue_Mode: {
909                     //  SetLum(SetSat(S * Da, Sat(D * Sa)), Sa*Da, D*Sa) + (1 - Sa) * D + (1 - Da) * S
910                     SkString setSat, setLum;
911                     AddSatFunction(fsBuilder, &setSat);
912                     AddLumFunction(fsBuilder, &setLum);
913                     fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
914                                            dstColor, inputColor);
915                     fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rgb), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
916                                            outputColor, setLum.c_str(), setSat.c_str(), inputColor,
917                                            dstColor);
918                     fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
919                                            outputColor, inputColor, dstColor, dstColor, inputColor);
920                     break;
921                 }
922                 case SkXfermode::kSaturation_Mode: {
923                     // SetLum(SetSat(D * Sa, Sat(S * Da)), Sa*Da, D*Sa)) + (1 - Sa) * D + (1 - Da) * S
924                     SkString setSat, setLum;
925                     AddSatFunction(fsBuilder, &setSat);
926                     AddLumFunction(fsBuilder, &setLum);
927                     fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n",
928                                            dstColor, inputColor);
929                     fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
930                                            outputColor, setLum.c_str(), setSat.c_str(), inputColor,
931                                            dstColor);
932                     fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
933                                            outputColor, inputColor, dstColor, dstColor, inputColor);
934                     break;
935                 }
936                 case SkXfermode::kColor_Mode: {
937                     //  SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S
938                     SkString setLum;
939                     AddLumFunction(fsBuilder, &setLum);
940                     fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
941                                            inputColor, dstColor);
942                     fsBuilder->codeAppendf("\t\t%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);\n",
943                                            outputColor, setLum.c_str(), dstColor, inputColor);
944                     fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
945                                            outputColor, inputColor, dstColor, dstColor, inputColor);
946                     break;
947                 }
948                 case SkXfermode::kLuminosity_Mode: {
949                     //  SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S
950                     SkString setLum;
951                     AddLumFunction(fsBuilder, &setLum);
952                     fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n",
953                                            inputColor, dstColor);
954                     fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, srcDstAlpha.rgb);\n",
955                                            outputColor, setLum.c_str(), dstColor, inputColor);
956                     fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
957                                            outputColor, inputColor, dstColor, dstColor, inputColor);
958                     break;
959                 }
960                 default:
961                     SkFAIL("Unknown XferEffect mode.");
962                     break;
963             }
964         }
965
966         static inline void GenKey(const GrProcessor& proc, const GrGLCaps&,
967                                   GrProcessorKeyBuilder* b) {
968             // The background may come from the dst or from a texture.
969             uint32_t key = proc.numTextures();
970             SkASSERT(key <= 1);
971             key |= proc.cast<XferEffect>().mode() << 1;
972             b->add32(key);
973         }
974
975     private:
976         static void HardLight(GrGLFPFragmentBuilder* fsBuilder,
977                               const char* final,
978                               const char* src,
979                               const char* dst) {
980             static const char kComponents[] = {'r', 'g', 'b'};
981             for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) {
982                 char component = kComponents[i];
983                 fsBuilder->codeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
984                 fsBuilder->codeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", final, component, src, component, dst, component);
985                 fsBuilder->codeAppend("\t\t} else {\n");
986                 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s.a - %s.%c);\n",
987                                        final, component, src, dst, dst, dst, component, src, src, component);
988                 fsBuilder->codeAppend("\t\t}\n");
989             }
990             fsBuilder->codeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n",
991                                    final, src, dst, dst, src);
992         }
993
994         // Does one component of color-dodge
995         static void ColorDodgeComponent(GrGLFPFragmentBuilder* fsBuilder,
996                                         const char* final,
997                                         const char* src,
998                                         const char* dst,
999                                         const char component) {
1000             fsBuilder->codeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component);
1001             fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
1002                                    final, component, src, component, dst);
1003             fsBuilder->codeAppend("\t\t} else {\n");
1004             fsBuilder->codeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component);
1005             fsBuilder->codeAppend("\t\t\tif (0.0 == d) {\n");
1006             fsBuilder->codeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
1007                                    final, component, src, dst, src, component, dst, dst, component,
1008                                    src);
1009             fsBuilder->codeAppend("\t\t\t} else {\n");
1010             fsBuilder->codeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n",
1011                                    dst, dst, component, src);
1012             fsBuilder->codeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
1013                                    final, component, src, src, component, dst, dst, component, src);
1014             fsBuilder->codeAppend("\t\t\t}\n");
1015             fsBuilder->codeAppend("\t\t}\n");
1016         }
1017
1018         // Does one component of color-burn
1019         static void ColorBurnComponent(GrGLFPFragmentBuilder* fsBuilder,
1020                                        const char* final,
1021                                        const char* src,
1022                                        const char* dst,
1023                                        const char component) {
1024             fsBuilder->codeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, component);
1025             fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
1026                                    final, component, src, dst, src, component, dst, dst, component,
1027                                    src);
1028             fsBuilder->codeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, component);
1029             fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
1030                                    final, component, dst, component, src);
1031             fsBuilder->codeAppend("\t\t} else {\n");
1032             fsBuilder->codeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / %s.%c);\n",
1033                                    dst, dst, dst, component, src, src, component);
1034             fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
1035                                    final, component, src, src, component, dst, dst, component, src);
1036             fsBuilder->codeAppend("\t\t}\n");
1037         }
1038
1039         // Does one component of soft-light. Caller should have already checked that dst alpha > 0.
1040         static void SoftLightComponentPosDstAlpha(GrGLFPFragmentBuilder* fsBuilder,
1041                                                   const char* final,
1042                                                   const char* src,
1043                                                   const char* dst,
1044                                                   const char component) {
1045             // if (2S < Sa)
1046             fsBuilder->codeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
1047             // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1)
1048             fsBuilder->codeAppendf("\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",
1049                                    final, component, dst, component, dst, component, src, src,
1050                                    component, dst, dst, src, component, dst, component, src, src,
1051                                    component);
1052             // else if (4D < Da)
1053             fsBuilder->codeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n",
1054                                    dst, component, dst);
1055             fsBuilder->codeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n",
1056                                    dst, component, dst, component);
1057             fsBuilder->codeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component);
1058             fsBuilder->codeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst);
1059             fsBuilder->codeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst);
1060             // (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
1061             fsBuilder->codeAppendf("\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",
1062                                    final, component, src, component, src, component, dst, component,
1063                                    src, src, component, dst, src, src, component, src, src,
1064                                    component);
1065             fsBuilder->codeAppendf("\t\t\t} else {\n");
1066             // -sqrt(Da * D) (Sa-2 S)-Da S+D (Sa-2 S+1)+S
1067             fsBuilder->codeAppendf("\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",
1068                                     final, component, dst, dst, component, src, src, component, dst,
1069                                     src, component, dst, component, src, src, component, src,
1070                                     component);
1071             fsBuilder->codeAppendf("\t\t\t}\n");
1072         }
1073
1074         // Adds a function that takes two colors and an alpha as input. It produces a color with the
1075         // hue and saturation of the first color, the luminosity of the second color, and the input
1076         // alpha. It has this signature:
1077         //      vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor).
1078         static void AddLumFunction(GrGLFPFragmentBuilder* fsBuilder, SkString* setLumFunction) {
1079             // Emit a helper that gets the luminance of a color.
1080             SkString getFunction;
1081             GrGLShaderVar getLumArgs[] = {
1082                 GrGLShaderVar("color", kVec3f_GrSLType),
1083             };
1084             SkString getLumBody("\treturn dot(vec3(0.3, 0.59, 0.11), color);\n");
1085             fsBuilder->emitFunction(kFloat_GrSLType,
1086                                     "luminance",
1087                                     SK_ARRAY_COUNT(getLumArgs), getLumArgs,
1088                                     getLumBody.c_str(),
1089                                     &getFunction);
1090
1091             // Emit the set luminance function.
1092             GrGLShaderVar setLumArgs[] = {
1093                 GrGLShaderVar("hueSat", kVec3f_GrSLType),
1094                 GrGLShaderVar("alpha", kFloat_GrSLType),
1095                 GrGLShaderVar("lumColor", kVec3f_GrSLType),
1096             };
1097             SkString setLumBody;
1098             setLumBody.printf("\tfloat diff = %s(lumColor - hueSat);\n", getFunction.c_str());
1099             setLumBody.append("\tvec3 outColor = hueSat + diff;\n");
1100             setLumBody.appendf("\tfloat outLum = %s(outColor);\n", getFunction.c_str());
1101             setLumBody.append("\tfloat minComp = min(min(outColor.r, outColor.g), outColor.b);\n"
1102                               "\tfloat maxComp = max(max(outColor.r, outColor.g), outColor.b);\n"
1103                               "\tif (minComp < 0.0) {\n"
1104                               "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * outLum) / (outLum - minComp);\n"
1105                               "\t}\n"
1106                               "\tif (maxComp > alpha) {\n"
1107                               "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) / (maxComp - outLum);\n"
1108                               "\t}\n"
1109                               "\treturn outColor;\n");
1110             fsBuilder->emitFunction(kVec3f_GrSLType,
1111                                     "set_luminance",
1112                                     SK_ARRAY_COUNT(setLumArgs), setLumArgs,
1113                                     setLumBody.c_str(),
1114                                     setLumFunction);
1115         }
1116
1117         // Adds a function that creates a color with the hue and luminosity of one input color and
1118         // the saturation of another color. It will have this signature:
1119         //      float set_saturation(vec3 hueLumColor, vec3 satColor)
1120         static void AddSatFunction(GrGLFPFragmentBuilder* fsBuilder, SkString* setSatFunction) {
1121             // Emit a helper that gets the saturation of a color
1122             SkString getFunction;
1123             GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLType) };
1124             SkString getSatBody;
1125             getSatBody.printf("\treturn max(max(color.r, color.g), color.b) - "
1126                               "min(min(color.r, color.g), color.b);\n");
1127             fsBuilder->emitFunction(kFloat_GrSLType,
1128                                     "saturation",
1129                                     SK_ARRAY_COUNT(getSatArgs), getSatArgs,
1130                                     getSatBody.c_str(),
1131                                     &getFunction);
1132
1133             // Emit a helper that sets the saturation given sorted input channels. This used
1134             // to use inout params for min, mid, and max components but that seems to cause
1135             // problems on PowerVR drivers. So instead it returns a vec3 where r, g ,b are the
1136             // adjusted min, mid, and max inputs, respectively.
1137             SkString helperFunction;
1138             GrGLShaderVar helperArgs[] = {
1139                 GrGLShaderVar("minComp", kFloat_GrSLType),
1140                 GrGLShaderVar("midComp", kFloat_GrSLType),
1141                 GrGLShaderVar("maxComp", kFloat_GrSLType),
1142                 GrGLShaderVar("sat", kFloat_GrSLType),
1143             };
1144             static const char kHelperBody[] = "\tif (minComp < maxComp) {\n"
1145                                               "\t\tvec3 result;\n"
1146                                               "\t\tresult.r = 0.0;\n"
1147                                               "\t\tresult.g = sat * (midComp - minComp) / (maxComp - minComp);\n"
1148                                               "\t\tresult.b = sat;\n"
1149                                               "\t\treturn result;\n"
1150                                               "\t} else {\n"
1151                                               "\t\treturn vec3(0, 0, 0);\n"
1152                                               "\t}\n";
1153             fsBuilder->emitFunction(kVec3f_GrSLType,
1154                                     "set_saturation_helper",
1155                                     SK_ARRAY_COUNT(helperArgs), helperArgs,
1156                                     kHelperBody,
1157                                     &helperFunction);
1158
1159             GrGLShaderVar setSatArgs[] = {
1160                 GrGLShaderVar("hueLumColor", kVec3f_GrSLType),
1161                 GrGLShaderVar("satColor", kVec3f_GrSLType),
1162             };
1163             const char* helpFunc = helperFunction.c_str();
1164             SkString setSatBody;
1165             setSatBody.appendf("\tfloat sat = %s(satColor);\n"
1166                                "\tif (hueLumColor.r <= hueLumColor.g) {\n"
1167                                "\t\tif (hueLumColor.g <= hueLumColor.b) {\n"
1168                                "\t\t\thueLumColor.rgb = %s(hueLumColor.r, hueLumColor.g, hueLumColor.b, sat);\n"
1169                                "\t\t} else if (hueLumColor.r <= hueLumColor.b) {\n"
1170                                "\t\t\thueLumColor.rbg = %s(hueLumColor.r, hueLumColor.b, hueLumColor.g, sat);\n"
1171                                "\t\t} else {\n"
1172                                "\t\t\thueLumColor.brg = %s(hueLumColor.b, hueLumColor.r, hueLumColor.g, sat);\n"
1173                                "\t\t}\n"
1174                                "\t} else if (hueLumColor.r <= hueLumColor.b) {\n"
1175                                "\t\thueLumColor.grb = %s(hueLumColor.g, hueLumColor.r, hueLumColor.b, sat);\n"
1176                                "\t} else if (hueLumColor.g <= hueLumColor.b) {\n"
1177                                "\t\thueLumColor.gbr = %s(hueLumColor.g, hueLumColor.b, hueLumColor.r, sat);\n"
1178                                "\t} else {\n"
1179                                "\t\thueLumColor.bgr = %s(hueLumColor.b, hueLumColor.g, hueLumColor.r, sat);\n"
1180                                "\t}\n"
1181                                "\treturn hueLumColor;\n",
1182                                getFunction.c_str(), helpFunc, helpFunc, helpFunc, helpFunc,
1183                                helpFunc, helpFunc);
1184             fsBuilder->emitFunction(kVec3f_GrSLType,
1185                                     "set_saturation",
1186                                     SK_ARRAY_COUNT(setSatArgs), setSatArgs,
1187                                     setSatBody.c_str(),
1188                                     setSatFunction);
1189
1190         }
1191
1192         typedef GrGLFragmentProcessor INHERITED;
1193     };
1194
1195     GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
1196
1197 private:
1198     XferEffect(SkXfermode::Mode mode, GrTexture* background)
1199         : fMode(mode) {
1200         if (background) {
1201             fBackgroundTransform.reset(kLocal_GrCoordSet, background);
1202             this->addCoordTransform(&fBackgroundTransform);
1203             fBackgroundAccess.reset(background);
1204             this->addTextureAccess(&fBackgroundAccess);
1205         } else {
1206             this->setWillReadDstColor();
1207         }
1208     }
1209     virtual bool onIsEqual(const GrFragmentProcessor& other) const SK_OVERRIDE {
1210         const XferEffect& s = other.cast<XferEffect>();
1211         return fMode == s.fMode;
1212     }
1213
1214     virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERRIDE {
1215         inout->setToUnknown(InvariantOutput::kWill_ReadInput);
1216     }
1217
1218     SkXfermode::Mode fMode;
1219     GrCoordTransform fBackgroundTransform;
1220     GrTextureAccess  fBackgroundAccess;
1221
1222     typedef GrFragmentProcessor INHERITED;
1223 };
1224
1225 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(XferEffect);
1226 GrFragmentProcessor* XferEffect::TestCreate(SkRandom* rand,
1227                                             GrContext*,
1228                                             const GrDrawTargetCaps&,
1229                                             GrTexture*[]) {
1230     int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLastSeparableMode);
1231
1232     return SkNEW_ARGS(XferEffect, (static_cast<SkXfermode::Mode>(mode), NULL));
1233 }
1234
1235 #endif
1236
1237 ///////////////////////////////////////////////////////////////////////////////
1238 ///////////////////////////////////////////////////////////////////////////////
1239
1240 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
1241 SkProcCoeffXfermode::SkProcCoeffXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {
1242     uint32_t mode32 = buffer.read32() % SK_ARRAY_COUNT(gProcCoeffs);
1243     if (mode32 >= SK_ARRAY_COUNT(gProcCoeffs)) {
1244         // out of range, just set to something harmless
1245         mode32 = SkXfermode::kSrcOut_Mode;
1246     }
1247     fMode = (SkXfermode::Mode)mode32;
1248
1249     const ProcCoeff& rec = gProcCoeffs[fMode];
1250     fProc = rec.fProc;
1251     // these may be valid, or may be CANNOT_USE_COEFF
1252     fSrcCoeff = rec.fSC;
1253     fDstCoeff = rec.fDC;
1254 }
1255 #endif
1256
1257 SkFlattenable* SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) {
1258     uint32_t mode32 = buffer.read32();
1259     if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcCoeffs))) {
1260         return NULL;
1261     }
1262     return SkXfermode::Create((SkXfermode::Mode)mode32);
1263 }
1264
1265 void SkProcCoeffXfermode::flatten(SkWriteBuffer& buffer) const {
1266     buffer.write32(fMode);
1267 }
1268
1269 bool SkProcCoeffXfermode::asMode(Mode* mode) const {
1270     if (mode) {
1271         *mode = fMode;
1272     }
1273     return true;
1274 }
1275
1276 bool SkProcCoeffXfermode::asCoeff(Coeff* sc, Coeff* dc) const {
1277     if (CANNOT_USE_COEFF == fSrcCoeff) {
1278         return false;
1279     }
1280
1281     if (sc) {
1282         *sc = fSrcCoeff;
1283     }
1284     if (dc) {
1285         *dc = fDstCoeff;
1286     }
1287     return true;
1288 }
1289
1290 void SkProcCoeffXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1291                                  const SkPMColor* SK_RESTRICT src, int count,
1292                                  const SkAlpha* SK_RESTRICT aa) const {
1293     SkASSERT(dst && src && count >= 0);
1294
1295     SkXfermodeProc proc = fProc;
1296
1297     if (proc) {
1298         if (NULL == aa) {
1299             for (int i = count - 1; i >= 0; --i) {
1300                 dst[i] = proc(src[i], dst[i]);
1301             }
1302         } else {
1303             for (int i = count - 1; i >= 0; --i) {
1304                 unsigned a = aa[i];
1305                 if (0 != a) {
1306                     SkPMColor dstC = dst[i];
1307                     SkPMColor C = proc(src[i], dstC);
1308                     if (a != 0xFF) {
1309                         C = SkFourByteInterp(C, dstC, a);
1310                     }
1311                     dst[i] = C;
1312                 }
1313             }
1314         }
1315     }
1316 }
1317
1318 void SkProcCoeffXfermode::xfer16(uint16_t* SK_RESTRICT dst,
1319                                  const SkPMColor* SK_RESTRICT src, int count,
1320                                  const SkAlpha* SK_RESTRICT aa) const {
1321     SkASSERT(dst && src && count >= 0);
1322
1323     SkXfermodeProc proc = fProc;
1324
1325     if (proc) {
1326         if (NULL == aa) {
1327             for (int i = count - 1; i >= 0; --i) {
1328                 SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
1329                 dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC));
1330             }
1331         } else {
1332             for (int i = count - 1; i >= 0; --i) {
1333                 unsigned a = aa[i];
1334                 if (0 != a) {
1335                     SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
1336                     SkPMColor C = proc(src[i], dstC);
1337                     if (0xFF != a) {
1338                         C = SkFourByteInterp(C, dstC, a);
1339                     }
1340                     dst[i] = SkPixel32ToPixel16_ToU16(C);
1341                 }
1342             }
1343         }
1344     }
1345 }
1346
1347 void SkProcCoeffXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
1348                                  const SkPMColor* SK_RESTRICT src, int count,
1349                                  const SkAlpha* SK_RESTRICT aa) const {
1350     SkASSERT(dst && src && count >= 0);
1351
1352     SkXfermodeProc proc = fProc;
1353
1354     if (proc) {
1355         if (NULL == aa) {
1356             for (int i = count - 1; i >= 0; --i) {
1357                 SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT);
1358                 dst[i] = SkToU8(SkGetPackedA32(res));
1359             }
1360         } else {
1361             for (int i = count - 1; i >= 0; --i) {
1362                 unsigned a = aa[i];
1363                 if (0 != a) {
1364                     SkAlpha dstA = dst[i];
1365                     SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT);
1366                     unsigned A = SkGetPackedA32(res);
1367                     if (0xFF != a) {
1368                         A = SkAlphaBlend(A, dstA, SkAlpha255To256(a));
1369                     }
1370                     dst[i] = SkToU8(A);
1371                 }
1372             }
1373         }
1374     }
1375 }
1376
1377 #if SK_SUPPORT_GPU
1378 bool SkProcCoeffXfermode::asFragmentProcessor(GrFragmentProcessor** fp,
1379                                               GrTexture* background) const {
1380     if (XferEffect::IsSupportedMode(fMode)) {
1381         if (fp) {
1382             *fp = XferEffect::Create(fMode, background);
1383             SkASSERT(*fp);
1384         }
1385         return true;
1386     }
1387     return false;
1388 }
1389 #endif
1390
1391 const char* SkXfermode::ModeName(Mode mode) {
1392     SkASSERT((unsigned) mode <= (unsigned)kLastMode);
1393     const char* gModeStrings[] = {
1394         "Clear", "Src", "Dst", "SrcOver", "DstOver", "SrcIn", "DstIn",
1395         "SrcOut", "DstOut", "SrcATop", "DstATop", "Xor", "Plus",
1396         "Modulate", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge",
1397         "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion",
1398         "Multiply", "Hue", "Saturation", "Color",  "Luminosity"
1399     };
1400     return gModeStrings[mode];
1401     SK_COMPILE_ASSERT(SK_ARRAY_COUNT(gModeStrings) == kLastMode + 1, mode_count);
1402 }
1403
1404 #ifndef SK_IGNORE_TO_STRING
1405 void SkProcCoeffXfermode::toString(SkString* str) const {
1406     str->append("SkProcCoeffXfermode: ");
1407
1408     str->append("mode: ");
1409     str->append(ModeName(fMode));
1410
1411     static const char* gCoeffStrings[kCoeffCount] = {
1412         "Zero", "One", "SC", "ISC", "DC", "IDC", "SA", "ISA", "DA", "IDA"
1413     };
1414
1415     str->append(" src: ");
1416     if (CANNOT_USE_COEFF == fSrcCoeff) {
1417         str->append("can't use");
1418     } else {
1419         str->append(gCoeffStrings[fSrcCoeff]);
1420     }
1421
1422     str->append(" dst: ");
1423     if (CANNOT_USE_COEFF == fDstCoeff) {
1424         str->append("can't use");
1425     } else {
1426         str->append(gCoeffStrings[fDstCoeff]);
1427     }
1428 }
1429 #endif
1430
1431 ///////////////////////////////////////////////////////////////////////////////
1432
1433 class SkClearXfermode : public SkProcCoeffXfermode {
1434 public:
1435     static SkClearXfermode* Create(const ProcCoeff& rec) {
1436         return SkNEW_ARGS(SkClearXfermode, (rec));
1437     }
1438
1439     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1440     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1441
1442     SK_TO_STRING_OVERRIDE()
1443
1444 private:
1445     SkClearXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kClear_Mode) {}
1446 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
1447     SkClearXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {}
1448 #endif
1449
1450     typedef SkProcCoeffXfermode INHERITED;
1451 };
1452
1453 void SkClearXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1454                              const SkPMColor* SK_RESTRICT, int count,
1455                              const SkAlpha* SK_RESTRICT aa) const {
1456     SkASSERT(dst && count >= 0);
1457
1458     if (NULL == aa) {
1459         memset(dst, 0, count << 2);
1460     } else {
1461         for (int i = count - 1; i >= 0; --i) {
1462             unsigned a = aa[i];
1463             if (0xFF == a) {
1464                 dst[i] = 0;
1465             } else if (a != 0) {
1466                 dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a));
1467             }
1468         }
1469     }
1470 }
1471 void SkClearXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
1472                              const SkPMColor* SK_RESTRICT, int count,
1473                              const SkAlpha* SK_RESTRICT aa) const {
1474     SkASSERT(dst && count >= 0);
1475
1476     if (NULL == aa) {
1477         memset(dst, 0, count);
1478     } else {
1479         for (int i = count - 1; i >= 0; --i) {
1480             unsigned a = aa[i];
1481             if (0xFF == a) {
1482                 dst[i] = 0;
1483             } else if (0 != a) {
1484                 dst[i] = SkAlphaMulAlpha(dst[i], 255 - a);
1485             }
1486         }
1487     }
1488 }
1489
1490 #ifndef SK_IGNORE_TO_STRING
1491 void SkClearXfermode::toString(SkString* str) const {
1492     this->INHERITED::toString(str);
1493 }
1494 #endif
1495
1496 ///////////////////////////////////////////////////////////////////////////////
1497
1498 class SkSrcXfermode : public SkProcCoeffXfermode {
1499 public:
1500     static SkSrcXfermode* Create(const ProcCoeff& rec) {
1501         return SkNEW_ARGS(SkSrcXfermode, (rec));
1502     }
1503
1504     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1505     virtual void xferA8(SkAlpha*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1506
1507     SK_TO_STRING_OVERRIDE()
1508
1509 private:
1510     SkSrcXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kSrc_Mode) {}
1511 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
1512     SkSrcXfermode(SkReadBuffer& buffer) : SkProcCoeffXfermode(buffer) {}
1513 #endif
1514     typedef SkProcCoeffXfermode INHERITED;
1515 };
1516
1517 void SkSrcXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1518                            const SkPMColor* SK_RESTRICT src, int count,
1519                            const SkAlpha* SK_RESTRICT aa) const {
1520     SkASSERT(dst && src && count >= 0);
1521
1522     if (NULL == aa) {
1523         memcpy(dst, src, count << 2);
1524     } else {
1525         for (int i = count - 1; i >= 0; --i) {
1526             unsigned a = aa[i];
1527             if (a == 0xFF) {
1528                 dst[i] = src[i];
1529             } else if (a != 0) {
1530                 dst[i] = SkFourByteInterp(src[i], dst[i], a);
1531             }
1532         }
1533     }
1534 }
1535
1536 void SkSrcXfermode::xferA8(SkAlpha* SK_RESTRICT dst,
1537                            const SkPMColor* SK_RESTRICT src, int count,
1538                            const SkAlpha* SK_RESTRICT aa) const {
1539     SkASSERT(dst && src && count >= 0);
1540
1541     if (NULL == aa) {
1542         for (int i = count - 1; i >= 0; --i) {
1543             dst[i] = SkToU8(SkGetPackedA32(src[i]));
1544         }
1545     } else {
1546         for (int i = count - 1; i >= 0; --i) {
1547             unsigned a = aa[i];
1548             if (0 != a) {
1549                 unsigned srcA = SkGetPackedA32(src[i]);
1550                 if (a == 0xFF) {
1551                     dst[i] = SkToU8(srcA);
1552                 } else {
1553                     dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a));
1554                 }
1555             }
1556         }
1557     }
1558 }
1559 #ifndef SK_IGNORE_TO_STRING
1560 void SkSrcXfermode::toString(SkString* str) const {
1561     this->INHERITED::toString(str);
1562 }
1563 #endif
1564
1565 ///////////////////////////////////////////////////////////////////////////////
1566
1567 class SkDstInXfermode : public SkProcCoeffXfermode {
1568 public:
1569     static SkDstInXfermode* Create(const ProcCoeff& rec) {
1570         return SkNEW_ARGS(SkDstInXfermode, (rec));
1571     }
1572
1573     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1574
1575     SK_TO_STRING_OVERRIDE()
1576
1577 private:
1578     SkDstInXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstIn_Mode) {}
1579 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
1580     SkDstInXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {}
1581 #endif
1582
1583     typedef SkProcCoeffXfermode INHERITED;
1584 };
1585
1586 void SkDstInXfermode::xfer32(SkPMColor* SK_RESTRICT dst,
1587                              const SkPMColor* SK_RESTRICT src, int count,
1588                              const SkAlpha* SK_RESTRICT aa) const {
1589     SkASSERT(dst && src);
1590
1591     if (count <= 0) {
1592         return;
1593     }
1594     if (aa) {
1595         return this->INHERITED::xfer32(dst, src, count, aa);
1596     }
1597
1598     do {
1599         unsigned a = SkGetPackedA32(*src);
1600         *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a));
1601         dst++;
1602         src++;
1603     } while (--count != 0);
1604 }
1605
1606 #ifndef SK_IGNORE_TO_STRING
1607 void SkDstInXfermode::toString(SkString* str) const {
1608     this->INHERITED::toString(str);
1609 }
1610 #endif
1611
1612 ///////////////////////////////////////////////////////////////////////////////
1613
1614 class SkDstOutXfermode : public SkProcCoeffXfermode {
1615 public:
1616     static SkDstOutXfermode* Create(const ProcCoeff& rec) {
1617         return SkNEW_ARGS(SkDstOutXfermode, (rec));
1618     }
1619
1620     virtual void xfer32(SkPMColor*, const SkPMColor*, int, const SkAlpha*) const SK_OVERRIDE;
1621
1622     SK_TO_STRING_OVERRIDE()
1623
1624 private:
1625     SkDstOutXfermode(const ProcCoeff& rec) : SkProcCoeffXfermode(rec, kDstOut_Mode) {}
1626 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
1627     SkDstOutXfermode(SkReadBuffer& buffer) : INHERITED(buffer) {}
1628 #endif
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 (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 #ifndef SK_IGNORE_TO_STRING
1654 void SkDstOutXfermode::toString(SkString* str) const {
1655     this->INHERITED::toString(str);
1656 }
1657 #endif
1658
1659 ///////////////////////////////////////////////////////////////////////////////
1660
1661 extern SkProcCoeffXfermode* SkPlatformXfermodeFactory(const ProcCoeff& rec, SkXfermode::Mode mode);
1662 extern SkXfermodeProc SkPlatformXfermodeProcFactory(SkXfermode::Mode mode);
1663
1664 // Technically, can't be static and passed as a template parameter.  So we use anonymous namespace.
1665 namespace {
1666 SkXfermode* create_mode(int iMode) {
1667     SkXfermode::Mode mode = (SkXfermode::Mode)iMode;
1668
1669     ProcCoeff rec = gProcCoeffs[mode];
1670     SkXfermodeProc pp = SkPlatformXfermodeProcFactory(mode);
1671     if (pp != NULL) {
1672         rec.fProc = pp;
1673     }
1674
1675     SkXfermode* xfer = NULL;
1676     // check if we have a platform optim for that
1677     SkProcCoeffXfermode* xfm = SkPlatformXfermodeFactory(rec, mode);
1678     if (xfm != NULL) {
1679         xfer = xfm;
1680     } else {
1681         // All modes can in theory be represented by the ProcCoeff rec, since
1682         // it contains function ptrs. However, a few modes are both simple and
1683         // commonly used, so we call those out for their own subclasses here.
1684         switch (mode) {
1685             case SkXfermode::kClear_Mode:
1686                 xfer = SkClearXfermode::Create(rec);
1687                 break;
1688             case SkXfermode::kSrc_Mode:
1689                 xfer = SkSrcXfermode::Create(rec);
1690                 break;
1691             case SkXfermode::kSrcOver_Mode:
1692                 SkASSERT(false);    // should not land here
1693                 break;
1694             case SkXfermode::kDstIn_Mode:
1695                 xfer = SkDstInXfermode::Create(rec);
1696                 break;
1697             case SkXfermode::kDstOut_Mode:
1698                 xfer = SkDstOutXfermode::Create(rec);
1699                 break;
1700             default:
1701                 // no special-case, just rely in the rec and its function-ptrs
1702                 xfer = SkNEW_ARGS(SkProcCoeffXfermode, (rec, mode));
1703                 break;
1704         }
1705     }
1706     return xfer;
1707 }
1708 }  // namespace
1709
1710 SK_DECLARE_STATIC_LAZY_PTR_ARRAY(SkXfermode, cached, SkXfermode::kLastMode + 1, create_mode);
1711
1712 SkXfermode* SkXfermode::Create(Mode mode) {
1713     SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
1714
1715     if ((unsigned)mode >= kModeCount) {
1716         // report error
1717         return NULL;
1718     }
1719
1720     // Skia's "default" mode is srcover. NULL in SkPaint is interpreted as srcover
1721     // so we can just return NULL from the factory.
1722     if (kSrcOver_Mode == mode) {
1723         return NULL;
1724     }
1725
1726     return SkSafeRef(cached[mode]);
1727 }
1728
1729 SkXfermodeProc SkXfermode::GetProc(Mode mode) {
1730     SkXfermodeProc  proc = NULL;
1731     if ((unsigned)mode < kModeCount) {
1732         proc = gProcCoeffs[mode].fProc;
1733     }
1734     return proc;
1735 }
1736
1737 bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) {
1738     SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
1739
1740     if ((unsigned)mode >= (unsigned)kModeCount) {
1741         // illegal mode parameter
1742         return false;
1743     }
1744
1745     const ProcCoeff& rec = gProcCoeffs[mode];
1746
1747     if (CANNOT_USE_COEFF == rec.fSC) {
1748         return false;
1749     }
1750
1751     SkASSERT(CANNOT_USE_COEFF != rec.fDC);
1752     if (src) {
1753         *src = rec.fSC;
1754     }
1755     if (dst) {
1756         *dst = rec.fDC;
1757     }
1758     return true;
1759 }
1760
1761 bool SkXfermode::AsMode(const SkXfermode* xfer, Mode* mode) {
1762     if (NULL == xfer) {
1763         if (mode) {
1764             *mode = kSrcOver_Mode;
1765         }
1766         return true;
1767     }
1768     return xfer->asMode(mode);
1769 }
1770
1771 bool SkXfermode::AsCoeff(const SkXfermode* xfer, Coeff* src, Coeff* dst) {
1772     if (NULL == xfer) {
1773         return ModeAsCoeff(kSrcOver_Mode, src, dst);
1774     }
1775     return xfer->asCoeff(src, dst);
1776 }
1777
1778 bool SkXfermode::IsMode(const SkXfermode* xfer, Mode mode) {
1779     // if xfer==null then the mode is srcover
1780     Mode m = kSrcOver_Mode;
1781     if (xfer && !xfer->asMode(&m)) {
1782         return false;
1783     }
1784     return mode == m;
1785 }
1786
1787 ///////////////////////////////////////////////////////////////////////////////
1788 //////////// 16bit xfermode procs
1789
1790 #ifdef SK_DEBUG
1791 static bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; }
1792 static bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; }
1793 #endif
1794
1795 static uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) {
1796     SkASSERT(require_255(src));
1797     return SkPixel32ToPixel16(src);
1798 }
1799
1800 static uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) {
1801     return dst;
1802 }
1803
1804 static uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) {
1805     SkASSERT(require_0(src));
1806     return dst;
1807 }
1808
1809 static uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) {
1810     SkASSERT(require_255(src));
1811     return SkPixel32ToPixel16(src);
1812 }
1813
1814 static uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) {
1815     SkASSERT(require_0(src));
1816     return dst;
1817 }
1818
1819 static uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) {
1820     SkASSERT(require_255(src));
1821     return dst;
1822 }
1823
1824 static uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) {
1825     SkASSERT(require_255(src));
1826     return SkPixel32ToPixel16(src);
1827 }
1828
1829 static uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) {
1830     SkASSERT(require_255(src));
1831     return dst;
1832 }
1833
1834 static uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) {
1835     SkASSERT(require_0(src));
1836     return dst;
1837 }
1838
1839 static uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) {
1840     unsigned isa = 255 - SkGetPackedA32(src);
1841
1842     return SkPackRGB16(
1843            SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa),
1844            SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa),
1845            SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa));
1846 }
1847
1848 static uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) {
1849     SkASSERT(require_0(src));
1850     return dst;
1851 }
1852
1853 static uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) {
1854     SkASSERT(require_255(src));
1855     return SkPixel32ToPixel16(src);
1856 }
1857
1858 static uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) {
1859     SkASSERT(require_255(src));
1860     return dst;
1861 }
1862
1863 /*********
1864     darken and lighten boil down to this.
1865
1866     darken  = (1 - Sa) * Dc + min(Sc, Dc)
1867     lighten = (1 - Sa) * Dc + max(Sc, Dc)
1868
1869     if (Sa == 0) these become
1870         darken  = Dc + min(0, Dc) = 0
1871         lighten = Dc + max(0, Dc) = Dc
1872
1873     if (Sa == 1) these become
1874         darken  = min(Sc, Dc)
1875         lighten = max(Sc, Dc)
1876 */
1877
1878 static uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) {
1879     SkASSERT(require_0(src));
1880     return 0;
1881 }
1882
1883 static uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) {
1884     SkASSERT(require_255(src));
1885     unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst));
1886     unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst));
1887     unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst));
1888     return SkPackRGB16(r, g, b);
1889 }
1890
1891 static uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) {
1892     SkASSERT(require_0(src));
1893     return dst;
1894 }
1895
1896 static uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) {
1897     SkASSERT(require_255(src));
1898     unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst));
1899     unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst));
1900     unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst));
1901     return SkPackRGB16(r, g, b);
1902 }
1903
1904 struct Proc16Rec {
1905     SkXfermodeProc16    fProc16_0;
1906     SkXfermodeProc16    fProc16_255;
1907     SkXfermodeProc16    fProc16_General;
1908 };
1909
1910 static const Proc16Rec gModeProcs16[] = {
1911     { NULL,                 NULL,                   NULL            }, // CLEAR
1912     { NULL,                 src_modeproc16_255,     NULL            },
1913     { dst_modeproc16,       dst_modeproc16,         dst_modeproc16  },
1914     { srcover_modeproc16_0, srcover_modeproc16_255, NULL            },
1915     { dstover_modeproc16_0, dstover_modeproc16_255, NULL            },
1916     { NULL,                 srcin_modeproc16_255,   NULL            },
1917     { NULL,                 dstin_modeproc16_255,   NULL            },
1918     { NULL,                 NULL,                   NULL            },// SRC_OUT
1919     { dstout_modeproc16_0,  NULL,                   NULL            },
1920     { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16  },
1921     { NULL,                 dstatop_modeproc16_255, NULL            },
1922     { NULL,                 NULL,                   NULL            }, // XOR
1923
1924     { NULL,                 NULL,                   NULL            }, // plus
1925     { NULL,                 NULL,                   NULL            }, // modulate
1926     { NULL,                 NULL,                   NULL            }, // screen
1927     { NULL,                 NULL,                   NULL            }, // overlay
1928     { darken_modeproc16_0,  darken_modeproc16_255,  NULL            }, // darken
1929     { lighten_modeproc16_0, lighten_modeproc16_255, NULL            }, // lighten
1930     { NULL,                 NULL,                   NULL            }, // colordodge
1931     { NULL,                 NULL,                   NULL            }, // colorburn
1932     { NULL,                 NULL,                   NULL            }, // hardlight
1933     { NULL,                 NULL,                   NULL            }, // softlight
1934     { NULL,                 NULL,                   NULL            }, // difference
1935     { NULL,                 NULL,                   NULL            }, // exclusion
1936     { NULL,                 NULL,                   NULL            }, // multiply
1937     { NULL,                 NULL,                   NULL            }, // hue
1938     { NULL,                 NULL,                   NULL            }, // saturation
1939     { NULL,                 NULL,                   NULL            }, // color
1940     { NULL,                 NULL,                   NULL            }, // luminosity
1941 };
1942
1943 SkXfermodeProc16 SkXfermode::GetProc16(Mode mode, SkColor srcColor) {
1944     SkXfermodeProc16  proc16 = NULL;
1945     if ((unsigned)mode < kModeCount) {
1946         const Proc16Rec& rec = gModeProcs16[mode];
1947         unsigned a = SkColorGetA(srcColor);
1948
1949         if (0 == a) {
1950             proc16 = rec.fProc16_0;
1951         } else if (255 == a) {
1952             proc16 = rec.fProc16_255;
1953         } else {
1954             proc16 = rec.fProc16_General;
1955         }
1956     }
1957     return proc16;
1958 }
1959
1960 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
1961     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
1962 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END