LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkSpriteBlitter_RGB16.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 121 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13