LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkBlitter_ARGB32.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 166 407 40.8 %
Date: 2017-07-14 16:53:18 Functions: 12 25 48.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             : #include "SkCoreBlitters.h"
       9             : #include "SkColorPriv.h"
      10             : #include "SkShader.h"
      11             : #include "SkUtils.h"
      12             : #include "SkXfermodePriv.h"
      13             : #include "SkBlitMask.h"
      14             : 
      15             : ///////////////////////////////////////////////////////////////////////////////
      16             : 
      17           0 : static void SkARGB32_Blit32(const SkPixmap& device, const SkMask& mask,
      18             :                             const SkIRect& clip, SkPMColor srcColor) {
      19           0 :     U8CPU alpha = SkGetPackedA32(srcColor);
      20           0 :     unsigned flags = SkBlitRow::kSrcPixelAlpha_Flag32;
      21           0 :     if (alpha != 255) {
      22           0 :         flags |= SkBlitRow::kGlobalAlpha_Flag32;
      23             :     }
      24           0 :     SkBlitRow::Proc32 proc = SkBlitRow::Factory32(flags);
      25             : 
      26           0 :     int x = clip.fLeft;
      27           0 :     int y = clip.fTop;
      28           0 :     int width = clip.width();
      29           0 :     int height = clip.height();
      30             : 
      31           0 :     SkPMColor* dstRow = device.writable_addr32(x, y);
      32           0 :     const SkPMColor* srcRow = reinterpret_cast<const SkPMColor*>(mask.getAddr8(x, y));
      33             : 
      34           0 :     do {
      35           0 :         proc(dstRow, srcRow, width, alpha);
      36           0 :         dstRow = (SkPMColor*)((char*)dstRow + device.rowBytes());
      37           0 :         srcRow = (const SkPMColor*)((const char*)srcRow + mask.fRowBytes);
      38             :     } while (--height != 0);
      39           0 : }
      40             : 
      41             : //////////////////////////////////////////////////////////////////////////////////////
      42             : 
      43         144 : SkARGB32_Blitter::SkARGB32_Blitter(const SkPixmap& device, const SkPaint& paint)
      44         144 :         : INHERITED(device) {
      45         144 :     SkColor color = paint.getColor();
      46         144 :     fColor = color;
      47             : 
      48         144 :     fSrcA = SkColorGetA(color);
      49         144 :     unsigned scale = SkAlpha255To256(fSrcA);
      50         144 :     fSrcR = SkAlphaMul(SkColorGetR(color), scale);
      51         144 :     fSrcG = SkAlphaMul(SkColorGetG(color), scale);
      52         144 :     fSrcB = SkAlphaMul(SkColorGetB(color), scale);
      53             : 
      54         144 :     fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB);
      55         144 : }
      56             : 
      57           0 : const SkPixmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) {
      58           0 :     if (255 == fSrcA) {
      59           0 :         *value = fPMColor;
      60           0 :         return &fDevice;
      61             :     }
      62           0 :     return nullptr;
      63             : }
      64             : 
      65             : #if defined _WIN32  // disable warning : local variable used without having been initialized
      66             : #pragma warning ( push )
      67             : #pragma warning ( disable : 4701 )
      68             : #endif
      69             : 
      70         514 : void SkARGB32_Blitter::blitH(int x, int y, int width) {
      71         514 :     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
      72             : 
      73         514 :     uint32_t* device = fDevice.writable_addr32(x, y);
      74         514 :     SkBlitRow::Color32(device, device, width, fPMColor);
      75         514 : }
      76             : 
      77        2156 : void SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
      78             :                                  const int16_t runs[]) {
      79        2156 :     if (fSrcA == 0) {
      80           0 :         return;
      81             :     }
      82             : 
      83        2156 :     uint32_t    color = fPMColor;
      84        2156 :     uint32_t*   device = fDevice.writable_addr32(x, y);
      85        2156 :     unsigned    opaqueMask = fSrcA; // if fSrcA is 0xFF, then we will catch the fast opaque case
      86             : 
      87             :     for (;;) {
      88       19369 :         int count = runs[0];
      89       19369 :         SkASSERT(count >= 0);
      90       19369 :         if (count <= 0) {
      91        2156 :             return;
      92             :         }
      93       17213 :         unsigned aa = antialias[0];
      94       17213 :         if (aa) {
      95       11261 :             if ((opaqueMask & aa) == 255) {
      96        6521 :                 sk_memset32(device, color, count);
      97             :             } else {
      98        9480 :                 uint32_t sc = SkAlphaMulQ(color, SkAlpha255To256(aa));
      99        4740 :                 SkBlitRow::Color32(device, device, count, sc);
     100             :             }
     101             :         }
     102       17213 :         runs += count;
     103       17213 :         antialias += count;
     104       17213 :         device += count;
     105       17213 :     }
     106             : }
     107             : 
     108           0 : void SkARGB32_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
     109           0 :     uint32_t* device = fDevice.writable_addr32(x, y);
     110           0 :     SkDEBUGCODE((void)fDevice.writable_addr32(x + 1, y);)
     111             : 
     112           0 :     device[0] = SkBlendARGB32(fPMColor, device[0], a0);
     113           0 :     device[1] = SkBlendARGB32(fPMColor, device[1], a1);
     114           0 : }
     115             : 
     116           0 : void SkARGB32_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
     117           0 :     uint32_t* device = fDevice.writable_addr32(x, y);
     118           0 :     SkDEBUGCODE((void)fDevice.writable_addr32(x, y + 1);)
     119             : 
     120           0 :     device[0] = SkBlendARGB32(fPMColor, device[0], a0);
     121           0 :     device = (uint32_t*)((char*)device + fDevice.rowBytes());
     122           0 :     device[0] = SkBlendARGB32(fPMColor, device[0], a1);
     123           0 : }
     124             : 
     125             : //////////////////////////////////////////////////////////////////////////////////////
     126             : 
     127             : #define solid_8_pixels(mask, dst, color)    \
     128             :     do {                                    \
     129             :         if (mask & 0x80) dst[0] = color;    \
     130             :         if (mask & 0x40) dst[1] = color;    \
     131             :         if (mask & 0x20) dst[2] = color;    \
     132             :         if (mask & 0x10) dst[3] = color;    \
     133             :         if (mask & 0x08) dst[4] = color;    \
     134             :         if (mask & 0x04) dst[5] = color;    \
     135             :         if (mask & 0x02) dst[6] = color;    \
     136             :         if (mask & 0x01) dst[7] = color;    \
     137             :     } while (0)
     138             : 
     139             : #define SK_BLITBWMASK_NAME                  SkARGB32_BlitBW
     140             : #define SK_BLITBWMASK_ARGS                  , SkPMColor color
     141             : #define SK_BLITBWMASK_BLIT8(mask, dst)      solid_8_pixels(mask, dst, color)
     142             : #define SK_BLITBWMASK_GETADDR               writable_addr32
     143             : #define SK_BLITBWMASK_DEVTYPE               uint32_t
     144             : #include "SkBlitBWMaskTemplate.h"
     145             : 
     146             : #define blend_8_pixels(mask, dst, sc, dst_scale)                            \
     147             :     do {                                                                    \
     148             :         if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ(dst[0], dst_scale); }  \
     149             :         if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ(dst[1], dst_scale); }  \
     150             :         if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ(dst[2], dst_scale); }  \
     151             :         if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ(dst[3], dst_scale); }  \
     152             :         if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ(dst[4], dst_scale); }  \
     153             :         if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ(dst[5], dst_scale); }  \
     154             :         if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ(dst[6], dst_scale); }  \
     155             :         if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ(dst[7], dst_scale); }  \
     156             :     } while (0)
     157             : 
     158             : #define SK_BLITBWMASK_NAME                  SkARGB32_BlendBW
     159             : #define SK_BLITBWMASK_ARGS                  , uint32_t sc, unsigned dst_scale
     160             : #define SK_BLITBWMASK_BLIT8(mask, dst)      blend_8_pixels(mask, dst, sc, dst_scale)
     161             : #define SK_BLITBWMASK_GETADDR               writable_addr32
     162             : #define SK_BLITBWMASK_DEVTYPE               uint32_t
     163             : #include "SkBlitBWMaskTemplate.h"
     164             : 
     165         114 : void SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     166         114 :     SkASSERT(mask.fBounds.contains(clip));
     167         114 :     SkASSERT(fSrcA != 0xFF);
     168             : 
     169         114 :     if (fSrcA == 0) {
     170           0 :         return;
     171             :     }
     172             : 
     173         114 :     if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
     174         114 :         return;
     175             :     }
     176             : 
     177           0 :     switch (mask.fFormat) {
     178             :         case SkMask::kBW_Format:
     179           0 :             SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA));
     180           0 :             break;
     181             :         case SkMask::kARGB32_Format:
     182           0 :             SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
     183           0 :             break;
     184             :         default:
     185           0 :             SkFAIL("Mask format not handled.");
     186             :     }
     187             : }
     188             : 
     189         339 : void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
     190             :                                        const SkIRect& clip) {
     191         339 :     SkASSERT(mask.fBounds.contains(clip));
     192             : 
     193         339 :     if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
     194         339 :         return;
     195             :     }
     196             : 
     197           0 :     switch (mask.fFormat) {
     198             :         case SkMask::kBW_Format:
     199           0 :             SkARGB32_BlitBW(fDevice, mask, clip, fPMColor);
     200           0 :             break;
     201             :         case SkMask::kARGB32_Format:
     202           0 :             SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
     203           0 :             break;
     204             :         default:
     205           0 :             SkFAIL("Mask format not handled.");
     206             :     }
     207             : }
     208             : 
     209           0 : void SkARGB32_Opaque_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
     210           0 :     uint32_t* device = fDevice.writable_addr32(x, y);
     211           0 :     SkDEBUGCODE((void)fDevice.writable_addr32(x + 1, y);)
     212             : 
     213           0 :     device[0] = SkFastFourByteInterp(fPMColor, device[0], a0);
     214           0 :     device[1] = SkFastFourByteInterp(fPMColor, device[1], a1);
     215           0 : }
     216             : 
     217           0 : void SkARGB32_Opaque_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
     218           0 :     uint32_t* device = fDevice.writable_addr32(x, y);
     219           0 :     SkDEBUGCODE((void)fDevice.writable_addr32(x, y + 1);)
     220             : 
     221           0 :     device[0] = SkFastFourByteInterp(fPMColor, device[0], a0);
     222           0 :     device = (uint32_t*)((char*)device + fDevice.rowBytes());
     223           0 :     device[0] = SkFastFourByteInterp(fPMColor, device[0], a1);
     224           0 : }
     225             : 
     226             : ///////////////////////////////////////////////////////////////////////////////
     227             : 
     228           0 : void SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
     229           0 :     if (alpha == 0 || fSrcA == 0) {
     230           0 :         return;
     231             :     }
     232             : 
     233           0 :     uint32_t* device = fDevice.writable_addr32(x, y);
     234           0 :     uint32_t  color = fPMColor;
     235             : 
     236           0 :     if (alpha != 255) {
     237           0 :         color = SkAlphaMulQ(color, SkAlpha255To256(alpha));
     238             :     }
     239             : 
     240           0 :     unsigned dst_scale = SkAlpha255To256(255 - SkGetPackedA32(color));
     241           0 :     size_t rowBytes = fDevice.rowBytes();
     242           0 :     while (--height >= 0) {
     243           0 :         device[0] = color + SkAlphaMulQ(device[0], dst_scale);
     244           0 :         device = (uint32_t*)((char*)device + rowBytes);
     245             :     }
     246             : }
     247             : 
     248          32 : void SkARGB32_Blitter::blitRect(int x, int y, int width, int height) {
     249          32 :     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height());
     250             : 
     251          32 :     if (fSrcA == 0) {
     252           0 :         return;
     253             :     }
     254             : 
     255          32 :     uint32_t*   device = fDevice.writable_addr32(x, y);
     256          32 :     uint32_t    color = fPMColor;
     257          32 :     size_t      rowBytes = fDevice.rowBytes();
     258             : 
     259       12940 :     while (--height >= 0) {
     260        6454 :         SkBlitRow::Color32(device, device, width, color);
     261        6454 :         device = (uint32_t*)((char*)device + rowBytes);
     262             :     }
     263             : }
     264             : 
     265             : #if defined _WIN32
     266             : #pragma warning ( pop )
     267             : #endif
     268             : 
     269             : ///////////////////////////////////////////////////////////////////////
     270             : 
     271           0 : void SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     272             :                                        const int16_t runs[]) {
     273           0 :     uint32_t*   device = fDevice.writable_addr32(x, y);
     274           0 :     SkPMColor   black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT);
     275             : 
     276             :     for (;;) {
     277           0 :         int count = runs[0];
     278           0 :         SkASSERT(count >= 0);
     279           0 :         if (count <= 0) {
     280           0 :             return;
     281             :         }
     282           0 :         unsigned aa = antialias[0];
     283           0 :         if (aa) {
     284           0 :             if (aa == 255) {
     285           0 :                 sk_memset32(device, black, count);
     286             :             } else {
     287           0 :                 SkPMColor src = aa << SK_A32_SHIFT;
     288           0 :                 unsigned dst_scale = 256 - aa;
     289           0 :                 int n = count;
     290           0 :                 do {
     291           0 :                     --n;
     292           0 :                     device[n] = src + SkAlphaMulQ(device[n], dst_scale);
     293           0 :                 } while (n > 0);
     294             :             }
     295             :         }
     296           0 :         runs += count;
     297           0 :         antialias += count;
     298           0 :         device += count;
     299           0 :     }
     300             : }
     301             : 
     302           0 : void SkARGB32_Black_Blitter::blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
     303           0 :     uint32_t* device = fDevice.writable_addr32(x, y);
     304           0 :     SkDEBUGCODE((void)fDevice.writable_addr32(x + 1, y);)
     305             : 
     306           0 :     device[0] = (a0 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a0);
     307           0 :     device[1] = (a1 << SK_A32_SHIFT) + SkAlphaMulQ(device[1], 256 - a1);
     308           0 : }
     309             : 
     310           0 : void SkARGB32_Black_Blitter::blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
     311           0 :     uint32_t* device = fDevice.writable_addr32(x, y);
     312           0 :     SkDEBUGCODE((void)fDevice.writable_addr32(x, y + 1);)
     313             : 
     314           0 :     device[0] = (a0 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a0);
     315           0 :     device = (uint32_t*)((char*)device + fDevice.rowBytes());
     316           0 :     device[0] = (a1 << SK_A32_SHIFT) + SkAlphaMulQ(device[0], 256 - a1);
     317           0 : }
     318             : 
     319             : ///////////////////////////////////////////////////////////////////////////////
     320             : 
     321             : // Special version of SkBlitRow::Factory32 that knows we're in kSrc_Mode,
     322             : // instead of kSrcOver_Mode
     323           0 : static void blend_srcmode(SkPMColor* SK_RESTRICT device,
     324             :                           const SkPMColor* SK_RESTRICT span,
     325             :                           int count, U8CPU aa) {
     326           0 :     int aa256 = SkAlpha255To256(aa);
     327           0 :     for (int i = 0; i < count; ++i) {
     328           0 :         device[i] = SkFourByteInterp256(span[i], device[i], aa256);
     329             :     }
     330           0 : }
     331             : 
     332         164 : SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device,
     333         164 :         const SkPaint& paint, SkShader::Context* shaderContext)
     334         164 :     : INHERITED(device, paint, shaderContext)
     335             : {
     336         164 :     fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
     337             : 
     338         164 :     fXfermode = SkXfermode::Peek(paint.getBlendMode());
     339             : 
     340         164 :     int flags = 0;
     341         164 :     if (!(shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
     342         135 :         flags |= SkBlitRow::kSrcPixelAlpha_Flag32;
     343             :     }
     344             :     // we call this on the output from the shader
     345         164 :     fProc32 = SkBlitRow::Factory32(flags);
     346             :     // we call this on the output from the shader + alpha from the aa buffer
     347         164 :     fProc32Blend = SkBlitRow::Factory32(flags | SkBlitRow::kGlobalAlpha_Flag32);
     348             : 
     349         164 :     fShadeDirectlyIntoDevice = false;
     350         164 :     if (fXfermode == nullptr) {
     351         164 :         if (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) {
     352          29 :             fShadeDirectlyIntoDevice = true;
     353             :         }
     354             :     } else {
     355             :         SkXfermode::Mode mode;
     356           0 :         if (fXfermode->asMode(&mode)) {
     357           0 :             if (SkXfermode::kSrc_Mode == mode) {
     358           0 :                 fShadeDirectlyIntoDevice = true;
     359           0 :                 fProc32Blend = blend_srcmode;
     360             :             }
     361             :         }
     362             :     }
     363             : 
     364         164 :     fConstInY = SkToBool(shaderContext->getFlags() & SkShader::kConstInY32_Flag);
     365         164 : }
     366             : 
     367         328 : SkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() {
     368         164 :     sk_free(fBuffer);
     369         164 : }
     370             : 
     371        1228 : void SkARGB32_Shader_Blitter::blitH(int x, int y, int width) {
     372        1228 :     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
     373             : 
     374        1228 :     uint32_t* device = fDevice.writable_addr32(x, y);
     375             : 
     376        1228 :     if (fShadeDirectlyIntoDevice) {
     377           0 :         fShaderContext->shadeSpan(x, y, device, width);
     378             :     } else {
     379        1228 :         SkPMColor*  span = fBuffer;
     380        1228 :         fShaderContext->shadeSpan(x, y, span, width);
     381        1228 :         if (fXfermode) {
     382           0 :             fXfermode->xfer32(device, span, width, nullptr);
     383             :         } else {
     384        1228 :             fProc32(device, span, width, 255);
     385             :         }
     386             :     }
     387        1228 : }
     388             : 
     389          73 : void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) {
     390          73 :     SkASSERT(x >= 0 && y >= 0 &&
     391             :              x + width <= fDevice.width() && y + height <= fDevice.height());
     392             : 
     393          73 :     uint32_t*          device = fDevice.writable_addr32(x, y);
     394          73 :     size_t             deviceRB = fDevice.rowBytes();
     395          73 :     SkShader::Context* shaderContext = fShaderContext;
     396          73 :     SkPMColor*         span = fBuffer;
     397             : 
     398          73 :     if (fConstInY) {
     399           0 :         if (fShadeDirectlyIntoDevice) {
     400             :             // shade the first row directly into the device
     401           0 :             shaderContext->shadeSpan(x, y, device, width);
     402           0 :             span = device;
     403           0 :             while (--height > 0) {
     404           0 :                 device = (uint32_t*)((char*)device + deviceRB);
     405           0 :                 memcpy(device, span, width << 2);
     406             :             }
     407             :         } else {
     408           0 :             shaderContext->shadeSpan(x, y, span, width);
     409           0 :             SkXfermode* xfer = fXfermode;
     410           0 :             if (xfer) {
     411           0 :                 do {
     412           0 :                     xfer->xfer32(device, span, width, nullptr);
     413           0 :                     y += 1;
     414           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     415             :                 } while (--height > 0);
     416             :             } else {
     417           0 :                 SkBlitRow::Proc32 proc = fProc32;
     418           0 :                 do {
     419           0 :                     proc(device, span, width, 255);
     420           0 :                     y += 1;
     421           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     422             :                 } while (--height > 0);
     423             :             }
     424             :         }
     425           0 :         return;
     426             :     }
     427             : 
     428          73 :     if (fShadeDirectlyIntoDevice) {
     429             :         void* ctx;
     430          47 :         SkShader::Context::ShadeProc shadeProc = shaderContext->asAShadeProc(&ctx);
     431          47 :         if (shadeProc) {
     432       11341 :             do {
     433       11341 :                 shadeProc(ctx, x, y, device, width);
     434       11341 :                 y += 1;
     435       11341 :                 device = (uint32_t*)((char*)device + deviceRB);
     436             :             } while (--height > 0);
     437             :         } else {
     438           0 :             do {
     439           0 :                 shaderContext->shadeSpan(x, y, device, width);
     440           0 :                 y += 1;
     441           0 :                 device = (uint32_t*)((char*)device + deviceRB);
     442             :             } while (--height > 0);
     443             :         }
     444             :     } else {
     445          26 :         SkXfermode* xfer = fXfermode;
     446          26 :         if (xfer) {
     447           0 :             do {
     448           0 :                 shaderContext->shadeSpan(x, y, span, width);
     449           0 :                 xfer->xfer32(device, span, width, nullptr);
     450           0 :                 y += 1;
     451           0 :                 device = (uint32_t*)((char*)device + deviceRB);
     452             :             } while (--height > 0);
     453             :         } else {
     454          26 :             SkBlitRow::Proc32 proc = fProc32;
     455        1456 :             do {
     456        1456 :                 shaderContext->shadeSpan(x, y, span, width);
     457        1456 :                 proc(device, span, width, 255);
     458        1456 :                 y += 1;
     459        1456 :                 device = (uint32_t*)((char*)device + deviceRB);
     460             :             } while (--height > 0);
     461             :         }
     462             :     }
     463             : }
     464             : 
     465        2128 : void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     466             :                                         const int16_t runs[]) {
     467        2128 :     SkPMColor*         span = fBuffer;
     468        2128 :     uint32_t*          device = fDevice.writable_addr32(x, y);
     469        2128 :     SkShader::Context* shaderContext = fShaderContext;
     470             : 
     471        2128 :     if (fXfermode && !fShadeDirectlyIntoDevice) {
     472             :         for (;;) {
     473           0 :             SkXfermode* xfer = fXfermode;
     474             : 
     475           0 :             int count = *runs;
     476           0 :             if (count <= 0)
     477           0 :                 break;
     478           0 :             int aa = *antialias;
     479           0 :             if (aa) {
     480           0 :                 shaderContext->shadeSpan(x, y, span, count);
     481           0 :                 if (aa == 255) {
     482           0 :                     xfer->xfer32(device, span, count, nullptr);
     483             :                 } else {
     484             :                     // count is almost always 1
     485           0 :                     for (int i = count - 1; i >= 0; --i) {
     486           0 :                         xfer->xfer32(&device[i], &span[i], 1, antialias);
     487             :                     }
     488             :                 }
     489             :             }
     490           0 :             device += count;
     491           0 :             runs += count;
     492           0 :             antialias += count;
     493           0 :             x += count;
     494           0 :         }
     495        4244 :     } else if (fShadeDirectlyIntoDevice ||
     496        2116 :                (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
     497             :         for (;;) {
     498          24 :             int count = *runs;
     499          24 :             if (count <= 0) {
     500          12 :                 break;
     501             :             }
     502          12 :             int aa = *antialias;
     503          12 :             if (aa) {
     504          12 :                 if (aa == 255) {
     505             :                     // cool, have the shader draw right into the device
     506          12 :                     shaderContext->shadeSpan(x, y, device, count);
     507             :                 } else {
     508           0 :                     shaderContext->shadeSpan(x, y, span, count);
     509           0 :                     fProc32Blend(device, span, count, aa);
     510             :                 }
     511             :             }
     512          12 :             device += count;
     513          12 :             runs += count;
     514          12 :             antialias += count;
     515          12 :             x += count;
     516          12 :         }
     517             :     } else {
     518             :         for (;;) {
     519       12299 :             int count = *runs;
     520       12299 :             if (count <= 0) {
     521        2116 :                 break;
     522             :             }
     523       10183 :             int aa = *antialias;
     524       10183 :             if (aa) {
     525        5339 :                 shaderContext->shadeSpan(x, y, span, count);
     526        5339 :                 if (aa == 255) {
     527        4349 :                     fProc32(device, span, count, 255);
     528             :                 } else {
     529         990 :                     fProc32Blend(device, span, count, aa);
     530             :                 }
     531             :             }
     532       10183 :             device += count;
     533       10183 :             runs += count;
     534       10183 :             antialias += count;
     535       10183 :             x += count;
     536       10183 :         }
     537             :     }
     538        2128 : }
     539             : 
     540          61 : void SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     541             :     // we only handle kA8 with an xfermode
     542          61 :     if (fXfermode && (SkMask::kA8_Format != mask.fFormat)) {
     543           0 :         this->INHERITED::blitMask(mask, clip);
     544           0 :         return;
     545             :     }
     546             : 
     547          61 :     SkASSERT(mask.fBounds.contains(clip));
     548             : 
     549          61 :     SkShader::Context*  shaderContext = fShaderContext;
     550          61 :     SkBlitMask::RowProc proc = nullptr;
     551          61 :     if (!fXfermode) {
     552          61 :         unsigned flags = 0;
     553          61 :         if (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) {
     554          61 :             flags |= SkBlitMask::kSrcIsOpaque_RowFlag;
     555             :         }
     556          61 :         proc = SkBlitMask::RowFactory(kN32_SkColorType, mask.fFormat,
     557          61 :                                       (SkBlitMask::RowFlags)flags);
     558          61 :         if (nullptr == proc) {
     559           0 :             this->INHERITED::blitMask(mask, clip);
     560           0 :             return;
     561             :         }
     562             :     }
     563             : 
     564          61 :     const int x = clip.fLeft;
     565          61 :     const int width = clip.width();
     566          61 :     int y = clip.fTop;
     567          61 :     int height = clip.height();
     568             : 
     569          61 :     char* dstRow = (char*)fDevice.writable_addr32(x, y);
     570          61 :     const size_t dstRB = fDevice.rowBytes();
     571          61 :     const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y);
     572          61 :     const size_t maskRB = mask.fRowBytes;
     573             : 
     574          61 :     SkPMColor* span = fBuffer;
     575             : 
     576          61 :     if (fXfermode) {
     577           0 :         SkASSERT(SkMask::kA8_Format == mask.fFormat);
     578           0 :         SkXfermode* xfer = fXfermode;
     579           0 :         do {
     580           0 :             shaderContext->shadeSpan(x, y, span, width);
     581           0 :             xfer->xfer32(reinterpret_cast<SkPMColor*>(dstRow), span, width, maskRow);
     582           0 :             dstRow += dstRB;
     583           0 :             maskRow += maskRB;
     584           0 :             y += 1;
     585             :         } while (--height > 0);
     586             :     } else {
     587          90 :         do {
     588          90 :             shaderContext->shadeSpan(x, y, span, width);
     589          90 :             proc(reinterpret_cast<SkPMColor*>(dstRow), maskRow, span, width);
     590          90 :             dstRow += dstRB;
     591          90 :             maskRow += maskRB;
     592          90 :             y += 1;
     593             :         } while (--height > 0);
     594             :     }
     595             : }
     596             : 
     597           0 : void SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
     598           0 :     SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height());
     599             : 
     600           0 :     uint32_t*          device = fDevice.writable_addr32(x, y);
     601           0 :     size_t             deviceRB = fDevice.rowBytes();
     602           0 :     SkShader::Context* shaderContext = fShaderContext;
     603             : 
     604           0 :     if (fConstInY) {
     605             :         SkPMColor c;
     606           0 :         shaderContext->shadeSpan(x, y, &c, 1);
     607             : 
     608           0 :         if (fShadeDirectlyIntoDevice) {
     609           0 :             if (255 == alpha) {
     610           0 :                 do {
     611           0 :                     *device = c;
     612           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     613             :                 } while (--height > 0);
     614             :             } else {
     615           0 :                 do {
     616           0 :                     *device = SkFourByteInterp(c, *device, alpha);
     617           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     618             :                 } while (--height > 0);
     619             :             }
     620             :         } else {
     621           0 :             SkXfermode* xfer = fXfermode;
     622           0 :             if (xfer) {
     623           0 :                 do {
     624           0 :                     xfer->xfer32(device, &c, 1, &alpha);
     625           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     626             :                 } while (--height > 0);
     627             :             } else {
     628           0 :                 SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend;
     629           0 :                 do {
     630           0 :                     proc(device, &c, 1, alpha);
     631           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     632             :                 } while (--height > 0);
     633             :             }
     634             :         }
     635           0 :         return;
     636             :     }
     637             : 
     638           0 :     if (fShadeDirectlyIntoDevice) {
     639             :         void* ctx;
     640           0 :         SkShader::Context::ShadeProc shadeProc = shaderContext->asAShadeProc(&ctx);
     641           0 :         if (255 == alpha) {
     642           0 :             if (shadeProc) {
     643           0 :                 do {
     644           0 :                     shadeProc(ctx, x, y, device, 1);
     645           0 :                     y += 1;
     646           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     647             :                 } while (--height > 0);
     648             :             } else {
     649           0 :                 do {
     650           0 :                     shaderContext->shadeSpan(x, y, device, 1);
     651           0 :                     y += 1;
     652           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     653             :                 } while (--height > 0);
     654             :             }
     655             :         } else {    // alpha < 255
     656             :             SkPMColor c;
     657           0 :             if (shadeProc) {
     658           0 :                 do {
     659           0 :                     shadeProc(ctx, x, y, &c, 1);
     660           0 :                     *device = SkFourByteInterp(c, *device, alpha);
     661           0 :                     y += 1;
     662           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     663             :                 } while (--height > 0);
     664             :             } else {
     665           0 :                 do {
     666           0 :                     shaderContext->shadeSpan(x, y, &c, 1);
     667           0 :                     *device = SkFourByteInterp(c, *device, alpha);
     668           0 :                     y += 1;
     669           0 :                     device = (uint32_t*)((char*)device + deviceRB);
     670             :                 } while (--height > 0);
     671             :             }
     672             :         }
     673             :     } else {
     674           0 :         SkPMColor* span = fBuffer;
     675           0 :         SkXfermode* xfer = fXfermode;
     676           0 :         if (xfer) {
     677           0 :             do {
     678           0 :                 shaderContext->shadeSpan(x, y, span, 1);
     679           0 :                 xfer->xfer32(device, span, 1, &alpha);
     680           0 :                 y += 1;
     681           0 :                 device = (uint32_t*)((char*)device + deviceRB);
     682             :             } while (--height > 0);
     683             :         } else {
     684           0 :             SkBlitRow::Proc32 proc = (255 == alpha) ? fProc32 : fProc32Blend;
     685           0 :             do {
     686           0 :                 shaderContext->shadeSpan(x, y, span, 1);
     687           0 :                 proc(device, span, 1, alpha);
     688           0 :                 y += 1;
     689           0 :                 device = (uint32_t*)((char*)device + deviceRB);
     690             :             } while (--height > 0);
     691             :         }
     692             :     }
     693             : }

Generated by: LCOV version 1.13