LCOV - code coverage report
Current view: directory - gfx/skia/src/core - SkSpriteBlitter_RGB16.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 115 0 0.0 %
Date: 2012-06-02 Functions: 13 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2006 The Android Open Source Project
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : 
       9                 : 
      10                 : #include "SkSpriteBlitter.h"
      11                 : #include "SkBlitRow.h"
      12                 : #include "SkTemplates.h"
      13                 : #include "SkUtils.h"
      14                 : #include "SkColorPriv.h"
      15                 : 
      16                 : #define D16_S32A_Opaque_Pixel(dst, sc)                                        \
      17                 : do {                                                                          \
      18                 :     if (sc) {                                                                 \
      19                 :         *dst = SkSrcOver32To16(sc, *dst);                                     \
      20                 :     }                                                                         \
      21                 : } while (0)
      22                 : 
      23               0 : static inline void D16_S32A_Blend_Pixel_helper(uint16_t* dst, SkPMColor sc,
      24                 :                                                unsigned src_scale) {
      25               0 :     uint16_t dc = *dst;
      26               0 :     unsigned sa = SkGetPackedA32(sc);
      27                 :     unsigned dr, dg, db;
      28                 : 
      29               0 :     if (255 == sa) {
      30               0 :         dr = SkAlphaBlend(SkPacked32ToR16(sc), SkGetPackedR16(dc), src_scale);
      31               0 :         dg = SkAlphaBlend(SkPacked32ToG16(sc), SkGetPackedG16(dc), src_scale);
      32               0 :         db = SkAlphaBlend(SkPacked32ToB16(sc), SkGetPackedB16(dc), src_scale);
      33                 :     } else {
      34               0 :         unsigned dst_scale = 255 - SkAlphaMul(sa, src_scale);
      35                 :         dr = (SkPacked32ToR16(sc) * src_scale +
      36               0 :               SkGetPackedR16(dc) * dst_scale) >> 8;
      37                 :         dg = (SkPacked32ToG16(sc) * src_scale +
      38               0 :               SkGetPackedG16(dc) * dst_scale) >> 8;
      39                 :         db = (SkPacked32ToB16(sc) * src_scale +
      40               0 :               SkGetPackedB16(dc) * dst_scale) >> 8;
      41                 :     }
      42               0 :     *dst = SkPackRGB16(dr, dg, db);
      43               0 : }
      44                 : 
      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)
      47                 : 
      48                 : 
      49                 : ///////////////////////////////////////////////////////////////////////////////
      50                 : 
      51               0 : class Sprite_D16_S16_Opaque : public SkSpriteBlitter {
      52                 : public:
      53               0 :     Sprite_D16_S16_Opaque(const SkBitmap& source)
      54               0 :         : SkSpriteBlitter(source) {}
      55                 : 
      56                 :     // overrides
      57               0 :     virtual void blitRect(int x, int y, int width, int height) {
      58               0 :         uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y);
      59                 :         const uint16_t* SK_RESTRICT src = fSource->getAddr16(x - fLeft,
      60               0 :                                                              y - fTop);
      61               0 :         unsigned dstRB = fDevice->rowBytes();
      62               0 :         unsigned srcRB = fSource->rowBytes();
      63                 : 
      64               0 :         while (--height >= 0) {
      65               0 :             memcpy(dst, src, width << 1);
      66               0 :             dst = (uint16_t*)((char*)dst + dstRB);
      67               0 :             src = (const uint16_t*)((const char*)src + srcRB);
      68                 :         }
      69               0 :     }
      70                 : };
      71                 : 
      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)
      77                 : 
      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"
      91                 : 
      92                 : ///////////////////////////////////////////////////////////////////////////////
      93                 : 
      94                 : #define D16_S4444_Opaque(dst, sc)           \
      95                 :     do {                                    \
      96                 :         uint16_t dc = *dst;                 \
      97                 :         *dst = SkSrcOver4444To16(sc, dc);   \
      98                 :     } while (0)
      99                 : 
     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"
     113                 : 
     114                 : #define D16_S4444_Blend(dst, sc, scale16)           \
     115                 :     do {                                            \
     116                 :         uint16_t dc = *dst;                         \
     117                 :         *dst = SkBlend4444To16(sc, dc, scale16);    \
     118                 :     } while (0)
     119                 : 
     120                 : 
     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"
     134                 : 
     135                 : ///////////////////////////////////////////////////////////////////////////////
     136                 : 
     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(false)
     149                 : #include "SkSpriteBlitterTemplate.h"
     150                 : 
     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(false);
     163                 : #include "SkSpriteBlitterTemplate.h"
     164                 : 
     165                 : ///////////////////////////////////////////////////////////////////////////////
     166                 : 
     167               0 : static intptr_t asint(const void* ptr) {
     168               0 :     return reinterpret_cast<const char*>(ptr) - (const char*)0;
     169                 : }
     170                 : 
     171               0 : 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               0 :     if (count <= 8) {
     175               0 :         do {
     176               0 :             *dst++ = ctable[*src++];
     177                 :         } while (--count);
     178               0 :         return;
     179                 :     }
     180                 : 
     181                 :     // eat src until we're on a 4byte boundary
     182               0 :     while (asint(src) & 3) {
     183               0 :         *dst++ = ctable[*src++];
     184               0 :         count -= 1;
     185                 :     }
     186                 : 
     187               0 :     int qcount = count >> 2;
     188               0 :     SkASSERT(qcount > 0);
     189               0 :     const uint32_t* qsrc = reinterpret_cast<const uint32_t*>(src);
     190               0 :     if (asint(dst) & 2) {
     191               0 :         do {
     192               0 :             uint32_t s4 = *qsrc++;
     193                 : #ifdef SK_CPU_LENDIAN
     194               0 :             *dst++ = ctable[s4 & 0xFF];
     195               0 :             *dst++ = ctable[(s4 >> 8) & 0xFF];
     196               0 :             *dst++ = ctable[(s4 >> 16) & 0xFF];
     197               0 :             *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               0 :         uint32_t* ddst = reinterpret_cast<uint32_t*>(dst);
     207               0 :         do {
     208               0 :             uint32_t s4 = *qsrc++;
     209                 : #ifdef SK_CPU_LENDIAN
     210               0 :             *ddst++ = (ctable[(s4 >> 8) & 0xFF] << 16) | ctable[s4 & 0xFF];
     211               0 :             *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               0 :         dst = reinterpret_cast<uint16_t*>(ddst);
     218                 :     }
     219               0 :     src = reinterpret_cast<const uint8_t*>(qsrc);
     220               0 :     count &= 3;
     221                 :     // catch any remaining (will be < 4)
     222               0 :     while (--count >= 0) {
     223               0 :         *dst++ = ctable[*src++];
     224                 :     }
     225                 : }
     226                 : 
     227                 : #define SkSPRITE_ROW_PROC(d, s, n, x, y)    blitrow_d16_si8(d, s, n, ctable)
     228                 : 
     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"
     242                 : 
     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"
     256                 : 
     257                 : ///////////////////////////////////////////////////////////////////////////////
     258                 : 
     259               0 : class Sprite_D16_S32_BlitRowProc : public SkSpriteBlitter {
     260                 : public:
     261               0 :     Sprite_D16_S32_BlitRowProc(const SkBitmap& source)
     262               0 :         : SkSpriteBlitter(source) {}
     263                 :     
     264                 :     // overrides
     265                 :     
     266               0 :     virtual void setup(const SkBitmap& device, int left, int top,
     267                 :                        const SkPaint& paint) {
     268               0 :         this->INHERITED::setup(device, left, top, paint);
     269                 :         
     270               0 :         unsigned flags = 0;
     271                 :         
     272               0 :         if (paint.getAlpha() < 0xFF) {
     273               0 :             flags |= SkBlitRow::kGlobalAlpha_Flag;
     274                 :         }
     275               0 :         if (!fSource->isOpaque()) {
     276               0 :             flags |= SkBlitRow::kSrcPixelAlpha_Flag;
     277                 :         }
     278               0 :         if (paint.isDither()) {
     279               0 :             flags |= SkBlitRow::kDither_Flag;
     280                 :         }
     281               0 :         fProc = SkBlitRow::Factory(flags, SkBitmap::kRGB_565_Config);
     282               0 :     }
     283                 :     
     284               0 :     virtual void blitRect(int x, int y, int width, int height) {
     285               0 :         uint16_t* SK_RESTRICT dst = fDevice->getAddr16(x, y);
     286                 :         const SkPMColor* SK_RESTRICT src = fSource->getAddr32(x - fLeft,
     287               0 :                                                               y - fTop);
     288               0 :         unsigned dstRB = fDevice->rowBytes();
     289               0 :         unsigned srcRB = fSource->rowBytes();
     290               0 :         SkBlitRow::Proc proc = fProc;
     291               0 :         U8CPU alpha = fPaint->getAlpha();
     292                 :         
     293               0 :         while (--height >= 0) {
     294               0 :             proc(dst, src, width, alpha, x, y);
     295               0 :             y += 1;
     296               0 :             dst = (uint16_t* SK_RESTRICT)((char*)dst + dstRB);
     297               0 :             src = (const SkPMColor* SK_RESTRICT)((const char*)src + srcRB);
     298                 :         }
     299               0 :     }
     300                 :     
     301                 : private:
     302                 :     SkBlitRow::Proc fProc;
     303                 :     
     304                 :     typedef SkSpriteBlitter INHERITED;
     305                 : };
     306                 : 
     307                 : ///////////////////////////////////////////////////////////////////////////////
     308                 : 
     309                 : #include "SkTemplatesPriv.h"
     310                 : 
     311               0 : SkSpriteBlitter* SkSpriteBlitter::ChooseD16(const SkBitmap& source,
     312                 :                                             const SkPaint& paint,
     313                 :                                             void* storage, size_t storageSize) {
     314               0 :     if (paint.getMaskFilter() != NULL) { // may add cases for this
     315               0 :         return NULL;
     316                 :     }
     317               0 :     if (paint.getXfermode() != NULL) { // may add cases for this
     318               0 :         return NULL;
     319                 :     }
     320               0 :     if (paint.getColorFilter() != NULL) { // may add cases for this
     321               0 :         return NULL;
     322                 :     }
     323                 : 
     324               0 :     SkSpriteBlitter* blitter = NULL;
     325               0 :     unsigned alpha = paint.getAlpha();
     326                 : 
     327               0 :     switch (source.getConfig()) {
     328                 :         case SkBitmap::kARGB_8888_Config:
     329               0 :             SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S32_BlitRowProc,
     330                 :                                   storage, storageSize, (source));
     331               0 :             break;
     332                 :         case SkBitmap::kARGB_4444_Config:
     333               0 :             if (255 == alpha) {
     334               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Opaque,
     335                 :                                       storage, storageSize, (source));
     336                 :             } else {
     337               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S4444_Blend,
     338                 :                                     storage, storageSize, (source, alpha >> 4));
     339                 :             }
     340               0 :             break;
     341                 :         case SkBitmap::kRGB_565_Config:
     342               0 :             if (255 == alpha) {
     343               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Opaque,
     344                 :                                       storage, storageSize, (source));
     345                 :             } else {
     346               0 :                 SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_S16_Blend,
     347                 :                                       storage, storageSize, (source, alpha));
     348                 :             }
     349               0 :             break;
     350                 :         case SkBitmap::kIndex8_Config:
     351               0 :             if (paint.isDither()) {
     352                 :                 // we don't support dither yet in these special cases
     353               0 :                 break;
     354                 :             }
     355               0 :             if (source.isOpaque()) {
     356               0 :                 if (255 == alpha) {
     357               0 :                     SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Opaque,
     358                 :                                           storage, storageSize, (source));
     359                 :                 } else {
     360               0 :                     SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8_Blend,
     361                 :                                          storage, storageSize, (source, alpha));
     362                 :                 }
     363                 :             } else {
     364               0 :                 if (255 == alpha) {
     365               0 :                     SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Opaque,
     366                 :                                           storage, storageSize, (source));
     367                 :                 } else {
     368               0 :                     SK_PLACEMENT_NEW_ARGS(blitter, Sprite_D16_SIndex8A_Blend,
     369                 :                                          storage, storageSize, (source, alpha));
     370                 :                 }
     371                 :             }
     372               0 :             break;
     373                 :         default:
     374               0 :             break;
     375                 :     }
     376               0 :     return blitter;
     377                 : }

Generated by: LCOV version 1.7