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