Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkBlitter_RGB16.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 "SkBlitRow.h"
11 #include "SkCoreBlitters.h"
12 #include "SkColorPriv.h"
13 #include "SkDither.h"
14 #include "SkShader.h"
15 #include "SkUtils.h"
16 #include "SkUtilsArm.h"
17 #include "SkXfermode.h"
18
19 #if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN)
20     #include <arm_neon.h>
21 #else
22     // if we don't have neon, then our black blitter is worth the extra code
23     #define USE_BLACK_BLITTER
24 #endif
25
26 void sk_dither_memset16(uint16_t dst[], uint16_t value, uint16_t other,
27                         int count) {
28     if (count > 0) {
29         // see if we need to write one short before we can cast to an 4byte ptr
30         // (we do this subtract rather than (unsigned)dst so we don't get warnings
31         //  on 64bit machines)
32         if (((char*)dst - (char*)0) & 2) {
33             *dst++ = value;
34             count -= 1;
35             SkTSwap(value, other);
36         }
37
38         // fast way to set [value,other] pairs
39 #ifdef SK_CPU_BENDIAN
40         sk_memset32((uint32_t*)dst, (value << 16) | other, count >> 1);
41 #else
42         sk_memset32((uint32_t*)dst, (other << 16) | value, count >> 1);
43 #endif
44
45         if (count & 1) {
46             dst[count - 1] = value;
47         }
48     }
49 }
50
51 ///////////////////////////////////////////////////////////////////////////////
52
53 class SkRGB16_Blitter : public SkRasterBlitter {
54 public:
55     SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint);
56     virtual void blitH(int x, int y, int width);
57     virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
58                            const int16_t* runs);
59     virtual void blitV(int x, int y, int height, SkAlpha alpha);
60     virtual void blitRect(int x, int y, int width, int height);
61     virtual void blitMask(const SkMask&,
62                           const SkIRect&);
63     virtual const SkBitmap* justAnOpaqueColor(uint32_t*);
64
65 protected:
66     SkPMColor   fSrcColor32;
67     uint32_t    fExpandedRaw16;
68     unsigned    fScale;
69     uint16_t    fColor16;       // already scaled by fScale
70     uint16_t    fRawColor16;    // unscaled
71     uint16_t    fRawDither16;   // unscaled
72     SkBool8     fDoDither;
73
74     // illegal
75     SkRGB16_Blitter& operator=(const SkRGB16_Blitter&);
76
77     typedef SkRasterBlitter INHERITED;
78 };
79
80 class SkRGB16_Opaque_Blitter : public SkRGB16_Blitter {
81 public:
82     SkRGB16_Opaque_Blitter(const SkBitmap& device, const SkPaint& paint);
83     virtual void blitH(int x, int y, int width);
84     virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
85                            const int16_t* runs);
86     virtual void blitV(int x, int y, int height, SkAlpha alpha);
87     virtual void blitRect(int x, int y, int width, int height);
88     virtual void blitMask(const SkMask&,
89                           const SkIRect&);
90
91 private:
92     typedef SkRGB16_Blitter INHERITED;
93 };
94
95 #ifdef USE_BLACK_BLITTER
96 class SkRGB16_Black_Blitter : public SkRGB16_Opaque_Blitter {
97 public:
98     SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint);
99     virtual void blitMask(const SkMask&, const SkIRect&);
100     virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
101                            const int16_t* runs);
102
103 private:
104     typedef SkRGB16_Opaque_Blitter INHERITED;
105 };
106 #endif
107
108 class SkRGB16_Shader_Blitter : public SkShaderBlitter {
109 public:
110     SkRGB16_Shader_Blitter(const SkBitmap& device, const SkPaint& paint);
111     virtual ~SkRGB16_Shader_Blitter();
112     virtual void blitH(int x, int y, int width);
113     virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
114                            const int16_t* runs);
115     virtual void blitRect(int x, int y, int width, int height);
116
117 protected:
118     SkPMColor*      fBuffer;
119     SkBlitRow::Proc fOpaqueProc;
120     SkBlitRow::Proc fAlphaProc;
121
122 private:
123     // illegal
124     SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&);
125
126     typedef SkShaderBlitter INHERITED;
127 };
128
129 // used only if the shader can perform shadSpan16
130 class SkRGB16_Shader16_Blitter : public SkRGB16_Shader_Blitter {
131 public:
132     SkRGB16_Shader16_Blitter(const SkBitmap& device, const SkPaint& paint);
133     virtual void blitH(int x, int y, int width);
134     virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
135                            const int16_t* runs);
136     virtual void blitRect(int x, int y, int width, int height);
137
138 private:
139     typedef SkRGB16_Shader_Blitter INHERITED;
140 };
141
142 class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter {
143 public:
144     SkRGB16_Shader_Xfermode_Blitter(const SkBitmap& device, const SkPaint& paint);
145     virtual ~SkRGB16_Shader_Xfermode_Blitter();
146     virtual void blitH(int x, int y, int width);
147     virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
148                            const int16_t* runs);
149
150 private:
151     SkXfermode* fXfermode;
152     SkPMColor*  fBuffer;
153     uint8_t*    fAAExpand;
154
155     // illegal
156     SkRGB16_Shader_Xfermode_Blitter& operator=(const SkRGB16_Shader_Xfermode_Blitter&);
157
158     typedef SkShaderBlitter INHERITED;
159 };
160
161 ///////////////////////////////////////////////////////////////////////////////
162 #ifdef USE_BLACK_BLITTER
163 SkRGB16_Black_Blitter::SkRGB16_Black_Blitter(const SkBitmap& device, const SkPaint& paint)
164     : INHERITED(device, paint) {
165     SkASSERT(paint.getShader() == NULL);
166     SkASSERT(paint.getColorFilter() == NULL);
167     SkASSERT(paint.getXfermode() == NULL);
168     SkASSERT(paint.getColor() == SK_ColorBLACK);
169 }
170
171 #if 1
172 #define black_8_pixels(mask, dst)       \
173     do {                                \
174         if (mask & 0x80) dst[0] = 0;    \
175         if (mask & 0x40) dst[1] = 0;    \
176         if (mask & 0x20) dst[2] = 0;    \
177         if (mask & 0x10) dst[3] = 0;    \
178         if (mask & 0x08) dst[4] = 0;    \
179         if (mask & 0x04) dst[5] = 0;    \
180         if (mask & 0x02) dst[6] = 0;    \
181         if (mask & 0x01) dst[7] = 0;    \
182     } while (0)
183 #else
184 static inline black_8_pixels(U8CPU mask, uint16_t dst[])
185 {
186     if (mask & 0x80) dst[0] = 0;
187     if (mask & 0x40) dst[1] = 0;
188     if (mask & 0x20) dst[2] = 0;
189     if (mask & 0x10) dst[3] = 0;
190     if (mask & 0x08) dst[4] = 0;
191     if (mask & 0x04) dst[5] = 0;
192     if (mask & 0x02) dst[6] = 0;
193     if (mask & 0x01) dst[7] = 0;
194 }
195 #endif
196
197 #define SK_BLITBWMASK_NAME                  SkRGB16_Black_BlitBW
198 #define SK_BLITBWMASK_ARGS
199 #define SK_BLITBWMASK_BLIT8(mask, dst)      black_8_pixels(mask, dst)
200 #define SK_BLITBWMASK_GETADDR               getAddr16
201 #define SK_BLITBWMASK_DEVTYPE               uint16_t
202 #include "SkBlitBWMaskTemplate.h"
203
204 void SkRGB16_Black_Blitter::blitMask(const SkMask& mask,
205                                      const SkIRect& clip) {
206     if (mask.fFormat == SkMask::kBW_Format) {
207         SkRGB16_Black_BlitBW(fDevice, mask, clip);
208     } else {
209         uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop);
210         const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop);
211         unsigned width = clip.width();
212         unsigned height = clip.height();
213         size_t deviceRB = fDevice.rowBytes() - (width << 1);
214         unsigned maskRB = mask.fRowBytes - width;
215
216         SkASSERT((int)height > 0);
217         SkASSERT((int)width > 0);
218         SkASSERT((int)deviceRB >= 0);
219         SkASSERT((int)maskRB >= 0);
220
221         do {
222             unsigned w = width;
223             do {
224                 unsigned aa = *alpha++;
225                 *device = SkAlphaMulRGB16(*device, SkAlpha255To256(255 - aa));
226                 device += 1;
227             } while (--w != 0);
228             device = (uint16_t*)((char*)device + deviceRB);
229             alpha += maskRB;
230         } while (--height != 0);
231     }
232 }
233
234 void SkRGB16_Black_Blitter::blitAntiH(int x, int y,
235                                       const SkAlpha* SK_RESTRICT antialias,
236                                       const int16_t* SK_RESTRICT runs) {
237     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
238
239     for (;;) {
240         int count = runs[0];
241         SkASSERT(count >= 0);
242         if (count <= 0) {
243             return;
244         }
245         runs += count;
246
247         unsigned aa = antialias[0];
248         antialias += count;
249         if (aa) {
250             if (aa == 255) {
251                 memset(device, 0, count << 1);
252             } else {
253                 aa = SkAlpha255To256(255 - aa);
254                 do {
255                     *device = SkAlphaMulRGB16(*device, aa);
256                     device += 1;
257                 } while (--count != 0);
258                 continue;
259             }
260         }
261         device += count;
262     }
263 }
264 #endif
265
266 ///////////////////////////////////////////////////////////////////////////////
267 ///////////////////////////////////////////////////////////////////////////////
268
269 SkRGB16_Opaque_Blitter::SkRGB16_Opaque_Blitter(const SkBitmap& device,
270                                                const SkPaint& paint)
271 : INHERITED(device, paint) {}
272
273 void SkRGB16_Opaque_Blitter::blitH(int x, int y, int width) {
274     SkASSERT(width > 0);
275     SkASSERT(x + width <= fDevice.width());
276     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
277     uint16_t srcColor = fColor16;
278
279     SkASSERT(fRawColor16 == srcColor);
280     if (fDoDither) {
281         uint16_t ditherColor = fRawDither16;
282         if ((x ^ y) & 1) {
283             SkTSwap(ditherColor, srcColor);
284         }
285         sk_dither_memset16(device, srcColor, ditherColor, width);
286     } else {
287         sk_memset16(device, srcColor, width);
288     }
289 }
290
291 // return 1 or 0 from a bool
292 static inline int Bool2Int(int value) {
293     return !!value;
294 }
295
296 void SkRGB16_Opaque_Blitter::blitAntiH(int x, int y,
297                                        const SkAlpha* SK_RESTRICT antialias,
298                                        const int16_t* SK_RESTRICT runs) {
299     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
300     uint16_t    srcColor = fRawColor16;
301     uint32_t    srcExpanded = fExpandedRaw16;
302     int         ditherInt = Bool2Int(fDoDither);
303     uint16_t    ditherColor = fRawDither16;
304     // if we have no dithering, this will always fail
305     if ((x ^ y) & ditherInt) {
306         SkTSwap(ditherColor, srcColor);
307     }
308     for (;;) {
309         int count = runs[0];
310         SkASSERT(count >= 0);
311         if (count <= 0) {
312             return;
313         }
314         runs += count;
315
316         unsigned aa = antialias[0];
317         antialias += count;
318         if (aa) {
319             if (aa == 255) {
320                 if (ditherInt) {
321                     sk_dither_memset16(device, srcColor,
322                                        ditherColor, count);
323                 } else {
324                     sk_memset16(device, srcColor, count);
325                 }
326             } else {
327                 // TODO: respect fDoDither
328                 unsigned scale5 = SkAlpha255To256(aa) >> 3;
329                 uint32_t src32 = srcExpanded * scale5;
330                 scale5 = 32 - scale5; // now we can use it on the device
331                 int n = count;
332                 do {
333                     uint32_t dst32 = SkExpand_rgb_16(*device) * scale5;
334                     *device++ = SkCompact_rgb_16((src32 + dst32) >> 5);
335                 } while (--n != 0);
336                 goto DONE;
337             }
338         }
339         device += count;
340
341     DONE:
342         // if we have no dithering, this will always fail
343         if (count & ditherInt) {
344             SkTSwap(ditherColor, srcColor);
345         }
346     }
347 }
348
349 #define solid_8_pixels(mask, dst, color)    \
350     do {                                    \
351         if (mask & 0x80) dst[0] = color;    \
352         if (mask & 0x40) dst[1] = color;    \
353         if (mask & 0x20) dst[2] = color;    \
354         if (mask & 0x10) dst[3] = color;    \
355         if (mask & 0x08) dst[4] = color;    \
356         if (mask & 0x04) dst[5] = color;    \
357         if (mask & 0x02) dst[6] = color;    \
358         if (mask & 0x01) dst[7] = color;    \
359     } while (0)
360
361 #define SK_BLITBWMASK_NAME                  SkRGB16_BlitBW
362 #define SK_BLITBWMASK_ARGS                  , uint16_t color
363 #define SK_BLITBWMASK_BLIT8(mask, dst)      solid_8_pixels(mask, dst, color)
364 #define SK_BLITBWMASK_GETADDR               getAddr16
365 #define SK_BLITBWMASK_DEVTYPE               uint16_t
366 #include "SkBlitBWMaskTemplate.h"
367
368 static U16CPU blend_compact(uint32_t src32, uint32_t dst32, unsigned scale5) {
369     return SkCompact_rgb_16(dst32 + ((src32 - dst32) * scale5 >> 5));
370 }
371
372 void SkRGB16_Opaque_Blitter::blitMask(const SkMask& mask,
373                                       const SkIRect& clip) {
374     if (mask.fFormat == SkMask::kBW_Format) {
375         SkRGB16_BlitBW(fDevice, mask, clip, fColor16);
376         return;
377     }
378
379     uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop);
380     const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop);
381     int width = clip.width();
382     int height = clip.height();
383     size_t      deviceRB = fDevice.rowBytes() - (width << 1);
384     unsigned    maskRB = mask.fRowBytes - width;
385     uint32_t    expanded32 = fExpandedRaw16;
386
387 #if SK_ARM_NEON_IS_ALWAYS && defined(SK_CPU_LENDIAN)
388 #define    UNROLL    8
389     do {
390         int w = width;
391         if (w >= UNROLL) {
392             uint32x4_t color, dev_lo, dev_hi;
393             uint32x4_t wn1, wn2, tmp;
394             uint32x4_t vmask_g16, vmask_ng16;
395             uint16x8_t valpha, vdev;
396             uint16x4_t odev_lo, odev_hi, valpha_lo, valpha_hi;
397
398             // prepare constants
399             vmask_g16 = vdupq_n_u32(SK_G16_MASK_IN_PLACE);
400             vmask_ng16 = vdupq_n_u32(~SK_G16_MASK_IN_PLACE);
401             color = vdupq_n_u32(expanded32);
402
403             do {
404                 // alpha is 8x8, widen and split to get a pair of 16x4
405                 valpha = vaddw_u8(vdupq_n_u16(1), vld1_u8(alpha));
406                 valpha = vshrq_n_u16(valpha, 3);
407                 valpha_lo = vget_low_u16(valpha);
408                 valpha_hi = vget_high_u16(valpha);
409
410                 // load pixels
411                 vdev = vld1q_u16(device);
412                 dev_lo = vmovl_u16(vget_low_u16(vdev));
413                 dev_hi = vmovl_u16(vget_high_u16(vdev));
414
415                 // unpack them in 32 bits
416                 dev_lo = (dev_lo & vmask_ng16) | vshlq_n_u32(dev_lo & vmask_g16, 16);
417                 dev_hi = (dev_hi & vmask_ng16) | vshlq_n_u32(dev_hi & vmask_g16, 16);
418
419                 // blend with color
420                 tmp = (color - dev_lo) * vmovl_u16(valpha_lo);
421                 tmp = vshrq_n_u32(tmp, 5);
422                 dev_lo += tmp;
423
424                 tmp = vmulq_u32(color - dev_hi, vmovl_u16(valpha_hi));
425                 tmp = vshrq_n_u32(tmp, 5);
426                 dev_hi += tmp;
427
428                 // re-compact
429                 wn1 = dev_lo & vmask_ng16;
430                 wn2 = vshrq_n_u32(dev_lo, 16) & vmask_g16;
431                 odev_lo = vmovn_u32(wn1 | wn2);
432
433                 wn1 = dev_hi & vmask_ng16;
434                 wn2 = vshrq_n_u32(dev_hi, 16) & vmask_g16;
435                 odev_hi = vmovn_u32(wn1 | wn2);
436
437                 // store
438                 vst1q_u16(device, vcombine_u16(odev_lo, odev_hi));
439
440                 device += UNROLL;
441                 alpha += UNROLL;
442                 w -= UNROLL;
443             } while (w >= UNROLL);
444         }
445
446         // residuals
447         while (w > 0) {
448             *device = blend_compact(expanded32, SkExpand_rgb_16(*device),
449                                     SkAlpha255To256(*alpha++) >> 3);
450             device += 1;
451             --w;
452         }
453         device = (uint16_t*)((char*)device + deviceRB);
454         alpha += maskRB;
455     } while (--height != 0);
456 #undef    UNROLL
457 #else   // non-neon code
458     do {
459         int w = width;
460         do {
461             *device = blend_compact(expanded32, SkExpand_rgb_16(*device),
462                                     SkAlpha255To256(*alpha++) >> 3);
463             device += 1;
464         } while (--w != 0);
465         device = (uint16_t*)((char*)device + deviceRB);
466         alpha += maskRB;
467     } while (--height != 0);
468 #endif
469 }
470
471 void SkRGB16_Opaque_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
472     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
473     size_t    deviceRB = fDevice.rowBytes();
474
475     // TODO: respect fDoDither
476     unsigned scale5 = SkAlpha255To256(alpha) >> 3;
477     uint32_t src32 =  fExpandedRaw16 * scale5;
478     scale5 = 32 - scale5;
479     do {
480         uint32_t dst32 = SkExpand_rgb_16(*device) * scale5;
481         *device = SkCompact_rgb_16((src32 + dst32) >> 5);
482         device = (uint16_t*)((char*)device + deviceRB);
483     } while (--height != 0);
484 }
485
486 void SkRGB16_Opaque_Blitter::blitRect(int x, int y, int width, int height) {
487     SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height());
488     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
489     size_t      deviceRB = fDevice.rowBytes();
490     uint16_t    color16 = fColor16;
491
492     if (fDoDither) {
493         uint16_t ditherColor = fRawDither16;
494         if ((x ^ y) & 1) {
495             SkTSwap(ditherColor, color16);
496         }
497         while (--height >= 0) {
498             sk_dither_memset16(device, color16, ditherColor, width);
499             SkTSwap(ditherColor, color16);
500             device = (uint16_t*)((char*)device + deviceRB);
501         }
502     } else {  // no dither
503         while (--height >= 0) {
504             sk_memset16(device, color16, width);
505             device = (uint16_t*)((char*)device + deviceRB);
506         }
507     }
508 }
509
510 ///////////////////////////////////////////////////////////////////////////////
511
512 SkRGB16_Blitter::SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint)
513     : INHERITED(device) {
514     SkColor color = paint.getColor();
515
516     fSrcColor32 = SkPreMultiplyColor(color);
517     fScale = SkAlpha255To256(SkColorGetA(color));
518
519     int r = SkColorGetR(color);
520     int g = SkColorGetG(color);
521     int b = SkColorGetB(color);
522
523     fRawColor16 = fRawDither16 = SkPack888ToRGB16(r, g, b);
524     // if we're dithered, use fRawDither16 to hold that.
525     if ((fDoDither = paint.isDither()) != false) {
526         fRawDither16 = SkDitherPack888ToRGB16(r, g, b);
527     }
528
529     fExpandedRaw16 = SkExpand_rgb_16(fRawColor16);
530
531     fColor16 = SkPackRGB16( SkAlphaMul(r, fScale) >> (8 - SK_R16_BITS),
532                             SkAlphaMul(g, fScale) >> (8 - SK_G16_BITS),
533                             SkAlphaMul(b, fScale) >> (8 - SK_B16_BITS));
534 }
535
536 const SkBitmap* SkRGB16_Blitter::justAnOpaqueColor(uint32_t* value) {
537     if (!fDoDither && 256 == fScale) {
538         *value = fRawColor16;
539         return &fDevice;
540     }
541     return NULL;
542 }
543
544 static uint32_t pmcolor_to_expand16(SkPMColor c) {
545     unsigned r = SkGetPackedR32(c);
546     unsigned g = SkGetPackedG32(c);
547     unsigned b = SkGetPackedB32(c);
548     return (g << 24) | (r << 13) | (b << 2);
549 }
550
551 static inline void blend32_16_row(SkPMColor src, uint16_t dst[], int count) {
552     SkASSERT(count > 0);
553     uint32_t src_expand = pmcolor_to_expand16(src);
554     unsigned scale = SkAlpha255To256(0xFF - SkGetPackedA32(src)) >> 3;
555     do {
556         uint32_t dst_expand = SkExpand_rgb_16(*dst) * scale;
557         *dst = SkCompact_rgb_16((src_expand + dst_expand) >> 5);
558         dst += 1;
559     } while (--count != 0);
560 }
561
562 void SkRGB16_Blitter::blitH(int x, int y, int width) {
563     SkASSERT(width > 0);
564     SkASSERT(x + width <= fDevice.width());
565     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
566
567     // TODO: respect fDoDither
568     blend32_16_row(fSrcColor32, device, width);
569 }
570
571 void SkRGB16_Blitter::blitAntiH(int x, int y,
572                                 const SkAlpha* SK_RESTRICT antialias,
573                                 const int16_t* SK_RESTRICT runs) {
574     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
575     uint32_t    srcExpanded = fExpandedRaw16;
576     unsigned    scale = fScale;
577
578     // TODO: respect fDoDither
579     for (;;) {
580         int count = runs[0];
581         SkASSERT(count >= 0);
582         if (count <= 0) {
583             return;
584         }
585         runs += count;
586
587         unsigned aa = antialias[0];
588         antialias += count;
589         if (aa) {
590             unsigned scale5 = SkAlpha255To256(aa) * scale >> (8 + 3);
591             uint32_t src32 =  srcExpanded * scale5;
592             scale5 = 32 - scale5;
593             do {
594                 uint32_t dst32 = SkExpand_rgb_16(*device) * scale5;
595                 *device++ = SkCompact_rgb_16((src32 + dst32) >> 5);
596             } while (--count != 0);
597             continue;
598         }
599         device += count;
600     }
601 }
602
603 static inline void blend_8_pixels(U8CPU bw, uint16_t dst[], unsigned dst_scale,
604                                   U16CPU srcColor) {
605     if (bw & 0x80) dst[0] = srcColor + SkAlphaMulRGB16(dst[0], dst_scale);
606     if (bw & 0x40) dst[1] = srcColor + SkAlphaMulRGB16(dst[1], dst_scale);
607     if (bw & 0x20) dst[2] = srcColor + SkAlphaMulRGB16(dst[2], dst_scale);
608     if (bw & 0x10) dst[3] = srcColor + SkAlphaMulRGB16(dst[3], dst_scale);
609     if (bw & 0x08) dst[4] = srcColor + SkAlphaMulRGB16(dst[4], dst_scale);
610     if (bw & 0x04) dst[5] = srcColor + SkAlphaMulRGB16(dst[5], dst_scale);
611     if (bw & 0x02) dst[6] = srcColor + SkAlphaMulRGB16(dst[6], dst_scale);
612     if (bw & 0x01) dst[7] = srcColor + SkAlphaMulRGB16(dst[7], dst_scale);
613 }
614
615 #define SK_BLITBWMASK_NAME                  SkRGB16_BlendBW
616 #define SK_BLITBWMASK_ARGS                  , unsigned dst_scale, U16CPU src_color
617 #define SK_BLITBWMASK_BLIT8(mask, dst)      blend_8_pixels(mask, dst, dst_scale, src_color)
618 #define SK_BLITBWMASK_GETADDR               getAddr16
619 #define SK_BLITBWMASK_DEVTYPE               uint16_t
620 #include "SkBlitBWMaskTemplate.h"
621
622 void SkRGB16_Blitter::blitMask(const SkMask& mask,
623                                const SkIRect& clip) {
624     if (mask.fFormat == SkMask::kBW_Format) {
625         SkRGB16_BlendBW(fDevice, mask, clip, 256 - fScale, fColor16);
626         return;
627     }
628
629     uint16_t* SK_RESTRICT device = fDevice.getAddr16(clip.fLeft, clip.fTop);
630     const uint8_t* SK_RESTRICT alpha = mask.getAddr8(clip.fLeft, clip.fTop);
631     int width = clip.width();
632     int height = clip.height();
633     size_t      deviceRB = fDevice.rowBytes() - (width << 1);
634     unsigned    maskRB = mask.fRowBytes - width;
635     uint32_t    color32 = fExpandedRaw16;
636
637     unsigned scale256 = fScale;
638     do {
639         int w = width;
640         do {
641             unsigned aa = *alpha++;
642             unsigned scale = SkAlpha255To256(aa) * scale256 >> (8 + 3);
643             uint32_t src32 = color32 * scale;
644             uint32_t dst32 = SkExpand_rgb_16(*device) * (32 - scale);
645             *device++ = SkCompact_rgb_16((src32 + dst32) >> 5);
646         } while (--w != 0);
647         device = (uint16_t*)((char*)device + deviceRB);
648         alpha += maskRB;
649     } while (--height != 0);
650 }
651
652 void SkRGB16_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
653     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
654     size_t    deviceRB = fDevice.rowBytes();
655
656     // TODO: respect fDoDither
657     unsigned scale5 = SkAlpha255To256(alpha) * fScale >> (8 + 3);
658     uint32_t src32 =  fExpandedRaw16 * scale5;
659     scale5 = 32 - scale5;
660     do {
661         uint32_t dst32 = SkExpand_rgb_16(*device) * scale5;
662         *device = SkCompact_rgb_16((src32 + dst32) >> 5);
663         device = (uint16_t*)((char*)device + deviceRB);
664     } while (--height != 0);
665 }
666
667 void SkRGB16_Blitter::blitRect(int x, int y, int width, int height) {
668     SkASSERT(x + width <= fDevice.width() && y + height <= fDevice.height());
669     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
670     size_t    deviceRB = fDevice.rowBytes();
671     SkPMColor src32 = fSrcColor32;
672
673     while (--height >= 0) {
674         blend32_16_row(src32, device, width);
675         device = (uint16_t*)((char*)device + deviceRB);
676     }
677 }
678
679 ///////////////////////////////////////////////////////////////////////////////
680
681 SkRGB16_Shader16_Blitter::SkRGB16_Shader16_Blitter(const SkBitmap& device,
682                                                    const SkPaint& paint)
683     : SkRGB16_Shader_Blitter(device, paint) {
684     SkASSERT(SkShader::CanCallShadeSpan16(fShaderFlags));
685 }
686
687 void SkRGB16_Shader16_Blitter::blitH(int x, int y, int width) {
688     SkASSERT(x + width <= fDevice.width());
689
690     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
691     SkShader*   shader = fShader;
692
693     int alpha = shader->getSpan16Alpha();
694     if (0xFF == alpha) {
695         shader->shadeSpan16(x, y, device, width);
696     } else {
697         uint16_t* span16 = (uint16_t*)fBuffer;
698         shader->shadeSpan16(x, y, span16, width);
699         SkBlendRGB16(span16, device, SkAlpha255To256(alpha), width);
700     }
701 }
702
703 void SkRGB16_Shader16_Blitter::blitRect(int x, int y, int width, int height) {
704     SkShader*   shader = fShader;
705     uint16_t*   dst = fDevice.getAddr16(x, y);
706     size_t      dstRB = fDevice.rowBytes();
707     int         alpha = shader->getSpan16Alpha();
708
709     if (0xFF == alpha) {
710         if (fShaderFlags & SkShader::kConstInY16_Flag) {
711             // have the shader blit directly into the device the first time
712             shader->shadeSpan16(x, y, dst, width);
713             // and now just memcpy that line on the subsequent lines
714             if (--height > 0) {
715                 const uint16_t* orig = dst;
716                 do {
717                     dst = (uint16_t*)((char*)dst + dstRB);
718                     memcpy(dst, orig, width << 1);
719                 } while (--height);
720             }
721         } else {    // need to call shadeSpan16 for every line
722             do {
723                 shader->shadeSpan16(x, y, dst, width);
724                 y += 1;
725                 dst = (uint16_t*)((char*)dst + dstRB);
726             } while (--height);
727         }
728     } else {
729         int scale = SkAlpha255To256(alpha);
730         uint16_t* span16 = (uint16_t*)fBuffer;
731         if (fShaderFlags & SkShader::kConstInY16_Flag) {
732             shader->shadeSpan16(x, y, span16, width);
733             do {
734                 SkBlendRGB16(span16, dst, scale, width);
735                 dst = (uint16_t*)((char*)dst + dstRB);
736             } while (--height);
737         } else {
738             do {
739                 shader->shadeSpan16(x, y, span16, width);
740                 SkBlendRGB16(span16, dst, scale, width);
741                 y += 1;
742                 dst = (uint16_t*)((char*)dst + dstRB);
743             } while (--height);
744         }
745     }
746 }
747
748 void SkRGB16_Shader16_Blitter::blitAntiH(int x, int y,
749                                          const SkAlpha* SK_RESTRICT antialias,
750                                          const int16_t* SK_RESTRICT runs) {
751     SkShader*   shader = fShader;
752     SkPMColor* SK_RESTRICT span = fBuffer;
753     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
754
755     int alpha = shader->getSpan16Alpha();
756     uint16_t* span16 = (uint16_t*)span;
757
758     if (0xFF == alpha) {
759         for (;;) {
760             int count = *runs;
761             if (count <= 0) {
762                 break;
763             }
764             SkASSERT(count <= fDevice.width()); // don't overrun fBuffer
765
766             int aa = *antialias;
767             if (aa == 255) {
768                 // go direct to the device!
769                 shader->shadeSpan16(x, y, device, count);
770             } else if (aa) {
771                 shader->shadeSpan16(x, y, span16, count);
772                 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count);
773             }
774             device += count;
775             runs += count;
776             antialias += count;
777             x += count;
778         }
779     } else {  // span alpha is < 255
780         alpha = SkAlpha255To256(alpha);
781         for (;;) {
782             int count = *runs;
783             if (count <= 0) {
784                 break;
785             }
786             SkASSERT(count <= fDevice.width()); // don't overrun fBuffer
787
788             int aa = SkAlphaMul(*antialias, alpha);
789             if (aa) {
790                 shader->shadeSpan16(x, y, span16, count);
791                 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count);
792             }
793
794             device += count;
795             runs += count;
796             antialias += count;
797             x += count;
798         }
799     }
800 }
801
802 ///////////////////////////////////////////////////////////////////////////////
803
804 SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkBitmap& device,
805                                                const SkPaint& paint)
806 : INHERITED(device, paint) {
807     SkASSERT(paint.getXfermode() == NULL);
808
809     fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor));
810
811     // compute SkBlitRow::Procs
812     unsigned flags = 0;
813
814     uint32_t shaderFlags = fShaderFlags;
815     // shaders take care of global alpha, so we never set it in SkBlitRow
816     if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) {
817         flags |= SkBlitRow::kSrcPixelAlpha_Flag;
818     }
819     // don't dither if the shader is really 16bit
820     if (paint.isDither() && !(shaderFlags & SkShader::kIntrinsicly16_Flag)) {
821         flags |= SkBlitRow::kDither_Flag;
822     }
823     // used when we know our global alpha is 0xFF
824     fOpaqueProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config);
825     // used when we know our global alpha is < 0xFF
826     fAlphaProc  = SkBlitRow::Factory(flags | SkBlitRow::kGlobalAlpha_Flag,
827                                      SkBitmap::kRGB_565_Config);
828 }
829
830 SkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() {
831     sk_free(fBuffer);
832 }
833
834 void SkRGB16_Shader_Blitter::blitH(int x, int y, int width) {
835     SkASSERT(x + width <= fDevice.width());
836
837     fShader->shadeSpan(x, y, fBuffer, width);
838     // shaders take care of global alpha, so we pass 0xFF (should be ignored)
839     fOpaqueProc(fDevice.getAddr16(x, y), fBuffer, width, 0xFF, x, y);
840 }
841
842 void SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) {
843     SkShader*       shader = fShader;
844     SkBlitRow::Proc proc = fOpaqueProc;
845     SkPMColor*      buffer = fBuffer;
846     uint16_t*       dst = fDevice.getAddr16(x, y);
847     size_t          dstRB = fDevice.rowBytes();
848
849     if (fShaderFlags & SkShader::kConstInY32_Flag) {
850         shader->shadeSpan(x, y, buffer, width);
851         do {
852             proc(dst, buffer, width, 0xFF, x, y);
853             y += 1;
854             dst = (uint16_t*)((char*)dst + dstRB);
855         } while (--height);
856     } else {
857         do {
858             shader->shadeSpan(x, y, buffer, width);
859             proc(dst, buffer, width, 0xFF, x, y);
860             y += 1;
861             dst = (uint16_t*)((char*)dst + dstRB);
862         } while (--height);
863     }
864 }
865
866 static inline int count_nonzero_span(const int16_t runs[], const SkAlpha aa[]) {
867     int count = 0;
868     for (;;) {
869         int n = *runs;
870         if (n == 0 || *aa == 0) {
871             break;
872         }
873         runs += n;
874         aa += n;
875         count += n;
876     }
877     return count;
878 }
879
880 void SkRGB16_Shader_Blitter::blitAntiH(int x, int y,
881                                        const SkAlpha* SK_RESTRICT antialias,
882                                        const int16_t* SK_RESTRICT runs) {
883     SkShader*   shader = fShader;
884     SkPMColor* SK_RESTRICT span = fBuffer;
885     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
886
887     for (;;) {
888         int count = *runs;
889         if (count <= 0) {
890             break;
891         }
892         int aa = *antialias;
893         if (0 == aa) {
894             device += count;
895             runs += count;
896             antialias += count;
897             x += count;
898             continue;
899         }
900
901         int nonZeroCount = count + count_nonzero_span(runs + count, antialias + count);
902
903         SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer
904         shader->shadeSpan(x, y, span, nonZeroCount);
905
906         SkPMColor* localSpan = span;
907         for (;;) {
908             SkBlitRow::Proc proc = (aa == 0xFF) ? fOpaqueProc : fAlphaProc;
909             proc(device, localSpan, count, aa, x, y);
910
911             x += count;
912             device += count;
913             runs += count;
914             antialias += count;
915             nonZeroCount -= count;
916             if (nonZeroCount == 0) {
917                 break;
918             }
919             localSpan += count;
920             SkASSERT(nonZeroCount > 0);
921             count = *runs;
922             SkASSERT(count > 0);
923             aa = *antialias;
924         }
925     }
926 }
927
928 ///////////////////////////////////////////////////////////////////////
929
930 SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter(
931                                 const SkBitmap& device, const SkPaint& paint)
932 : INHERITED(device, paint) {
933     fXfermode = paint.getXfermode();
934     SkASSERT(fXfermode);
935     fXfermode->ref();
936
937     int width = device.width();
938     fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * sizeof(SkPMColor));
939     fAAExpand = (uint8_t*)(fBuffer + width);
940 }
941
942 SkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() {
943     fXfermode->unref();
944     sk_free(fBuffer);
945 }
946
947 void SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) {
948     SkASSERT(x + width <= fDevice.width());
949
950     uint16_t*   device = fDevice.getAddr16(x, y);
951     SkPMColor*  span = fBuffer;
952
953     fShader->shadeSpan(x, y, span, width);
954     fXfermode->xfer16(device, span, width, NULL);
955 }
956
957 void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y,
958                                 const SkAlpha* SK_RESTRICT antialias,
959                                 const int16_t* SK_RESTRICT runs) {
960     SkShader*   shader = fShader;
961     SkXfermode* mode = fXfermode;
962     SkPMColor* SK_RESTRICT span = fBuffer;
963     uint8_t* SK_RESTRICT aaExpand = fAAExpand;
964     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
965
966     for (;;) {
967         int count = *runs;
968         if (count <= 0) {
969             break;
970         }
971         int aa = *antialias;
972         if (0 == aa) {
973             device += count;
974             runs += count;
975             antialias += count;
976             x += count;
977             continue;
978         }
979
980         int nonZeroCount = count + count_nonzero_span(runs + count,
981                                                       antialias + count);
982
983         SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer
984         shader->shadeSpan(x, y, span, nonZeroCount);
985
986         x += nonZeroCount;
987         SkPMColor* localSpan = span;
988         for (;;) {
989             if (aa == 0xFF) {
990                 mode->xfer16(device, localSpan, count, NULL);
991             } else {
992                 SkASSERT(aa);
993                 memset(aaExpand, aa, count);
994                 mode->xfer16(device, localSpan, count, aaExpand);
995             }
996             device += count;
997             runs += count;
998             antialias += count;
999             nonZeroCount -= count;
1000             if (nonZeroCount == 0) {
1001                 break;
1002             }
1003             localSpan += count;
1004             SkASSERT(nonZeroCount > 0);
1005             count = *runs;
1006             SkASSERT(count > 0);
1007             aa = *antialias;
1008         }
1009     }
1010 }
1011
1012 ///////////////////////////////////////////////////////////////////////////////
1013
1014 SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint,
1015         SkTBlitterAllocator* allocator) {
1016     SkASSERT(allocator != NULL);
1017
1018     SkBlitter* blitter;
1019     SkShader* shader = paint.getShader();
1020     SkXfermode* mode = paint.getXfermode();
1021
1022     // we require a shader if there is an xfermode, handled by our caller
1023     SkASSERT(NULL == mode || NULL != shader);
1024
1025     if (shader) {
1026         if (mode) {
1027             blitter = allocator->createT<SkRGB16_Shader_Xfermode_Blitter>(device, paint);
1028         } else if (shader->canCallShadeSpan16()) {
1029             blitter = allocator->createT<SkRGB16_Shader16_Blitter>(device, paint);
1030         } else {
1031             blitter = allocator->createT<SkRGB16_Shader_Blitter>(device, paint);
1032         }
1033     } else {
1034         // no shader, no xfermode, (and we always ignore colorfilter)
1035         SkColor color = paint.getColor();
1036         if (0 == SkColorGetA(color)) {
1037             blitter = allocator->createT<SkNullBlitter>();
1038 #ifdef USE_BLACK_BLITTER
1039         } else if (SK_ColorBLACK == color) {
1040             blitter = allocator->createT<SkRGB16_Black_Blitter>(device, paint);
1041 #endif
1042         } else if (0xFF == SkColorGetA(color)) {
1043             blitter = allocator->createT<SkRGB16_Opaque_Blitter>(device, paint);
1044         } else {
1045             blitter = allocator->createT<SkRGB16_Blitter>(device, paint);
1046         }
1047     }
1048
1049     return blitter;
1050 }