gfx/skia/trunk/src/core/SkBlitter_RGB16.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     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  */
    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 "SkXfermode.h"
    18 #if defined(__ARM_HAVE_NEON) && defined(SK_CPU_LENDIAN)
    19     #define SK_USE_NEON
    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
    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         }
    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
    45         if (count & 1) {
    46             dst[count - 1] = value;
    47         }
    48     }
    49 }
    51 ///////////////////////////////////////////////////////////////////////////////
    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*);
    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;
    74     // illegal
    75     SkRGB16_Blitter& operator=(const SkRGB16_Blitter&);
    77     typedef SkRasterBlitter INHERITED;
    78 };
    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&);
    91 private:
    92     typedef SkRGB16_Blitter INHERITED;
    93 };
    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);
   103 private:
   104     typedef SkRGB16_Opaque_Blitter INHERITED;
   105 };
   106 #endif
   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);
   117 protected:
   118     SkPMColor*      fBuffer;
   119     SkBlitRow::Proc fOpaqueProc;
   120     SkBlitRow::Proc fAlphaProc;
   122 private:
   123     // illegal
   124     SkRGB16_Shader_Blitter& operator=(const SkRGB16_Shader_Blitter&);
   126     typedef SkShaderBlitter INHERITED;
   127 };
   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);
   138 private:
   139     typedef SkRGB16_Shader_Blitter INHERITED;
   140 };
   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);
   150 private:
   151     SkXfermode* fXfermode;
   152     SkPMColor*  fBuffer;
   153     uint8_t*    fAAExpand;
   155     // illegal
   156     SkRGB16_Shader_Xfermode_Blitter& operator=(const SkRGB16_Shader_Xfermode_Blitter&);
   158     typedef SkShaderBlitter INHERITED;
   159 };
   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 }
   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
   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"
   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;
   216         SkASSERT((int)height > 0);
   217         SkASSERT((int)width > 0);
   218         SkASSERT((int)deviceRB >= 0);
   219         SkASSERT((int)maskRB >= 0);
   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 }
   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);
   239     for (;;) {
   240         int count = runs[0];
   241         SkASSERT(count >= 0);
   242         if (count <= 0) {
   243             return;
   244         }
   245         runs += count;
   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
   266 ///////////////////////////////////////////////////////////////////////////////
   267 ///////////////////////////////////////////////////////////////////////////////
   269 SkRGB16_Opaque_Blitter::SkRGB16_Opaque_Blitter(const SkBitmap& device,
   270                                                const SkPaint& paint)
   271 : INHERITED(device, paint) {}
   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;
   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 }
   291 // return 1 or 0 from a bool
   292 static inline int Bool2Int(int value) {
   293     return !!value;
   294 }
   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;
   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;
   341     DONE:
   342         // if we have no dithering, this will always fail
   343         if (count & ditherInt) {
   344             SkTSwap(ditherColor, srcColor);
   345         }
   346     }
   347 }
   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)
   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"
   368 static U16CPU blend_compact(uint32_t src32, uint32_t dst32, unsigned scale5) {
   369     return SkCompact_rgb_16(dst32 + ((src32 - dst32) * scale5 >> 5));
   370 }
   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     }
   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;
   387 #ifdef SK_USE_NEON
   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;
   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);
   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);
   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));
   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);
   419                 // blend with color
   420                 tmp = (color - dev_lo) * vmovl_u16(valpha_lo);
   421                 tmp = vshrq_n_u32(tmp, 5);
   422                 dev_lo += tmp;
   424                 tmp = vmulq_u32(color - dev_hi, vmovl_u16(valpha_hi));
   425                 tmp = vshrq_n_u32(tmp, 5);
   426                 dev_hi += tmp;
   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);
   433                 wn1 = dev_hi & vmask_ng16;
   434                 wn2 = vshrq_n_u32(dev_hi, 16) & vmask_g16;
   435                 odev_hi = vmovn_u32(wn1 | wn2);
   437                 // store
   438                 vst1q_u16(device, vcombine_u16(odev_lo, odev_hi));
   440                 device += UNROLL;
   441                 alpha += UNROLL;
   442                 w -= UNROLL;
   443             } while (w >= UNROLL);
   444         }
   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 }
   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();
   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 }
   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;
   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 }
   510 ///////////////////////////////////////////////////////////////////////////////
   512 SkRGB16_Blitter::SkRGB16_Blitter(const SkBitmap& device, const SkPaint& paint)
   513     : INHERITED(device) {
   514     SkColor color = paint.getColor();
   516     fSrcColor32 = SkPreMultiplyColor(color);
   517     fScale = SkAlpha255To256(SkColorGetA(color));
   519     int r = SkColorGetR(color);
   520     int g = SkColorGetG(color);
   521     int b = SkColorGetB(color);
   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     }
   529     fExpandedRaw16 = SkExpand_rgb_16(fRawColor16);
   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 }
   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 }
   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 }
   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 }
   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);
   567     // TODO: respect fDoDither
   568     blend32_16_row(fSrcColor32, device, width);
   569 }
   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;
   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;
   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 }
   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 }
   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"
   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     }
   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;
   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 }
   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();
   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 }
   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;
   673     while (--height >= 0) {
   674         blend32_16_row(src32, device, width);
   675         device = (uint16_t*)((char*)device + deviceRB);
   676     }
   677 }
   679 ///////////////////////////////////////////////////////////////////////////////
   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 }
   687 void SkRGB16_Shader16_Blitter::blitH(int x, int y, int width) {
   688     SkASSERT(x + width <= fDevice.width());
   690     uint16_t* SK_RESTRICT device = fDevice.getAddr16(x, y);
   691     SkShader*   shader = fShader;
   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 }
   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();
   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 }
   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);
   755     int alpha = shader->getSpan16Alpha();
   756     uint16_t* span16 = (uint16_t*)span;
   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
   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
   788             int aa = SkAlphaMul(*antialias, alpha);
   789             if (aa) {
   790                 shader->shadeSpan16(x, y, span16, count);
   791                 SkBlendRGB16(span16, device, SkAlpha255To256(aa), count);
   792             }
   794             device += count;
   795             runs += count;
   796             antialias += count;
   797             x += count;
   798         }
   799     }
   800 }
   802 ///////////////////////////////////////////////////////////////////////////////
   804 SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkBitmap& device,
   805                                                const SkPaint& paint)
   806 : INHERITED(device, paint) {
   807     SkASSERT(paint.getXfermode() == NULL);
   809     fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * sizeof(SkPMColor));
   811     // compute SkBlitRow::Procs
   812     unsigned flags = 0;
   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 }
   830 SkRGB16_Shader_Blitter::~SkRGB16_Shader_Blitter() {
   831     sk_free(fBuffer);
   832 }
   834 void SkRGB16_Shader_Blitter::blitH(int x, int y, int width) {
   835     SkASSERT(x + width <= fDevice.width());
   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 }
   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();
   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 }
   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 }
   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);
   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         }
   901         int nonZeroCount = count + count_nonzero_span(runs + count, antialias + count);
   903         SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer
   904         shader->shadeSpan(x, y, span, nonZeroCount);
   906         SkPMColor* localSpan = span;
   907         for (;;) {
   908             SkBlitRow::Proc proc = (aa == 0xFF) ? fOpaqueProc : fAlphaProc;
   909             proc(device, localSpan, count, aa, x, y);
   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 }
   928 ///////////////////////////////////////////////////////////////////////
   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();
   937     int width = device.width();
   938     fBuffer = (SkPMColor*)sk_malloc_throw((width + (SkAlign4(width) >> 2)) * sizeof(SkPMColor));
   939     fAAExpand = (uint8_t*)(fBuffer + width);
   940 }
   942 SkRGB16_Shader_Xfermode_Blitter::~SkRGB16_Shader_Xfermode_Blitter() {
   943     fXfermode->unref();
   944     sk_free(fBuffer);
   945 }
   947 void SkRGB16_Shader_Xfermode_Blitter::blitH(int x, int y, int width) {
   948     SkASSERT(x + width <= fDevice.width());
   950     uint16_t*   device = fDevice.getAddr16(x, y);
   951     SkPMColor*  span = fBuffer;
   953     fShader->shadeSpan(x, y, span, width);
   954     fXfermode->xfer16(device, span, width, NULL);
   955 }
   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);
   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         }
   980         int nonZeroCount = count + count_nonzero_span(runs + count,
   981                                                       antialias + count);
   983         SkASSERT(nonZeroCount <= fDevice.width()); // don't overrun fBuffer
   984         shader->shadeSpan(x, y, span, nonZeroCount);
   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;
  1003             localSpan += count;
  1004             SkASSERT(nonZeroCount > 0);
  1005             count = *runs;
  1006             SkASSERT(count > 0);
  1007             aa = *antialias;
  1012 ///////////////////////////////////////////////////////////////////////////////
  1014 SkBlitter* SkBlitter_ChooseD565(const SkBitmap& device, const SkPaint& paint,
  1015         SkTBlitterAllocator* allocator) {
  1016     SkASSERT(allocator != NULL);
  1018     SkBlitter* blitter;
  1019     SkShader* shader = paint.getShader();
  1020     SkXfermode* mode = paint.getXfermode();
  1022     // we require a shader if there is an xfermode, handled by our caller
  1023     SkASSERT(NULL == mode || NULL != shader);
  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);
  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);
  1049     return blitter;

mercurial