LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkBlitter_A8.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 25 244 10.2 %
Date: 2017-07-14 16:53:18 Functions: 3 22 13.6 %
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 "SkCoreBlitters.h"
      10             : #include "SkColorPriv.h"
      11             : #include "SkShader.h"
      12             : #include "SkXfermodePriv.h"
      13             : 
      14           0 : SkA8_Blitter::SkA8_Blitter(const SkPixmap& device, const SkPaint& paint) : INHERITED(device) {
      15           0 :     fSrcA = paint.getAlpha();
      16           0 : }
      17             : 
      18           0 : const SkPixmap* SkA8_Blitter::justAnOpaqueColor(uint32_t* value) {
      19           0 :     if (255 == fSrcA) {
      20           0 :         *value = 255;
      21           0 :         return &fDevice;
      22             :     }
      23           0 :     return nullptr;
      24             : }
      25             : 
      26           0 : void SkA8_Blitter::blitH(int x, int y, int width) {
      27           0 :     SkASSERT(x >= 0 && y >= 0 &&
      28             :              (unsigned)(x + width) <= (unsigned)fDevice.width());
      29             : 
      30           0 :     if (fSrcA == 0) {
      31           0 :         return;
      32             :     }
      33             : 
      34           0 :     uint8_t* device = fDevice.writable_addr8(x, y);
      35             : 
      36           0 :     if (fSrcA == 255) {
      37           0 :         memset(device, 0xFF, width);
      38             :     } else {
      39           0 :         unsigned scale = 256 - SkAlpha255To256(fSrcA);
      40           0 :         unsigned srcA = fSrcA;
      41             : 
      42           0 :         for (int i = 0; i < width; i++) {
      43           0 :             device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
      44             :         }
      45             :     }
      46             : }
      47             : 
      48           0 : void SkA8_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
      49             :                              const int16_t runs[]) {
      50           0 :     if (fSrcA == 0) {
      51           0 :         return;
      52             :     }
      53             : 
      54           0 :     uint8_t*    device = fDevice.writable_addr8(x, y);
      55           0 :     unsigned    srcA = fSrcA;
      56             : 
      57             :     for (;;) {
      58           0 :         int count = runs[0];
      59           0 :         SkASSERT(count >= 0);
      60           0 :         if (count == 0) {
      61           0 :             return;
      62             :         }
      63           0 :         unsigned aa = antialias[0];
      64             : 
      65           0 :         if (aa == 255 && srcA == 255) {
      66           0 :             memset(device, 0xFF, count);
      67             :         } else {
      68           0 :             unsigned sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
      69           0 :             unsigned scale = 256 - sa;
      70             : 
      71           0 :             for (int i = 0; i < count; i++) {
      72           0 :                 device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
      73             :             }
      74             :         }
      75           0 :         runs += count;
      76           0 :         antialias += count;
      77           0 :         device += count;
      78           0 :     }
      79             : }
      80             : 
      81             : /////////////////////////////////////////////////////////////////////////////////////
      82             : 
      83             : #define solid_8_pixels(mask, dst)           \
      84             :     do {                                    \
      85             :         if (mask & 0x80) dst[0] = 0xFF;     \
      86             :         if (mask & 0x40) dst[1] = 0xFF;     \
      87             :         if (mask & 0x20) dst[2] = 0xFF;     \
      88             :         if (mask & 0x10) dst[3] = 0xFF;     \
      89             :         if (mask & 0x08) dst[4] = 0xFF;     \
      90             :         if (mask & 0x04) dst[5] = 0xFF;     \
      91             :         if (mask & 0x02) dst[6] = 0xFF;     \
      92             :         if (mask & 0x01) dst[7] = 0xFF;     \
      93             :     } while (0)
      94             : 
      95             : #define SK_BLITBWMASK_NAME                  SkA8_BlitBW
      96             : #define SK_BLITBWMASK_ARGS
      97             : #define SK_BLITBWMASK_BLIT8(mask, dst)      solid_8_pixels(mask, dst)
      98             : #define SK_BLITBWMASK_GETADDR               writable_addr8
      99             : #define SK_BLITBWMASK_DEVTYPE               uint8_t
     100             : #include "SkBlitBWMaskTemplate.h"
     101             : 
     102           0 : static inline void blend_8_pixels(U8CPU bw, uint8_t dst[], U8CPU sa,
     103             :                                   unsigned dst_scale) {
     104           0 :     if (bw & 0x80) dst[0] = SkToU8(sa + SkAlphaMul(dst[0], dst_scale));
     105           0 :     if (bw & 0x40) dst[1] = SkToU8(sa + SkAlphaMul(dst[1], dst_scale));
     106           0 :     if (bw & 0x20) dst[2] = SkToU8(sa + SkAlphaMul(dst[2], dst_scale));
     107           0 :     if (bw & 0x10) dst[3] = SkToU8(sa + SkAlphaMul(dst[3], dst_scale));
     108           0 :     if (bw & 0x08) dst[4] = SkToU8(sa + SkAlphaMul(dst[4], dst_scale));
     109           0 :     if (bw & 0x04) dst[5] = SkToU8(sa + SkAlphaMul(dst[5], dst_scale));
     110           0 :     if (bw & 0x02) dst[6] = SkToU8(sa + SkAlphaMul(dst[6], dst_scale));
     111           0 :     if (bw & 0x01) dst[7] = SkToU8(sa + SkAlphaMul(dst[7], dst_scale));
     112           0 : }
     113             : 
     114             : #define SK_BLITBWMASK_NAME                  SkA8_BlendBW
     115             : #define SK_BLITBWMASK_ARGS                  , U8CPU sa, unsigned dst_scale
     116             : #define SK_BLITBWMASK_BLIT8(mask, dst)      blend_8_pixels(mask, dst, sa, dst_scale)
     117             : #define SK_BLITBWMASK_GETADDR               writable_addr8
     118             : #define SK_BLITBWMASK_DEVTYPE               uint8_t
     119             : #include "SkBlitBWMaskTemplate.h"
     120             : 
     121           0 : void SkA8_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     122           0 :     if (fSrcA == 0) {
     123           0 :         return;
     124             :     }
     125             : 
     126           0 :     if (mask.fFormat == SkMask::kBW_Format) {
     127           0 :         if (fSrcA == 0xFF) {
     128           0 :             SkA8_BlitBW(fDevice, mask, clip);
     129             :         } else {
     130           0 :             SkA8_BlendBW(fDevice, mask, clip, fSrcA,
     131           0 :                          SkAlpha255To256(255 - fSrcA));
     132             :         }
     133           0 :         return;
     134             :     }
     135             : 
     136           0 :     int x = clip.fLeft;
     137           0 :     int y = clip.fTop;
     138           0 :     int width = clip.width();
     139           0 :     int height = clip.height();
     140           0 :     uint8_t* device = fDevice.writable_addr8(x, y);
     141           0 :     const uint8_t* alpha = mask.getAddr8(x, y);
     142           0 :     unsigned    srcA = fSrcA;
     143             : 
     144           0 :     while (--height >= 0) {
     145           0 :         for (int i = width - 1; i >= 0; --i) {
     146             :             unsigned sa;
     147             :             // scale our src by the alpha value
     148             :             {
     149           0 :                 int aa = alpha[i];
     150           0 :                 if (aa == 0) {
     151           0 :                     continue;
     152             :                 }
     153           0 :                 if (aa == 255) {
     154           0 :                     if (srcA == 255) {
     155           0 :                         device[i] = 0xFF;
     156           0 :                         continue;
     157             :                     }
     158           0 :                     sa = srcA;
     159             :                 } else {
     160           0 :                     sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
     161             :                 }
     162             :             }
     163             : 
     164           0 :             int scale = 256 - SkAlpha255To256(sa);
     165           0 :             device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
     166             :         }
     167           0 :         device += fDevice.rowBytes();
     168           0 :         alpha += mask.fRowBytes;
     169             :     }
     170             : }
     171             : 
     172             : ///////////////////////////////////////////////////////////////////////////////
     173             : 
     174           0 : void SkA8_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
     175           0 :     if (fSrcA == 0) {
     176           0 :         return;
     177             :     }
     178             : 
     179           0 :     unsigned sa = SkAlphaMul(fSrcA, SkAlpha255To256(alpha));
     180           0 :     uint8_t* device = fDevice.writable_addr8(x, y);
     181           0 :     size_t   rowBytes = fDevice.rowBytes();
     182             : 
     183           0 :     if (sa == 0xFF) {
     184           0 :         for (int i = 0; i < height; i++) {
     185           0 :             *device = SkToU8(sa);
     186           0 :             device += rowBytes;
     187             :         }
     188             :     } else {
     189           0 :         unsigned scale = 256 - SkAlpha255To256(sa);
     190             : 
     191           0 :         for (int i = 0; i < height; i++) {
     192           0 :             *device = SkToU8(sa + SkAlphaMul(*device, scale));
     193           0 :             device += rowBytes;
     194             :         }
     195             :     }
     196             : }
     197             : 
     198           0 : void SkA8_Blitter::blitRect(int x, int y, int width, int height) {
     199           0 :     SkASSERT(x >= 0 && y >= 0 &&
     200             :              (unsigned)(x + width) <= (unsigned)fDevice.width() &&
     201             :              (unsigned)(y + height) <= (unsigned)fDevice.height());
     202             : 
     203           0 :     if (fSrcA == 0) {
     204           0 :         return;
     205             :     }
     206             : 
     207           0 :     uint8_t*    device = fDevice.writable_addr8(x, y);
     208           0 :     unsigned    srcA = fSrcA;
     209             : 
     210           0 :     if (srcA == 255) {
     211           0 :         while (--height >= 0) {
     212           0 :             memset(device, 0xFF, width);
     213           0 :             device += fDevice.rowBytes();
     214             :         }
     215             :     } else {
     216           0 :         unsigned scale = 256 - SkAlpha255To256(srcA);
     217             : 
     218           0 :         while (--height >= 0) {
     219           0 :             for (int i = 0; i < width; i++) {
     220           0 :                 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
     221             :             }
     222           0 :             device += fDevice.rowBytes();
     223             :         }
     224             :     }
     225             : }
     226             : 
     227             : ///////////////////////////////////////////////////////////////////////
     228             : 
     229           2 : SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint& paint,
     230           2 :                                          SkShader::Context* shaderContext)
     231           2 :     : INHERITED(device, paint, shaderContext)
     232             : {
     233           2 :     fXfermode = SkXfermode::Peek(paint.getBlendMode());
     234           2 :     SkASSERT(!fXfermode || fShaderContext);
     235             : 
     236           2 :     int width = device.width();
     237           2 :     fBuffer = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor) * (width + (SkAlign4(width) >> 2)));
     238           2 :     fAAExpand = (uint8_t*)(fBuffer + width);
     239           2 : }
     240             : 
     241           4 : SkA8_Shader_Blitter::~SkA8_Shader_Blitter() {
     242           2 :     sk_free(fBuffer);
     243           2 : }
     244             : 
     245          58 : void SkA8_Shader_Blitter::blitH(int x, int y, int width) {
     246          58 :     SkASSERT(x >= 0 && y >= 0 &&
     247             :              (unsigned)(x + width) <= (unsigned)fDevice.width());
     248             : 
     249          58 :     uint8_t* device = fDevice.writable_addr8(x, y);
     250          58 :     SkShader::Context* shaderContext = fShaderContext;
     251             : 
     252          58 :     if ((shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) && !fXfermode) {
     253           0 :         memset(device, 0xFF, width);
     254             :     } else {
     255          58 :         SkPMColor*  span = fBuffer;
     256             : 
     257          58 :         shaderContext->shadeSpan(x, y, span, width);
     258          58 :         if (fXfermode) {
     259           0 :             fXfermode->xferA8(device, span, width, nullptr);
     260             :         } else {
     261       19314 :             for (int i = width - 1; i >= 0; --i) {
     262       19256 :                 unsigned    srcA = SkGetPackedA32(span[i]);
     263       19256 :                 unsigned    scale = 256 - SkAlpha255To256(srcA);
     264             : 
     265       19256 :                 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
     266             :             }
     267             :         }
     268             :     }
     269          58 : }
     270             : 
     271           0 : static inline uint8_t aa_blend8(SkPMColor src, U8CPU da, int aa) {
     272           0 :     SkASSERT((unsigned)aa <= 255);
     273             : 
     274           0 :     int src_scale = SkAlpha255To256(aa);
     275           0 :     int sa = SkGetPackedA32(src);
     276           0 :     int dst_scale = SkAlphaMulInv256(sa, src_scale);
     277             : 
     278           0 :     return SkToU8((sa * src_scale + da * dst_scale) >> 8);
     279             : }
     280             : 
     281           0 : void SkA8_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     282             :                                     const int16_t runs[]) {
     283           0 :     SkShader::Context* shaderContext = fShaderContext;
     284           0 :     SkXfermode*        mode = fXfermode;
     285           0 :     uint8_t*           aaExpand = fAAExpand;
     286           0 :     SkPMColor*         span = fBuffer;
     287           0 :     uint8_t*           device = fDevice.writable_addr8(x, y);
     288           0 :     int                opaque = shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag;
     289             : 
     290             :     for (;;) {
     291           0 :         int count = *runs;
     292           0 :         if (count == 0) {
     293           0 :             break;
     294             :         }
     295           0 :         int aa = *antialias;
     296           0 :         if (aa) {
     297           0 :             if (opaque && aa == 255 && mode == nullptr) {
     298           0 :                 memset(device, 0xFF, count);
     299             :             } else {
     300           0 :                 shaderContext->shadeSpan(x, y, span, count);
     301           0 :                 if (mode) {
     302           0 :                     memset(aaExpand, aa, count);
     303           0 :                     mode->xferA8(device, span, count, aaExpand);
     304             :                 } else {
     305           0 :                     for (int i = count - 1; i >= 0; --i) {
     306           0 :                         device[i] = aa_blend8(span[i], device[i], aa);
     307             :                     }
     308             :                 }
     309             :             }
     310             :         }
     311           0 :         device += count;
     312           0 :         runs += count;
     313           0 :         antialias += count;
     314           0 :         x += count;
     315           0 :     }
     316           0 : }
     317             : 
     318           0 : void SkA8_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     319           0 :     if (mask.fFormat == SkMask::kBW_Format) {
     320           0 :         this->INHERITED::blitMask(mask, clip);
     321           0 :         return;
     322             :     }
     323             : 
     324           0 :     int x = clip.fLeft;
     325           0 :     int y = clip.fTop;
     326           0 :     int width = clip.width();
     327           0 :     int height = clip.height();
     328           0 :     uint8_t* device = fDevice.writable_addr8(x, y);
     329           0 :     const uint8_t* alpha = mask.getAddr8(x, y);
     330           0 :     SkShader::Context* shaderContext = fShaderContext;
     331             : 
     332           0 :     SkPMColor*  span = fBuffer;
     333             : 
     334           0 :     while (--height >= 0) {
     335           0 :         shaderContext->shadeSpan(x, y, span, width);
     336           0 :         if (fXfermode) {
     337           0 :             fXfermode->xferA8(device, span, width, alpha);
     338             :         } else {
     339           0 :             for (int i = width - 1; i >= 0; --i) {
     340           0 :                 device[i] = aa_blend8(span[i], device[i], alpha[i]);
     341             :             }
     342             :         }
     343             : 
     344           0 :         y += 1;
     345           0 :         device += fDevice.rowBytes();
     346           0 :         alpha += mask.fRowBytes;
     347             :     }
     348             : }
     349             : 
     350             : ///////////////////////////////////////////////////////////////////////////////
     351             : 
     352           0 : SkA8_Coverage_Blitter::SkA8_Coverage_Blitter(const SkPixmap& device,
     353           0 :                              const SkPaint& paint) : SkRasterBlitter(device) {
     354           0 :     SkASSERT(nullptr == paint.getShader());
     355           0 :     SkASSERT(paint.isSrcOver());
     356           0 :     SkASSERT(nullptr == paint.getColorFilter());
     357           0 : }
     358             : 
     359           0 : void SkA8_Coverage_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     360             :                                       const int16_t runs[]) {
     361           0 :     uint8_t* device = fDevice.writable_addr8(x, y);
     362           0 :     SkDEBUGCODE(int totalCount = 0;)
     363             : 
     364             :     for (;;) {
     365           0 :         int count = runs[0];
     366           0 :         SkASSERT(count >= 0);
     367           0 :         if (count == 0) {
     368           0 :             return;
     369             :         }
     370           0 :         if (antialias[0]) {
     371           0 :             memset(device, antialias[0], count);
     372             :         }
     373           0 :         runs += count;
     374           0 :         antialias += count;
     375           0 :         device += count;
     376             : 
     377           0 :         SkDEBUGCODE(totalCount += count;)
     378           0 :     }
     379             :     SkASSERT(fDevice.width() == totalCount);
     380             : }
     381             : 
     382           0 : void SkA8_Coverage_Blitter::blitH(int x, int y, int width) {
     383           0 :     memset(fDevice.writable_addr8(x, y), 0xFF, width);
     384           0 : }
     385             : 
     386           0 : void SkA8_Coverage_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
     387           0 :     if (0 == alpha) {
     388           0 :         return;
     389             :     }
     390             : 
     391           0 :     uint8_t* dst = fDevice.writable_addr8(x, y);
     392           0 :     const size_t dstRB = fDevice.rowBytes();
     393           0 :     while (--height >= 0) {
     394           0 :         *dst = alpha;
     395           0 :         dst += dstRB;
     396             :     }
     397             : }
     398             : 
     399           0 : void SkA8_Coverage_Blitter::blitRect(int x, int y, int width, int height) {
     400           0 :     uint8_t* dst = fDevice.writable_addr8(x, y);
     401           0 :     const size_t dstRB = fDevice.rowBytes();
     402           0 :     while (--height >= 0) {
     403           0 :         memset(dst, 0xFF, width);
     404           0 :         dst += dstRB;
     405             :     }
     406           0 : }
     407             : 
     408           0 : void SkA8_Coverage_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     409           0 :     SkASSERT(SkMask::kA8_Format == mask.fFormat);
     410             : 
     411           0 :     int x = clip.fLeft;
     412           0 :     int y = clip.fTop;
     413           0 :     int width = clip.width();
     414           0 :     int height = clip.height();
     415             : 
     416           0 :     uint8_t* dst = fDevice.writable_addr8(x, y);
     417           0 :     const uint8_t* src = mask.getAddr8(x, y);
     418           0 :     const size_t srcRB = mask.fRowBytes;
     419           0 :     const size_t dstRB = fDevice.rowBytes();
     420             : 
     421           0 :     while (--height >= 0) {
     422           0 :         memcpy(dst, src, width);
     423           0 :         dst += dstRB;
     424           0 :         src += srcRB;
     425             :     }
     426           0 : }
     427             : 
     428           0 : const SkPixmap* SkA8_Coverage_Blitter::justAnOpaqueColor(uint32_t*) {
     429           0 :     return nullptr;
     430             : }

Generated by: LCOV version 1.13