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

       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 "SkXfermode.h"
      13                 : #include "SkBlitMask.h"
      14                 : 
      15                 : ///////////////////////////////////////////////////////////////////////////////
      16                 : 
      17               0 : static void SkARGB32_Blit32(const SkBitmap& 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.getAddr32(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               0 : SkARGB32_Blitter::SkARGB32_Blitter(const SkBitmap& device, const SkPaint& paint)
      44               0 :         : INHERITED(device) {
      45               0 :     SkColor color = paint.getColor();
      46               0 :     fColor = color;
      47                 : 
      48               0 :     fSrcA = SkColorGetA(color);
      49               0 :     unsigned scale = SkAlpha255To256(fSrcA);
      50               0 :     fSrcR = SkAlphaMul(SkColorGetR(color), scale);
      51               0 :     fSrcG = SkAlphaMul(SkColorGetG(color), scale);
      52               0 :     fSrcB = SkAlphaMul(SkColorGetB(color), scale);
      53                 : 
      54               0 :     fPMColor = SkPackARGB32(fSrcA, fSrcR, fSrcG, fSrcB);
      55               0 :     fColor32Proc = SkBlitRow::ColorProcFactory();
      56               0 : }
      57                 : 
      58               0 : const SkBitmap* SkARGB32_Blitter::justAnOpaqueColor(uint32_t* value) {
      59               0 :     if (255 == fSrcA) {
      60               0 :         *value = fPMColor;
      61               0 :         return &fDevice;
      62                 :     }
      63               0 :     return NULL;
      64                 : }
      65                 : 
      66                 : #if defined _WIN32 && _MSC_VER >= 1300  // disable warning : local variable used without having been initialized
      67                 : #pragma warning ( push )
      68                 : #pragma warning ( disable : 4701 )
      69                 : #endif
      70                 : 
      71               0 : void SkARGB32_Blitter::blitH(int x, int y, int width) {
      72               0 :     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
      73                 : 
      74               0 :     uint32_t*   device = fDevice.getAddr32(x, y);
      75               0 :     fColor32Proc(device, device, width, fPMColor);
      76               0 : }
      77                 : 
      78               0 : void SkARGB32_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
      79                 :                                  const int16_t runs[]) {
      80               0 :     if (fSrcA == 0) {
      81               0 :         return;
      82                 :     }
      83                 : 
      84               0 :     uint32_t    color = fPMColor;
      85               0 :     uint32_t*   device = fDevice.getAddr32(x, y);
      86               0 :     unsigned    opaqueMask = fSrcA; // if fSrcA is 0xFF, then we will catch the fast opaque case
      87                 : 
      88               0 :     for (;;) {
      89               0 :         int count = runs[0];
      90               0 :         SkASSERT(count >= 0);
      91               0 :         if (count <= 0) {
      92               0 :             return;
      93                 :         }
      94               0 :         unsigned aa = antialias[0];
      95               0 :         if (aa) {
      96               0 :             if ((opaqueMask & aa) == 255) {
      97               0 :                 sk_memset32(device, color, count);
      98                 :             } else {
      99               0 :                 uint32_t sc = SkAlphaMulQ(color, SkAlpha255To256(aa));
     100               0 :                 fColor32Proc(device, device, count, sc);
     101                 :             }
     102                 :         }
     103               0 :         runs += count;
     104               0 :         antialias += count;
     105               0 :         device += count;
     106                 :     }
     107                 : }
     108                 : 
     109                 : //////////////////////////////////////////////////////////////////////////////////////
     110                 : 
     111                 : #define solid_8_pixels(mask, dst, color)    \
     112                 :     do {                                    \
     113                 :         if (mask & 0x80) dst[0] = color;    \
     114                 :         if (mask & 0x40) dst[1] = color;    \
     115                 :         if (mask & 0x20) dst[2] = color;    \
     116                 :         if (mask & 0x10) dst[3] = color;    \
     117                 :         if (mask & 0x08) dst[4] = color;    \
     118                 :         if (mask & 0x04) dst[5] = color;    \
     119                 :         if (mask & 0x02) dst[6] = color;    \
     120                 :         if (mask & 0x01) dst[7] = color;    \
     121                 :     } while (0)
     122                 : 
     123                 : #define SK_BLITBWMASK_NAME                  SkARGB32_BlitBW
     124                 : #define SK_BLITBWMASK_ARGS                  , SkPMColor color
     125                 : #define SK_BLITBWMASK_BLIT8(mask, dst)      solid_8_pixels(mask, dst, color)
     126                 : #define SK_BLITBWMASK_GETADDR               getAddr32
     127                 : #define SK_BLITBWMASK_DEVTYPE               uint32_t
     128                 : #include "SkBlitBWMaskTemplate.h"
     129                 : 
     130                 : #define blend_8_pixels(mask, dst, sc, dst_scale)                            \
     131                 :     do {                                                                    \
     132                 :         if (mask & 0x80) { dst[0] = sc + SkAlphaMulQ(dst[0], dst_scale); }  \
     133                 :         if (mask & 0x40) { dst[1] = sc + SkAlphaMulQ(dst[1], dst_scale); }  \
     134                 :         if (mask & 0x20) { dst[2] = sc + SkAlphaMulQ(dst[2], dst_scale); }  \
     135                 :         if (mask & 0x10) { dst[3] = sc + SkAlphaMulQ(dst[3], dst_scale); }  \
     136                 :         if (mask & 0x08) { dst[4] = sc + SkAlphaMulQ(dst[4], dst_scale); }  \
     137                 :         if (mask & 0x04) { dst[5] = sc + SkAlphaMulQ(dst[5], dst_scale); }  \
     138                 :         if (mask & 0x02) { dst[6] = sc + SkAlphaMulQ(dst[6], dst_scale); }  \
     139                 :         if (mask & 0x01) { dst[7] = sc + SkAlphaMulQ(dst[7], dst_scale); }  \
     140                 :     } while (0)
     141                 : 
     142                 : #define SK_BLITBWMASK_NAME                  SkARGB32_BlendBW
     143                 : #define SK_BLITBWMASK_ARGS                  , uint32_t sc, unsigned dst_scale
     144                 : #define SK_BLITBWMASK_BLIT8(mask, dst)      blend_8_pixels(mask, dst, sc, dst_scale)
     145                 : #define SK_BLITBWMASK_GETADDR               getAddr32
     146                 : #define SK_BLITBWMASK_DEVTYPE               uint32_t
     147                 : #include "SkBlitBWMaskTemplate.h"
     148                 : 
     149               0 : void SkARGB32_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     150               0 :     SkASSERT(mask.fBounds.contains(clip));
     151               0 :     SkASSERT(fSrcA != 0xFF);
     152                 : 
     153               0 :     if (fSrcA == 0) {
     154               0 :         return;
     155                 :     }
     156                 : 
     157               0 :     if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
     158               0 :         return;
     159                 :     }
     160                 : 
     161               0 :     if (mask.fFormat == SkMask::kBW_Format) {
     162               0 :         SkARGB32_BlendBW(fDevice, mask, clip, fPMColor, SkAlpha255To256(255 - fSrcA));
     163               0 :     } else if (SkMask::kARGB32_Format == mask.fFormat) {
     164               0 :                 SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
     165                 :     }
     166                 : }
     167                 : 
     168               0 : void SkARGB32_Opaque_Blitter::blitMask(const SkMask& mask,
     169                 :                                        const SkIRect& clip) {
     170               0 :     SkASSERT(mask.fBounds.contains(clip));
     171                 : 
     172               0 :     if (SkBlitMask::BlitColor(fDevice, mask, clip, fColor)) {
     173               0 :         return;
     174                 :     }
     175                 :     
     176               0 :     if (mask.fFormat == SkMask::kBW_Format) {
     177               0 :         SkARGB32_BlitBW(fDevice, mask, clip, fPMColor);
     178               0 :     } else if (SkMask::kARGB32_Format == mask.fFormat) {
     179               0 :                 SkARGB32_Blit32(fDevice, mask, clip, fPMColor);
     180                 :         }
     181                 : }
     182                 : 
     183                 : ///////////////////////////////////////////////////////////////////////////////
     184                 : 
     185               0 : void SkARGB32_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
     186               0 :     if (alpha == 0 || fSrcA == 0) {
     187               0 :         return;
     188                 :     }
     189                 : 
     190               0 :     uint32_t* device = fDevice.getAddr32(x, y);
     191               0 :     uint32_t  color = fPMColor;
     192                 : 
     193               0 :     if (alpha != 255) {
     194               0 :         color = SkAlphaMulQ(color, SkAlpha255To256(alpha));
     195                 :     }
     196                 : 
     197               0 :     unsigned dst_scale = 255 - SkGetPackedA32(color);
     198               0 :     uint32_t rowBytes = fDevice.rowBytes();
     199               0 :     while (--height >= 0) {
     200               0 :         device[0] = color + SkAlphaMulQ(device[0], dst_scale);
     201               0 :         device = (uint32_t*)((char*)device + rowBytes);
     202                 :     }
     203                 : }
     204                 : 
     205               0 : void SkARGB32_Blitter::blitRect(int x, int y, int width, int height) {
     206               0 :     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height <= fDevice.height());
     207                 : 
     208               0 :     if (fSrcA == 0) {
     209               0 :         return;
     210                 :     }
     211                 : 
     212               0 :     uint32_t*   device = fDevice.getAddr32(x, y);
     213               0 :     uint32_t    color = fPMColor;
     214               0 :     size_t      rowBytes = fDevice.rowBytes();
     215                 : 
     216               0 :     while (--height >= 0) {
     217               0 :         fColor32Proc(device, device, width, color);
     218               0 :         device = (uint32_t*)((char*)device + rowBytes);
     219                 :     }
     220                 : }
     221                 : 
     222                 : #if defined _WIN32 && _MSC_VER >= 1300
     223                 : #pragma warning ( pop )
     224                 : #endif
     225                 : 
     226                 : ///////////////////////////////////////////////////////////////////////
     227                 : 
     228               0 : void SkARGB32_Black_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     229                 :                                        const int16_t runs[]) {
     230               0 :     uint32_t*   device = fDevice.getAddr32(x, y);
     231               0 :     SkPMColor   black = (SkPMColor)(SK_A32_MASK << SK_A32_SHIFT);
     232                 : 
     233               0 :     for (;;) {
     234               0 :         int count = runs[0];
     235               0 :         SkASSERT(count >= 0);
     236               0 :         if (count <= 0) {
     237                 :             return;
     238                 :         }
     239               0 :         unsigned aa = antialias[0];
     240               0 :         if (aa) {
     241               0 :             if (aa == 255) {
     242               0 :                 sk_memset32(device, black, count);
     243                 :             } else {
     244               0 :                 SkPMColor src = aa << SK_A32_SHIFT;
     245               0 :                 unsigned dst_scale = 256 - aa;
     246               0 :                 int n = count;
     247               0 :                 do {
     248               0 :                     --n;
     249               0 :                     device[n] = src + SkAlphaMulQ(device[n], dst_scale);
     250                 :                 } while (n > 0);
     251                 :             }
     252                 :         }
     253               0 :         runs += count;
     254               0 :         antialias += count;
     255               0 :         device += count;
     256                 :     }
     257                 : }
     258                 : 
     259                 : ///////////////////////////////////////////////////////////////////////////////
     260                 : 
     261               0 : SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkBitmap& device,
     262               0 :                             const SkPaint& paint) : INHERITED(device, paint) {
     263               0 :     fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
     264                 : 
     265               0 :     fXfermode = paint.getXfermode();
     266               0 :     SkSafeRef(fXfermode);
     267                 : 
     268               0 :     int flags = 0;
     269               0 :     if (!(fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
     270               0 :         flags |= SkBlitRow::kSrcPixelAlpha_Flag32;
     271                 :     }
     272                 :     // we call this on the output from the shader
     273               0 :     fProc32 = SkBlitRow::Factory32(flags);
     274                 :     // we call this on the output from the shader + alpha from the aa buffer
     275               0 :     fProc32Blend = SkBlitRow::Factory32(flags | SkBlitRow::kGlobalAlpha_Flag32);
     276               0 : }
     277                 : 
     278               0 : SkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() {
     279               0 :     SkSafeUnref(fXfermode);
     280               0 :     sk_free(fBuffer);
     281               0 : }
     282                 : 
     283               0 : void SkARGB32_Shader_Blitter::blitH(int x, int y, int width) {
     284               0 :     SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width());
     285                 : 
     286               0 :     uint32_t*   device = fDevice.getAddr32(x, y);
     287                 : 
     288               0 :     if (fXfermode == NULL && (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
     289               0 :         fShader->shadeSpan(x, y, device, width);
     290                 :     } else {
     291               0 :         SkPMColor*  span = fBuffer;
     292               0 :         fShader->shadeSpan(x, y, span, width);
     293               0 :         if (fXfermode) {
     294               0 :             fXfermode->xfer32(device, span, width, NULL);
     295                 :         } else {
     296               0 :             fProc32(device, span, width, 255);
     297                 :         }
     298                 :     }
     299               0 : }
     300                 : 
     301               0 : void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
     302                 :                                         const int16_t runs[]) {
     303               0 :     SkPMColor*  span = fBuffer;
     304               0 :     uint32_t*   device = fDevice.getAddr32(x, y);
     305               0 :     SkShader*   shader = fShader;
     306                 : 
     307               0 :     if (fXfermode) {
     308               0 :         for (;;) {
     309               0 :             SkXfermode* xfer = fXfermode;
     310                 : 
     311               0 :             int count = *runs;
     312               0 :             if (count <= 0)
     313                 :                 break;
     314               0 :             int aa = *antialias;
     315               0 :             if (aa) {
     316               0 :                 shader->shadeSpan(x, y, span, count);
     317               0 :                 if (aa == 255) {
     318               0 :                     xfer->xfer32(device, span, count, NULL);
     319                 :                 } else {
     320                 :                     // count is almost always 1
     321               0 :                     for (int i = count - 1; i >= 0; --i) {
     322               0 :                         xfer->xfer32(&device[i], &span[i], 1, antialias);
     323                 :                     }
     324                 :                 }
     325                 :             }
     326               0 :             device += count;
     327               0 :             runs += count;
     328               0 :             antialias += count;
     329               0 :             x += count;
     330                 :         }
     331               0 :     } else if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) {
     332               0 :         for (;;) {
     333               0 :             int count = *runs;
     334               0 :             if (count <= 0) {
     335                 :                 break;
     336                 :             }
     337               0 :             int aa = *antialias;
     338               0 :             if (aa) {
     339               0 :                 if (aa == 255) {
     340                 :                     // cool, have the shader draw right into the device
     341               0 :                     shader->shadeSpan(x, y, device, count);
     342                 :                 } else {
     343               0 :                     shader->shadeSpan(x, y, span, count);
     344               0 :                     fProc32Blend(device, span, count, aa);
     345                 :                 }
     346                 :             }
     347               0 :             device += count;
     348               0 :             runs += count;
     349               0 :             antialias += count;
     350               0 :             x += count;
     351                 :         }
     352                 :     } else {    // no xfermode but the shader not opaque
     353               0 :         for (;;) {
     354               0 :             int count = *runs;
     355               0 :             if (count <= 0) {
     356               0 :                 break;
     357                 :             }
     358               0 :             int aa = *antialias;
     359               0 :             if (aa) {
     360               0 :                 fShader->shadeSpan(x, y, span, count);
     361               0 :                 if (aa == 255) {
     362               0 :                     fProc32(device, span, count, 255);
     363                 :                 } else {
     364               0 :                     fProc32Blend(device, span, count, aa);
     365                 :                 }
     366                 :             }
     367               0 :             device += count;
     368               0 :             runs += count;
     369               0 :             antialias += count;
     370               0 :             x += count;
     371                 :         }
     372                 :     }
     373               0 : }
     374                 : 
     375               0 : void SkARGB32_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
     376                 :     // we only handle kA8 with an xfermode
     377               0 :     if (fXfermode && (SkMask::kA8_Format != mask.fFormat)) {
     378               0 :         this->INHERITED::blitMask(mask, clip);
     379               0 :         return;
     380                 :     }
     381                 : 
     382               0 :     SkASSERT(mask.fBounds.contains(clip));
     383                 : 
     384               0 :     SkBlitMask::RowProc proc = NULL;
     385               0 :     if (!fXfermode) {
     386               0 :         unsigned flags = 0;
     387               0 :         if (fShader->getFlags() & SkShader::kOpaqueAlpha_Flag) {
     388               0 :             flags |= SkBlitMask::kSrcIsOpaque_RowFlag;
     389                 :         }
     390                 :         proc = SkBlitMask::RowFactory(SkBitmap::kARGB_8888_Config, mask.fFormat,
     391               0 :                                       (SkBlitMask::RowFlags)flags);
     392               0 :         if (NULL == proc) {
     393               0 :             this->INHERITED::blitMask(mask, clip);
     394               0 :             return;
     395                 :         }
     396                 :     }
     397                 : 
     398               0 :     const int x = clip.fLeft;
     399               0 :     const int width = clip.width();
     400               0 :     int y = clip.fTop;
     401               0 :     int height = clip.height();
     402                 : 
     403               0 :     char* dstRow = (char*)fDevice.getAddr32(x, y);
     404               0 :     const size_t dstRB = fDevice.rowBytes();
     405               0 :     const uint8_t* maskRow = (const uint8_t*)mask.getAddr(x, y);
     406               0 :     const size_t maskRB = mask.fRowBytes;
     407                 : 
     408               0 :     SkShader* shader = fShader;
     409               0 :     SkPMColor* span = fBuffer;
     410                 : 
     411               0 :     if (fXfermode) {
     412               0 :         SkASSERT(SkMask::kA8_Format == mask.fFormat);
     413               0 :         SkXfermode* xfer = fXfermode;
     414               0 :         do {
     415               0 :             shader->shadeSpan(x, y, span, width);
     416               0 :             xfer->xfer32((SkPMColor*)dstRow, span, width, maskRow);
     417               0 :             dstRow += dstRB;
     418               0 :             maskRow += maskRB;
     419               0 :             y += 1;
     420                 :         } while (--height > 0);
     421                 :     } else {
     422               0 :         do {
     423               0 :             shader->shadeSpan(x, y, span, width);
     424               0 :             proc(dstRow, maskRow, span, width);
     425               0 :             dstRow += dstRB;
     426               0 :             maskRow += maskRB;
     427               0 :             y += 1;
     428                 :         } while (--height > 0);
     429                 :     }
     430                 : }
     431                 : 

Generated by: LCOV version 1.7