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

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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 "SkSpriteBlitter.h"
    11 #include "SkBlitRow.h"
    12 #include "SkTemplates.h"
    13 #include "SkUtils.h"
    14 #include "SkColorPriv.h"
    16 #define D16_S32A_Opaque_Pixel(dst, sc)                                        \
    17 do {                                                                          \
    18     if (sc) {                                                                 \
    19         *dst = SkSrcOver32To16(sc, *dst);                                     \
    20     }                                                                         \
    21 } while (0)
    23 static inline void D16_S32A_Blend_Pixel_helper(uint16_t* dst, SkPMColor sc,
    24                                                unsigned src_scale) {
    25     uint16_t dc = *dst;
    26     unsigned sa = SkGetPackedA32(sc);
    27     unsigned dr, dg, db;
    29     if (255 == sa) {
    30         dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), src_scale);
    31         dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale);
    32         db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_scale);
    33     } else {
    34         unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale);
    35         dr = (SkPacked32ToR16(sc) * src_scale +
    36               SkGetPackedR16(dc) * dst_scale) >> 8;
    37         dg = (SkPacked32ToG16(sc) * src_scale +
    38               SkGetPackedG16(dc) * dst_scale) >> 8;
    39         db = (SkPacked32ToB16(sc) * src_scale +
    40               SkGetPackedB16(dc) * dst_scale) >> 8;
    41     }
    42     *dst = SkPackRGB16(dr, dg, db);
    43 }
    45 #define D16_S32A_Blend_Pixel(dst, sc, src_scale) \
    46     do { if (sc) D16_S32A_Blend_Pixel_helper(dst, sc, src_scale); } while (0)
    49 ///////////////////////////////////////////////////////////////////////////////
    51 class Sprite_D16_S16_Opaque : public SkSpriteBlitter {
    52 public:
    53     Sprite_D16_S16_Opaque(const SkBitmap& source)
    54         : SkSpriteBlitter(source) {}
    56     // overrides
    57     virtual void blitRect(int x, int y, int width, int height) {
    58         uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y);
    59         const uint16_t* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
    60                                                              y - fTop);
    61         size_t dstRB = fDevice->rowBytes();
    62         size_t srcRB = fSource->rowBytes();
    64         while (--height >= 0) {
    65             memcpy(dst, src, width << 1);
    66             dst = (uint16_t*)((char*)dst + dstRB);
    67             src = (const uint16_t*)((const char*)src + srcRB);
    68         }
    69     }
    70 };
    72 #define D16_S16_Blend_Pixel(dst, sc, scale)     \
    73     do {                                        \
    74         uint16_t dc = *dst;                     \
    75         *dst = SkBlendRGB16(sc, dc, scale);     \
    76     } while (0)
    78 #define SkSPRITE_CLASSNAME                  Sprite_D16_S16_Blend
    79 #define SkSPRITE_ARGS                       , uint8_t alpha
    80 #define SkSPRITE_FIELDS                     uint8_t  fSrcAlpha;
    81 #define SkSPRITE_INIT                       fSrcAlpha = alpha;
    82 #define SkSPRITE_DST_TYPE                   uint16_t
    83 #define SkSPRITE_SRC_TYPE                   uint16_t
    84 #define SkSPRITE_DST_GETADDR                getAddr16
    85 #define SkSPRITE_SRC_GETADDR                getAddr16
    86 #define SkSPRITE_PREAMBLE(srcBM, x, y)      int scale = SkAlpha255To256(fSrcAlpha);
    87 #define SkSPRITE_BLIT_PIXEL(dst, src)       D16_S16_Blend_Pixel(dst, src, scale)
    88 #define SkSPRITE_NEXT_ROW
    89 #define SkSPRITE_POSTAMBLE(srcBM)
    90 #include "SkSpriteBlitterTemplate.h"
    92 ///////////////////////////////////////////////////////////////////////////////
    94 #define D16_S4444_Opaque(dst, sc)           \
    95     do {                                    \
    96         uint16_t dc = *dst;                 \
    97         *dst = SkSrcOver4444To16(sc, dc);   \
    98     } while (0)
   100 #define SkSPRITE_CLASSNAME                  Sprite_D16_S4444_Opaque
   101 #define SkSPRITE_ARGS
   102 #define SkSPRITE_FIELDS
   103 #define SkSPRITE_INIT
   104 #define SkSPRITE_DST_TYPE                   uint16_t
   105 #define SkSPRITE_SRC_TYPE                   SkPMColor16
   106 #define SkSPRITE_DST_GETADDR                getAddr16
   107 #define SkSPRITE_SRC_GETADDR                getAddr16
   108 #define SkSPRITE_PREAMBLE(srcBM, x, y)
   109 #define SkSPRITE_BLIT_PIXEL(dst, src)       D16_S4444_Opaque(dst, src)
   110 #define SkSPRITE_NEXT_ROW
   111 #define SkSPRITE_POSTAMBLE(srcBM)
   112 #include "SkSpriteBlitterTemplate.h"
   114 #define D16_S4444_Blend(dst, sc, scale16)           \
   115     do {                                            \
   116         uint16_t dc = *dst;                         \
   117         *dst = SkBlend4444To16(sc, dc, scale16);    \
   118     } while (0)
   121 #define SkSPRITE_CLASSNAME                  Sprite_D16_S4444_Blend
   122 #define SkSPRITE_ARGS                       , uint8_t alpha
   123 #define SkSPRITE_FIELDS                     uint8_t  fSrcAlpha;
   124 #define SkSPRITE_INIT                       fSrcAlpha = alpha;
   125 #define SkSPRITE_DST_TYPE                   uint16_t
   126 #define SkSPRITE_SRC_TYPE                   uint16_t
   127 #define SkSPRITE_DST_GETADDR                getAddr16
   128 #define SkSPRITE_SRC_GETADDR                getAddr16
   129 #define SkSPRITE_PREAMBLE(srcBM, x, y)      int scale = SkAlpha15To16(fSrcAlpha);
   130 #define SkSPRITE_BLIT_PIXEL(dst, src)       D16_S4444_Blend(dst, src, scale)
   131 #define SkSPRITE_NEXT_ROW
   132 #define SkSPRITE_POSTAMBLE(srcBM)
   133 #include "SkSpriteBlitterTemplate.h"
   135 ///////////////////////////////////////////////////////////////////////////////
   137 #define SkSPRITE_CLASSNAME                  Sprite_D16_SIndex8A_Opaque
   138 #define SkSPRITE_ARGS
   139 #define SkSPRITE_FIELDS
   140 #define SkSPRITE_INIT
   141 #define SkSPRITE_DST_TYPE                   uint16_t
   142 #define SkSPRITE_SRC_TYPE                   uint8_t
   143 #define SkSPRITE_DST_GETADDR                getAddr16
   144 #define SkSPRITE_SRC_GETADDR                getAddr8
   145 #define SkSPRITE_PREAMBLE(srcBM, x, y)      const SkPMColor* ctable = srcBM.getColorTable()->lockColors()
   146 #define SkSPRITE_BLIT_PIXEL(dst, src)       D16_S32A_Opaque_Pixel(dst, ctable[src])
   147 #define SkSPRITE_NEXT_ROW
   148 #define SkSPRITE_POSTAMBLE(srcBM)           srcBM.getColorTable()->unlockColors()
   149 #include "SkSpriteBlitterTemplate.h"
   151 #define SkSPRITE_CLASSNAME                  Sprite_D16_SIndex8A_Blend
   152 #define SkSPRITE_ARGS                       , uint8_t alpha
   153 #define SkSPRITE_FIELDS                     uint8_t fSrcAlpha;
   154 #define SkSPRITE_INIT                       fSrcAlpha = alpha;
   155 #define SkSPRITE_DST_TYPE                   uint16_t
   156 #define SkSPRITE_SRC_TYPE                   uint8_t
   157 #define SkSPRITE_DST_GETADDR                getAddr16
   158 #define SkSPRITE_SRC_GETADDR                getAddr8
   159 #define SkSPRITE_PREAMBLE(srcBM, x, y)      const SkPMColor* ctable = srcBM.getColorTable()->lockColors(); unsigned src_scale = SkAlpha255To256(fSrcAlpha);
   160 #define SkSPRITE_BLIT_PIXEL(dst, src)       D16_S32A_Blend_Pixel(dst, ctable[src], src_scale)
   161 #define SkSPRITE_NEXT_ROW
   162 #define SkSPRITE_POSTAMBLE(srcBM)           srcBM.getColorTable()->unlockColors();
   163 #include "SkSpriteBlitterTemplate.h"
   165 ///////////////////////////////////////////////////////////////////////////////
   167 static intptr_t asint(const void* ptr) {
   168     return reinterpret_cast<const char*>(ptr) - (const char*)0;
   169 }
   171 static void blitrow_d16_si8(uint16_t* SK_RESTRICT dst,
   172                             const uint8_t* SK_RESTRICT src, int count,
   173                             const uint16_t* SK_RESTRICT ctable) {
   174     if (count <= 8) {
   175         do {
   176             *dst++ = ctable[*src++];
   177         } while (--count);
   178         return;
   179     }
   181     // eat src until we're on a 4byte boundary
   182     while (asint(src) & 3) {
   183         *dst++ = ctable[*src++];
   184         count -= 1;
   185     }
   187     int qcount = count >> 2;
   188     SkASSERT(qcount > 0);
   189     const uint32_t* qsrc = reinterpret_cast<const uint32_t*>(src);
   190     if (asint(dst) & 2) {
   191         do {
   192             uint32_t s4 = *qsrc++;
   193 #ifdef SK_CPU_LENDIAN
   194             *dst++ = ctable[s4 & 0xFF];
   195             *dst++ = ctable[(s4 >> 8) & 0xFF];
   196             *dst++ = ctable[(s4 >> 16) & 0xFF];
   197             *dst++ = ctable[s4 >> 24];
   198 #else   // BENDIAN
   199             *dst++ = ctable[s4 >> 24];
   200             *dst++ = ctable[(s4 >> 16) & 0xFF];
   201             *dst++ = ctable[(s4 >> 8) & 0xFF];
   202             *dst++ = ctable[s4 & 0xFF];
   203 #endif
   204         } while (--qcount);
   205     } else {    // dst is on a 4byte boundary
   206         uint32_t* ddst = reinterpret_cast<uint32_t*>(dst);
   207         do {
   208             uint32_t s4 = *qsrc++;
   209 #ifdef SK_CPU_LENDIAN
   210             *ddst++ = (ctable[(s4 >> 8) & 0xFF] << 16) | ctable[s4 & 0xFF];
   211             *ddst++ = (ctable[s4 >> 24] << 16) | ctable[(s4 >> 16) & 0xFF];
   212 #else   // BENDIAN
   213             *ddst++ = (ctable[s4 >> 24] << 16) | ctable[(s4 >> 16) & 0xFF];
   214             *ddst++ = (ctable[(s4 >> 8) & 0xFF] << 16) | ctable[s4 & 0xFF];
   215 #endif
   216         } while (--qcount);
   217         dst = reinterpret_cast<uint16_t*>(ddst);
   218     }
   219     src = reinterpret_cast<const uint8_t*>(qsrc);
   220     count &= 3;
   221     // catch any remaining (will be < 4)
   222     while (--count >= 0) {
   223         *dst++ = ctable[*src++];
   224     }
   225 }
   227 #define SkSPRITE_ROW_PROC(d, s, n, x, y)    blitrow_d16_si8(d, s, n, ctable)
   229 #define SkSPRITE_CLASSNAME                  Sprite_D16_SIndex8_Opaque
   230 #define SkSPRITE_ARGS
   231 #define SkSPRITE_FIELDS
   232 #define SkSPRITE_INIT
   233 #define SkSPRITE_DST_TYPE                   uint16_t
   234 #define SkSPRITE_SRC_TYPE                   uint8_t
   235 #define SkSPRITE_DST_GETADDR                getAddr16
   236 #define SkSPRITE_SRC_GETADDR                getAddr8
   237 #define SkSPRITE_PREAMBLE(srcBM, x, y)      const uint16_t* ctable = srcBM.getColorTable()->lock16BitCache()
   238 #define SkSPRITE_BLIT_PIXEL(dst, src)       *dst = ctable[src]
   239 #define SkSPRITE_NEXT_ROW
   240 #define SkSPRITE_POSTAMBLE(srcBM)           srcBM.getColorTable()->unlock16BitCache()
   241 #include "SkSpriteBlitterTemplate.h"
   243 #define SkSPRITE_CLASSNAME                  Sprite_D16_SIndex8_Blend
   244 #define SkSPRITE_ARGS                       , uint8_t alpha
   245 #define SkSPRITE_FIELDS                     uint8_t fSrcAlpha;
   246 #define SkSPRITE_INIT                       fSrcAlpha = alpha;
   247 #define SkSPRITE_DST_TYPE                   uint16_t
   248 #define SkSPRITE_SRC_TYPE                   uint8_t
   249 #define SkSPRITE_DST_GETADDR                getAddr16
   250 #define SkSPRITE_SRC_GETADDR                getAddr8
   251 #define SkSPRITE_PREAMBLE(srcBM, x, y)      const uint16_t* ctable = srcBM.getColorTable()->lock16BitCache(); unsigned src_scale = SkAlpha255To256(fSrcAlpha);
   252 #define SkSPRITE_BLIT_PIXEL(dst, src)       D16_S16_Blend_Pixel(dst, ctable[src], src_scale)
   253 #define SkSPRITE_NEXT_ROW
   254 #define SkSPRITE_POSTAMBLE(srcBM)           srcBM.getColorTable()->unlock16BitCache();
   255 #include "SkSpriteBlitterTemplate.h"
   257 ///////////////////////////////////////////////////////////////////////////////
   259 class Sprite_D16_S32_BlitRowProc : public SkSpriteBlitter {
   260 public:
   261     Sprite_D16_S32_BlitRowProc(const SkBitmap& source)
   262         : SkSpriteBlitter(source) {}
   264     // overrides
   266     virtual void setup(const SkBitmap& device, int left, int top,
   267                        const SkPaint& paint) {
   268         this->INHERITED::setup(device, left, top, paint);
   270         unsigned flags = 0;
   272         if (paint.getAlpha() < 0xFF) {
   273             flags |= SkBlitRow::kGlobalAlpha_Flag;
   274         }
   275         if (!fSource->isOpaque()) {
   276             flags |= SkBlitRow::kSrcPixelAlpha_Flag;
   277         }
   278         if (paint.isDither()) {
   279             flags |= SkBlitRow::kDither_Flag;
   280         }
   281         fProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config);
   282     }
   284     virtual void blitRect(int x, int y, int width, int height) {
   285         uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y);
   286         const SkPMColor* SK_RESTRICT src = fSource->getAddr32(x - fLeft,
   287                                                               y - fTop);
   288         size_t dstRB = fDevice->rowBytes();
   289         size_t srcRB = fSource->rowBytes();
   290         SkBlitRow::Proc proc = fProc;
   291         U8CPU alpha = fPaint->getAlpha();
   293         while (--height >= 0) {
   294             proc(dst, src, width, alpha, x, y);
   295             y += 1;
   296             dst = (uint16_t* SK_RESTRICT)((char*)dst + dstRB);
   297             src = (const SkPMColor* SK_RESTRICT)((const char*)src + srcRB);
   298         }
   299     }
   301 private:
   302     SkBlitRow::Proc fProc;
   304     typedef SkSpriteBlitter INHERITED;
   305 };
   307 ///////////////////////////////////////////////////////////////////////////////
   309 SkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source, const SkPaint& paint,
   310         SkTBlitterAllocator* allocator) {
   312     SkASSERT(allocator != NULL);
   314     if (paint.getMaskFilter() != NULL) { // may add cases for this
   315         return NULL;
   316     }
   317     if (paint.getXfermode() != NULL) { // may add cases for this
   318         return NULL;
   319     }
   320     if (paint.getColorFilter() != NULL) { // may add cases for this
   321         return NULL;
   322     }
   324     SkSpriteBlitter* blitter = NULL;
   325     unsigned alpha = paint.getAlpha();
   327     switch (source.colorType()) {
   328         case kPMColor_SkColorType: {
   329             blitter = allocator->createT<Sprite_D16_S32_BlitRowProc>(source);
   330             break;
   331         }
   332         case kARGB_4444_SkColorType:
   333             if (255 == alpha) {
   334                 blitter = allocator->createT<Sprite_D16_S4444_Opaque>(source);
   335             } else {
   336                 blitter = allocator->createT<Sprite_D16_S4444_Blend>(source, alpha >> 4);
   337             }
   338             break;
   339         case kRGB_565_SkColorType:
   340             if (255 == alpha) {
   341                 blitter = allocator->createT<Sprite_D16_S16_Opaque>(source);
   342             } else {
   343                 blitter = allocator->createT<Sprite_D16_S16_Blend>(source, alpha);
   344             }
   345             break;
   346         case kIndex_8_SkColorType:
   347             if (paint.isDither()) {
   348                 // we don't support dither yet in these special cases
   349                 break;
   350             }
   351             if (source.isOpaque()) {
   352                 if (255 == alpha) {
   353                     blitter = allocator->createT<Sprite_D16_SIndex8_Opaque>(source);
   354                 } else {
   355                     blitter = allocator->createT<Sprite_D16_SIndex8_Blend>(source, alpha);
   356                 }
   357             } else {
   358                 if (255 == alpha) {
   359                     blitter = allocator->createT<Sprite_D16_SIndex8A_Opaque>(source);
   360                 } else {
   361                     blitter = allocator->createT<Sprite_D16_SIndex8A_Blend>(source, alpha);
   362                 }
   363             }
   364             break;
   365         default:
   366             break;
   367     }
   368     return blitter;
   369 }

mercurial