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

       1                 : #include "SkBlitMask.h"
       2                 : #include "SkColor.h"
       3                 : #include "SkColorPriv.h"
       4                 : 
       5               0 : static void D32_A8_Color(void* SK_RESTRICT dst, size_t dstRB,
       6                 :                          const void* SK_RESTRICT maskPtr, size_t maskRB,
       7                 :                          SkColor color, int width, int height) {
       8               0 :     SkPMColor pmc = SkPreMultiplyColor(color);
       9               0 :     size_t dstOffset = dstRB - (width << 2);
      10               0 :     size_t maskOffset = maskRB - width;
      11               0 :     SkPMColor* SK_RESTRICT device = (SkPMColor *)dst;
      12               0 :     const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr;
      13                 : 
      14               0 :     do {
      15               0 :         int w = width;
      16               0 :         do {
      17               0 :             unsigned aa = *mask++;
      18               0 :             *device = SkBlendARGB32(pmc, *device, aa);
      19               0 :             device += 1;
      20                 :         } while (--w != 0);
      21               0 :         device = (uint32_t*)((char*)device + dstOffset);
      22               0 :         mask += maskOffset;
      23                 :     } while (--height != 0);
      24               0 : }
      25                 : 
      26               0 : static void D32_A8_Opaque(void* SK_RESTRICT dst, size_t dstRB,
      27                 :                           const void* SK_RESTRICT maskPtr, size_t maskRB,
      28                 :                           SkColor color, int width, int height) {
      29               0 :     SkPMColor pmc = SkPreMultiplyColor(color);
      30               0 :     SkPMColor* SK_RESTRICT device = (SkPMColor*)dst;
      31               0 :     const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr;
      32                 : 
      33               0 :     maskRB -= width;
      34               0 :     dstRB -= (width << 2);
      35               0 :     do {
      36               0 :         int w = width;
      37               0 :         do {
      38               0 :             unsigned aa = *mask++;
      39               0 :             *device = SkAlphaMulQ(pmc, SkAlpha255To256(aa)) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
      40               0 :             device += 1;
      41                 :         } while (--w != 0);
      42               0 :         device = (uint32_t*)((char*)device + dstRB);
      43               0 :         mask += maskRB;
      44                 :     } while (--height != 0);
      45               0 : }
      46                 : 
      47               0 : static void D32_A8_Black(void* SK_RESTRICT dst, size_t dstRB,
      48                 :                          const void* SK_RESTRICT maskPtr, size_t maskRB,
      49                 :                          SkColor, int width, int height) {
      50               0 :     SkPMColor* SK_RESTRICT device = (SkPMColor*)dst;
      51               0 :     const uint8_t* SK_RESTRICT mask = (const uint8_t*)maskPtr;
      52                 : 
      53               0 :     maskRB -= width;
      54               0 :     dstRB -= (width << 2);
      55               0 :     do {
      56               0 :         int w = width;
      57               0 :         do {
      58               0 :             unsigned aa = *mask++;
      59               0 :             *device = (aa << SK_A32_SHIFT) + SkAlphaMulQ(*device, SkAlpha255To256(255 - aa));
      60               0 :             device += 1;
      61                 :         } while (--w != 0);
      62               0 :         device = (uint32_t*)((char*)device + dstRB);
      63               0 :         mask += maskRB;
      64                 :     } while (--height != 0);
      65               0 : }
      66                 : 
      67                 : ///////////////////////////////////////////////////////////////////////////////
      68                 : 
      69               0 : static inline int upscale31To32(int value) {
      70               0 :     SkASSERT((unsigned)value <= 31);
      71               0 :     return value + (value >> 4);
      72                 : }
      73                 : 
      74               0 : static inline int blend32(int src, int dst, int scale) {
      75               0 :     SkASSERT((unsigned)src <= 0xFF);
      76               0 :     SkASSERT((unsigned)dst <= 0xFF);
      77               0 :     SkASSERT((unsigned)scale <= 32);
      78               0 :     return dst + ((src - dst) * scale >> 5);
      79                 : }
      80                 : 
      81               0 : static void blit_lcd16_row(SkPMColor dst[], const uint16_t src[],
      82                 :                            SkColor color, int width, SkPMColor) {
      83               0 :     int srcA = SkColorGetA(color);
      84               0 :     int srcR = SkColorGetR(color);
      85               0 :     int srcG = SkColorGetG(color);
      86               0 :     int srcB = SkColorGetB(color);
      87                 :     
      88               0 :     srcA = SkAlpha255To256(srcA);
      89                 :     
      90               0 :     for (int i = 0; i < width; i++) {
      91               0 :         uint16_t mask = src[i];
      92               0 :         if (0 == mask) {
      93               0 :             continue;
      94                 :         }
      95                 :         
      96               0 :         SkPMColor d = dst[i];
      97                 :         
      98                 :         /*  We want all of these in 5bits, hence the shifts in case one of them
      99                 :          *  (green) is 6bits.
     100                 :          */
     101               0 :         int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
     102               0 :         int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
     103               0 :         int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
     104                 :         
     105                 :         // Now upscale them to 0..32, so we can use blend32
     106               0 :         maskR = upscale31To32(maskR);
     107               0 :         maskG = upscale31To32(maskG);
     108               0 :         maskB = upscale31To32(maskB);
     109                 :         
     110               0 :         maskR = maskR * srcA >> 8;
     111               0 :         maskG = maskG * srcA >> 8;
     112               0 :         maskB = maskB * srcA >> 8;
     113                 :         
     114               0 :         int dstR = SkGetPackedR32(d);
     115               0 :         int dstG = SkGetPackedG32(d);
     116               0 :         int dstB = SkGetPackedB32(d);
     117                 :         
     118                 :         // LCD blitting is only supported if the dst is known/required
     119                 :         // to be opaque
     120               0 :         dst[i] = SkPackARGB32(0xFF,
     121               0 :                               blend32(srcR, dstR, maskR),
     122               0 :                               blend32(srcG, dstG, maskG),
     123               0 :                               blend32(srcB, dstB, maskB));
     124                 :     }
     125               0 : }
     126                 : 
     127               0 : static void blit_lcd16_opaque_row(SkPMColor dst[], const uint16_t src[],
     128                 :                                   SkColor color, int width, SkPMColor opaqueDst) {
     129               0 :     int srcR = SkColorGetR(color);
     130               0 :     int srcG = SkColorGetG(color);
     131               0 :     int srcB = SkColorGetB(color);
     132                 :     
     133               0 :     for (int i = 0; i < width; i++) {
     134               0 :         uint16_t mask = src[i];
     135               0 :         if (0 == mask) {
     136               0 :             continue;
     137                 :         }
     138               0 :         if (0xFFFF == mask) {
     139               0 :             dst[i] = opaqueDst;
     140               0 :             continue;
     141                 :         }
     142                 :         
     143               0 :         SkPMColor d = dst[i];
     144                 :         
     145                 :         /*  We want all of these in 5bits, hence the shifts in case one of them
     146                 :          *  (green) is 6bits.
     147                 :          */
     148               0 :         int maskR = SkGetPackedR16(mask) >> (SK_R16_BITS - 5);
     149               0 :         int maskG = SkGetPackedG16(mask) >> (SK_G16_BITS - 5);
     150               0 :         int maskB = SkGetPackedB16(mask) >> (SK_B16_BITS - 5);
     151                 :         
     152                 :         // Now upscale them to 0..32, so we can use blend32
     153               0 :         maskR = upscale31To32(maskR);
     154               0 :         maskG = upscale31To32(maskG);
     155               0 :         maskB = upscale31To32(maskB);
     156                 :         
     157               0 :         int dstR = SkGetPackedR32(d);
     158               0 :         int dstG = SkGetPackedG32(d);
     159               0 :         int dstB = SkGetPackedB32(d);
     160                 :         
     161                 :         // LCD blitting is only supported if the dst is known/required
     162                 :         // to be opaque
     163               0 :         dst[i] = SkPackARGB32(0xFF,
     164               0 :                               blend32(srcR, dstR, maskR),
     165               0 :                               blend32(srcG, dstG, maskG),
     166               0 :                               blend32(srcB, dstB, maskB));
     167                 :     }
     168               0 : }
     169                 : 
     170               0 : static void D32_LCD16_Proc(void* SK_RESTRICT dst, size_t dstRB,
     171                 :                            const void* SK_RESTRICT mask, size_t maskRB,
     172                 :                            SkColor color, int width, int height) {
     173                 :     
     174               0 :     SkPMColor*          dstRow = (SkPMColor*)dst;
     175               0 :     const uint16_t* srcRow = (const uint16_t*)mask;
     176                 :     SkPMColor       opaqueDst;
     177                 :     
     178                 :     void (*proc)(SkPMColor dst[], const uint16_t src[],
     179                 :                  SkColor color, int width, SkPMColor);
     180               0 :     if (0xFF == SkColorGetA(color)) {
     181               0 :         proc = blit_lcd16_opaque_row;
     182               0 :         opaqueDst = SkPreMultiplyColor(color);
     183                 :     } else {
     184               0 :         proc = blit_lcd16_row;
     185               0 :         opaqueDst = 0;  // ignored
     186                 :     }
     187                 :     
     188               0 :     do {
     189               0 :         proc(dstRow, srcRow, color, width, opaqueDst);
     190               0 :         dstRow = (SkPMColor*)((char*)dstRow + dstRB);
     191               0 :         srcRow = (const uint16_t*)((const char*)srcRow + maskRB);
     192                 :     } while (--height != 0);
     193               0 : }
     194                 : 
     195                 : ///////////////////////////////////////////////////////////////////////////////
     196                 : 
     197               0 : static void blit_lcd32_opaque_row(SkPMColor* SK_RESTRICT dst,
     198                 :                                   const SkPMColor* SK_RESTRICT src,
     199                 :                                   SkColor color, int width) {
     200               0 :     int srcR = SkColorGetR(color);
     201               0 :     int srcG = SkColorGetG(color);
     202               0 :     int srcB = SkColorGetB(color);
     203                 :     
     204               0 :     for (int i = 0; i < width; i++) {
     205               0 :         SkPMColor mask = src[i];
     206               0 :         if (0 == mask) {
     207               0 :             continue;
     208                 :         }
     209                 :         
     210               0 :         SkPMColor d = dst[i];
     211                 :         
     212               0 :         int maskR = SkGetPackedR32(mask);
     213               0 :         int maskG = SkGetPackedG32(mask);
     214               0 :         int maskB = SkGetPackedB32(mask);
     215                 :         
     216                 :         // Now upscale them to 0..256, so we can use SkAlphaBlend
     217               0 :         maskR = SkAlpha255To256(maskR);
     218               0 :         maskG = SkAlpha255To256(maskG);
     219               0 :         maskB = SkAlpha255To256(maskB);
     220                 :         
     221               0 :         int dstR = SkGetPackedR32(d);
     222               0 :         int dstG = SkGetPackedG32(d);
     223               0 :         int dstB = SkGetPackedB32(d);
     224                 :         
     225                 :         // LCD blitting is only supported if the dst is known/required
     226                 :         // to be opaque
     227               0 :         dst[i] = SkPackARGB32(0xFF,
     228               0 :                               SkAlphaBlend(srcR, dstR, maskR),
     229               0 :                               SkAlphaBlend(srcG, dstG, maskG),
     230               0 :                               SkAlphaBlend(srcB, dstB, maskB));
     231                 :     }
     232               0 : }
     233                 : 
     234               0 : static void blit_lcd32_row(SkPMColor* SK_RESTRICT dst,
     235                 :                            const SkPMColor* SK_RESTRICT src,
     236                 :                            SkColor color, int width) {
     237               0 :     int srcA = SkColorGetA(color);
     238               0 :     int srcR = SkColorGetR(color);
     239               0 :     int srcG = SkColorGetG(color);
     240               0 :     int srcB = SkColorGetB(color);
     241                 :     
     242               0 :     srcA = SkAlpha255To256(srcA);
     243                 :     
     244               0 :     for (int i = 0; i < width; i++) {
     245               0 :         SkPMColor mask = src[i];
     246               0 :         if (0 == mask) {
     247               0 :             continue;
     248                 :         }
     249                 :         
     250               0 :         SkPMColor d = dst[i];
     251                 :         
     252               0 :         int maskR = SkGetPackedR32(mask);
     253               0 :         int maskG = SkGetPackedG32(mask);
     254               0 :         int maskB = SkGetPackedB32(mask);
     255                 :         
     256                 :         // Now upscale them to 0..256, so we can use SkAlphaBlend
     257               0 :         maskR = SkAlpha255To256(maskR);
     258               0 :         maskG = SkAlpha255To256(maskG);
     259               0 :         maskB = SkAlpha255To256(maskB);
     260                 :         
     261               0 :         maskR = maskR * srcA >> 8;
     262               0 :         maskG = maskG * srcA >> 8;
     263               0 :         maskB = maskB * srcA >> 8;
     264                 :         
     265               0 :         int dstR = SkGetPackedR32(d);
     266               0 :         int dstG = SkGetPackedG32(d);
     267               0 :         int dstB = SkGetPackedB32(d);
     268                 :         
     269                 :         // LCD blitting is only supported if the dst is known/required
     270                 :         // to be opaque
     271               0 :         dst[i] = SkPackARGB32(0xFF,
     272               0 :                               SkAlphaBlend(srcR, dstR, maskR),
     273               0 :                               SkAlphaBlend(srcG, dstG, maskG),
     274               0 :                               SkAlphaBlend(srcB, dstB, maskB));
     275                 :     }
     276               0 : }
     277                 : 
     278               0 : static void D32_LCD32_Blend(void* SK_RESTRICT dst, size_t dstRB,
     279                 :                             const void* SK_RESTRICT mask, size_t maskRB,
     280                 :                             SkColor color, int width, int height) {
     281               0 :     SkASSERT(height > 0);
     282               0 :     SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst;
     283               0 :     const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask;
     284                 :     
     285               0 :     do {
     286               0 :         blit_lcd32_row(dstRow, srcRow, color, width);
     287               0 :         dstRow = (SkPMColor*)((char*)dstRow + dstRB);
     288               0 :         srcRow = (const SkPMColor*)((const char*)srcRow + maskRB);
     289                 :     } while (--height != 0);
     290               0 : }
     291                 : 
     292               0 : static void D32_LCD32_Opaque(void* SK_RESTRICT dst, size_t dstRB,
     293                 :                              const void* SK_RESTRICT mask, size_t maskRB,
     294                 :                              SkColor color, int width, int height) {
     295               0 :     SkASSERT(height > 0);
     296               0 :     SkPMColor* SK_RESTRICT dstRow = (SkPMColor*)dst;
     297               0 :     const SkPMColor* SK_RESTRICT srcRow = (const SkPMColor*)mask;
     298                 :     
     299               0 :     do {
     300               0 :         blit_lcd32_opaque_row(dstRow, srcRow, color, width);
     301               0 :         dstRow = (SkPMColor*)((char*)dstRow + dstRB);
     302               0 :         srcRow = (const SkPMColor*)((const char*)srcRow + maskRB);
     303                 :     } while (--height != 0);
     304               0 : }
     305                 : 
     306                 : ///////////////////////////////////////////////////////////////////////////////
     307                 : 
     308               0 : static SkBlitMask::ColorProc D32_A8_Factory(SkColor color) {
     309               0 :     if (SK_ColorBLACK == color) {
     310               0 :         return D32_A8_Black;
     311               0 :     } else if (0xFF == SkColorGetA(color)) {
     312               0 :         return D32_A8_Opaque;
     313                 :     } else {
     314               0 :         return D32_A8_Color;
     315                 :     }
     316                 : }
     317                 : 
     318               0 : static SkBlitMask::ColorProc D32_LCD32_Factory(SkColor color) {
     319               0 :     return (0xFF == SkColorGetA(color)) ? D32_LCD32_Opaque : D32_LCD32_Blend;
     320                 : }
     321                 : 
     322               0 : SkBlitMask::ColorProc SkBlitMask::ColorFactory(SkBitmap::Config config,
     323                 :                                                SkMask::Format format,
     324                 :                                                SkColor color) {
     325               0 :     ColorProc proc = PlatformColorProcs(config, format, color);
     326               0 :     if (proc) {
     327               0 :         return proc;
     328                 :     }
     329                 : 
     330               0 :     switch (config) {
     331                 :         case SkBitmap::kARGB_8888_Config:
     332               0 :             switch (format) {
     333                 :                 case SkMask::kA8_Format:
     334               0 :                     return D32_A8_Factory(color);
     335                 :                 case SkMask::kLCD16_Format:
     336               0 :                     return D32_LCD16_Proc;
     337                 :                 case SkMask::kLCD32_Format:
     338               0 :                     return D32_LCD32_Factory(color);
     339                 :                 default:
     340                 :                     break;
     341                 :             }
     342               0 :             break;
     343                 :         default:
     344               0 :             break;
     345                 :     }
     346               0 :     return NULL;
     347                 : }
     348                 : 
     349               0 : bool SkBlitMask::BlitColor(const SkBitmap& device, const SkMask& mask,
     350                 :                            const SkIRect& clip, SkColor color) {
     351               0 :     ColorProc proc = ColorFactory(device.config(), mask.fFormat, color);
     352               0 :     if (proc) {
     353               0 :         int x = clip.fLeft;
     354               0 :         int y = clip.fTop;
     355               0 :         proc(device.getAddr32(x, y), device.rowBytes(), mask.getAddr(x, y),
     356               0 :              mask.fRowBytes, color, clip.width(), clip.height());
     357               0 :         return true;
     358                 :     }
     359               0 :     return false;
     360                 : }
     361                 : 
     362                 : ///////////////////////////////////////////////////////////////////////////////
     363                 : ///////////////////////////////////////////////////////////////////////////////
     364                 : 
     365               0 : static void BW_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
     366                 :                              const uint8_t* SK_RESTRICT mask,
     367                 :                              const SkPMColor* SK_RESTRICT src, int count) {
     368               0 :     int i, octuple = (count + 7) >> 3;
     369               0 :     for (i = 0; i < octuple; ++i) {
     370               0 :         int m = *mask++;
     371               0 :         if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
     372               0 :         if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); }
     373               0 :         if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); }
     374               0 :         if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); }
     375               0 :         if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); }
     376               0 :         if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); }
     377               0 :         if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); }
     378               0 :         if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); }
     379               0 :         src += 8;
     380               0 :         dst += 8;
     381                 :     }
     382               0 :     count &= 7;
     383               0 :     if (count > 0) {
     384               0 :         int m = *mask;
     385               0 :         do {
     386               0 :             if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
     387               0 :             m <<= 1;
     388               0 :             src += 1;
     389               0 :             dst += 1;
     390                 :         } while (--count > 0);
     391                 :     }
     392               0 : }
     393                 : 
     394               0 : static void BW_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
     395                 :                               const uint8_t* SK_RESTRICT mask,
     396                 :                               const SkPMColor* SK_RESTRICT src, int count) {
     397               0 :     int i, octuple = (count + 7) >> 3;
     398               0 :     for (i = 0; i < octuple; ++i) {
     399               0 :         int m = *mask++;
     400               0 :         if (m & 0x80) { dst[0] = src[0]; }
     401               0 :         if (m & 0x40) { dst[1] = src[1]; }
     402               0 :         if (m & 0x20) { dst[2] = src[2]; }
     403               0 :         if (m & 0x10) { dst[3] = src[3]; }
     404               0 :         if (m & 0x08) { dst[4] = src[4]; }
     405               0 :         if (m & 0x04) { dst[5] = src[5]; }
     406               0 :         if (m & 0x02) { dst[6] = src[6]; }
     407               0 :         if (m & 0x01) { dst[7] = src[7]; }
     408               0 :         src += 8;
     409               0 :         dst += 8;
     410                 :     }
     411               0 :     count &= 7;
     412               0 :     if (count > 0) {
     413               0 :         int m = *mask;
     414               0 :         do {
     415               0 :             if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
     416               0 :             m <<= 1;
     417               0 :             src += 1;
     418               0 :             dst += 1;
     419                 :         } while (--count > 0);
     420                 :     }
     421               0 : }
     422                 : 
     423               0 : static void A8_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
     424                 :                              const uint8_t* SK_RESTRICT mask,
     425                 :                              const SkPMColor* SK_RESTRICT src, int count) {
     426               0 :     for (int i = 0; i < count; ++i) {
     427               0 :         if (mask[i]) {
     428               0 :             dst[i] = SkBlendARGB32(src[i], dst[i], mask[i]);
     429                 :         }
     430                 :     }
     431               0 : }
     432                 : 
     433                 : // expand the steps that SkAlphaMulQ performs, but this way we can
     434                 : //  exand.. add.. combine
     435                 : // instead of
     436                 : // expand..combine add expand..combine
     437                 : //
     438                 : #define EXPAND0(v, m, s)    ((v) & (m)) * (s)
     439                 : #define EXPAND1(v, m, s)    (((v) >> 8) & (m)) * (s)
     440                 : #define COMBINE(e0, e1, m)  ((((e0) >> 8) & (m)) | ((e1) & ~(m)))
     441                 : 
     442               0 : static void A8_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
     443                 :                               const uint8_t* SK_RESTRICT mask,
     444                 :                               const SkPMColor* SK_RESTRICT src, int count) {
     445               0 :     const uint32_t rbmask = gMask_00FF00FF;
     446               0 :     for (int i = 0; i < count; ++i) {
     447               0 :         int m = mask[i];
     448               0 :         if (m) {
     449               0 :             m += (m >> 7);
     450                 : #if 1
     451                 :             // this is slightly slower than the expand/combine version, but it
     452                 :             // is much closer to the old results, so we use it for now to reduce
     453                 :             // rebaselining.
     454               0 :             dst[i] = SkAlphaMulQ(src[i], m) + SkAlphaMulQ(dst[i], 256 - m);
     455                 : #else
     456                 :             uint32_t v = src[i];
     457                 :             uint32_t s0 = EXPAND0(v, rbmask, m);
     458                 :             uint32_t s1 = EXPAND1(v, rbmask, m);
     459                 :             v = dst[i];
     460                 :             uint32_t d0 = EXPAND0(v, rbmask, m);
     461                 :             uint32_t d1 = EXPAND1(v, rbmask, m);
     462                 :             dst[i] = COMBINE(s0 + d0, s1 + d1, rbmask);
     463                 : #endif
     464                 :         }
     465                 :     }
     466               0 : }
     467                 : 
     468               0 : static int upscale31To255(int value) {
     469               0 :     value = (value << 3) | (value >> 2);
     470               0 :     return value;
     471                 : }
     472                 : 
     473               0 : static int mul(int a, int b) {
     474               0 :     return a * b >> 8;
     475                 : }
     476                 : 
     477               0 : static int src_alpha_blend(int src, int dst, int srcA, int mask) {
     478                 :     
     479               0 :     return dst + mul(src - mul(srcA, dst), mask);
     480                 : }
     481                 : 
     482               0 : static void LCD16_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
     483                 :                                 const uint16_t* SK_RESTRICT mask,
     484                 :                                 const SkPMColor* SK_RESTRICT src, int count) {
     485               0 :     for (int i = 0; i < count; ++i) {
     486               0 :         uint16_t m = mask[i];
     487               0 :         if (0 == m) {
     488               0 :             continue;
     489                 :         }
     490                 :         
     491               0 :         SkPMColor s = src[i];
     492               0 :         SkPMColor d = dst[i];
     493                 : 
     494               0 :         int srcA = SkGetPackedA32(s);
     495               0 :         int srcR = SkGetPackedR32(s);
     496               0 :         int srcG = SkGetPackedG32(s);
     497               0 :         int srcB = SkGetPackedB32(s);
     498                 : 
     499               0 :         srcA += srcA >> 7;
     500                 : 
     501                 :         /*  We want all of these in 5bits, hence the shifts in case one of them
     502                 :          *  (green) is 6bits.
     503                 :          */
     504               0 :         int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5);
     505               0 :         int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5);
     506               0 :         int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5);
     507                 :         
     508               0 :         maskR = upscale31To255(maskR);
     509               0 :         maskG = upscale31To255(maskG);
     510               0 :         maskB = upscale31To255(maskB);
     511                 :         
     512               0 :         int dstR = SkGetPackedR32(d);
     513               0 :         int dstG = SkGetPackedG32(d);
     514               0 :         int dstB = SkGetPackedB32(d);
     515                 :         
     516                 :         // LCD blitting is only supported if the dst is known/required
     517                 :         // to be opaque
     518               0 :         dst[i] = SkPackARGB32(0xFF,
     519               0 :                               src_alpha_blend(srcR, dstR, srcA, maskR),
     520               0 :                               src_alpha_blend(srcG, dstG, srcA, maskG),
     521               0 :                               src_alpha_blend(srcB, dstB, srcA, maskB));
     522                 :     }
     523               0 : }
     524                 : 
     525               0 : static void LCD16_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
     526                 :                                  const uint16_t* SK_RESTRICT mask,
     527                 :                                  const SkPMColor* SK_RESTRICT src, int count) {
     528               0 :     for (int i = 0; i < count; ++i) {
     529               0 :         uint16_t m = mask[i];
     530               0 :         if (0 == m) {
     531               0 :             continue;
     532                 :         }
     533                 :         
     534               0 :         SkPMColor s = src[i];
     535               0 :         SkPMColor d = dst[i];
     536                 :         
     537               0 :         int srcR = SkGetPackedR32(s);
     538               0 :         int srcG = SkGetPackedG32(s);
     539               0 :         int srcB = SkGetPackedB32(s);
     540                 : 
     541                 :         /*  We want all of these in 5bits, hence the shifts in case one of them
     542                 :          *  (green) is 6bits.
     543                 :          */
     544               0 :         int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5);
     545               0 :         int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5);
     546               0 :         int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5);
     547                 :         
     548                 :         // Now upscale them to 0..32, so we can use blend32
     549               0 :         maskR = upscale31To32(maskR);
     550               0 :         maskG = upscale31To32(maskG);
     551               0 :         maskB = upscale31To32(maskB);
     552                 :         
     553               0 :         int dstR = SkGetPackedR32(d);
     554               0 :         int dstG = SkGetPackedG32(d);
     555               0 :         int dstB = SkGetPackedB32(d);
     556                 :         
     557                 :         // LCD blitting is only supported if the dst is known/required
     558                 :         // to be opaque
     559               0 :         dst[i] = SkPackARGB32(0xFF,
     560               0 :                               blend32(srcR, dstR, maskR),
     561               0 :                               blend32(srcG, dstG, maskG),
     562               0 :                               blend32(srcB, dstB, maskB));
     563                 :     }
     564               0 : }
     565                 : 
     566               0 : static void LCD32_RowProc_Blend(SkPMColor* SK_RESTRICT dst,
     567                 :                                 const SkPMColor* SK_RESTRICT mask,
     568                 :                                 const SkPMColor* SK_RESTRICT src, int count) {
     569               0 :     for (int i = 0; i < count; ++i) {
     570               0 :         SkPMColor m = mask[i];
     571               0 :         if (0 == m) {
     572               0 :             continue;
     573                 :         }
     574                 : 
     575               0 :         SkPMColor s = src[i];
     576               0 :         int srcA = SkGetPackedA32(s);
     577               0 :         int srcR = SkGetPackedR32(s);
     578               0 :         int srcG = SkGetPackedG32(s);
     579               0 :         int srcB = SkGetPackedB32(s);
     580                 :         
     581               0 :         srcA = SkAlpha255To256(srcA);
     582                 :         
     583               0 :         SkPMColor d = dst[i];
     584                 :         
     585               0 :         int maskR = SkGetPackedR32(m);
     586               0 :         int maskG = SkGetPackedG32(m);
     587               0 :         int maskB = SkGetPackedB32(m);
     588                 : 
     589                 :         // Now upscale them to 0..256
     590               0 :         maskR = SkAlpha255To256(maskR);
     591               0 :         maskG = SkAlpha255To256(maskG);
     592               0 :         maskB = SkAlpha255To256(maskB);
     593                 : 
     594               0 :         int dstR = SkGetPackedR32(d);
     595               0 :         int dstG = SkGetPackedG32(d);
     596               0 :         int dstB = SkGetPackedB32(d);
     597                 :         
     598                 :         // LCD blitting is only supported if the dst is known/required
     599                 :         // to be opaque
     600               0 :         dst[i] = SkPackARGB32(0xFF,
     601               0 :                               src_alpha_blend(srcR, dstR, srcA, maskR),
     602               0 :                               src_alpha_blend(srcG, dstG, srcA, maskG),
     603               0 :                               src_alpha_blend(srcB, dstB, srcA, maskB));
     604                 :     }
     605               0 : }
     606                 : 
     607               0 : static void LCD32_RowProc_Opaque(SkPMColor* SK_RESTRICT dst,
     608                 :                                  const SkPMColor* SK_RESTRICT mask,
     609                 :                                  const SkPMColor* SK_RESTRICT src, int count) {
     610               0 :     for (int i = 0; i < count; ++i) {
     611               0 :         SkPMColor m = mask[i];
     612               0 :         if (0 == m) {
     613               0 :             continue;
     614                 :         }
     615                 :         
     616               0 :         SkPMColor s = src[i];
     617               0 :         SkPMColor d = dst[i];
     618                 : 
     619               0 :         int maskR = SkGetPackedR32(m);
     620               0 :         int maskG = SkGetPackedG32(m);
     621               0 :         int maskB = SkGetPackedB32(m);
     622                 : 
     623               0 :         int srcR = SkGetPackedR32(s);
     624               0 :         int srcG = SkGetPackedG32(s);
     625               0 :         int srcB = SkGetPackedB32(s);
     626                 : 
     627               0 :         int dstR = SkGetPackedR32(d);
     628               0 :         int dstG = SkGetPackedG32(d);
     629               0 :         int dstB = SkGetPackedB32(d);
     630                 :         
     631                 :         // Now upscale them to 0..256, so we can use SkAlphaBlend
     632               0 :         maskR = SkAlpha255To256(maskR);
     633               0 :         maskG = SkAlpha255To256(maskG);
     634               0 :         maskB = SkAlpha255To256(maskB);
     635                 : 
     636                 :         // LCD blitting is only supported if the dst is known/required
     637                 :         // to be opaque
     638               0 :         dst[i] = SkPackARGB32(0xFF,
     639               0 :                               SkAlphaBlend(srcR, dstR, maskR),
     640               0 :                               SkAlphaBlend(srcG, dstG, maskG),
     641               0 :                               SkAlphaBlend(srcB, dstB, maskB));
     642                 :     }
     643               0 : }
     644                 : 
     645               0 : SkBlitMask::RowProc SkBlitMask::RowFactory(SkBitmap::Config config,
     646                 :                                            SkMask::Format format,
     647                 :                                            RowFlags flags) {
     648                 : // make this opt-in until chrome can rebaseline
     649               0 :     RowProc proc = PlatformRowProcs(config, format, flags);
     650               0 :     if (proc) {
     651               0 :         return proc;
     652                 :     }
     653                 : 
     654                 :     static const RowProc gProcs[] = {
     655                 :         // need X coordinate to handle BW
     656                 :         NULL, NULL, //(RowProc)BW_RowProc_Blend,      (RowProc)BW_RowProc_Opaque,
     657                 :         (RowProc)A8_RowProc_Blend,      (RowProc)A8_RowProc_Opaque,
     658                 :         (RowProc)LCD16_RowProc_Blend,   (RowProc)LCD16_RowProc_Opaque,
     659                 :         (RowProc)LCD32_RowProc_Blend,   (RowProc)LCD32_RowProc_Opaque,
     660                 :     };
     661                 : 
     662                 :     int index;
     663               0 :     switch (config) {
     664                 :         case SkBitmap::kARGB_8888_Config:
     665               0 :             switch (format) {
     666               0 :                 case SkMask::kBW_Format:    index = 0; break;
     667               0 :                 case SkMask::kA8_Format:    index = 2; break;
     668               0 :                 case SkMask::kLCD16_Format: index = 4; break;
     669               0 :                 case SkMask::kLCD32_Format: index = 6; break;
     670                 :                 default:
     671               0 :                     return NULL;
     672                 :             }
     673               0 :             if (flags & kSrcIsOpaque_RowFlag) {
     674               0 :                 index |= 1;
     675                 :             }
     676               0 :             SkASSERT((size_t)index < SK_ARRAY_COUNT(gProcs));
     677               0 :             return gProcs[index];
     678                 :         default:
     679                 :             break;
     680                 :     }
     681               0 :     return NULL;
     682                 : }
     683                 : 

Generated by: LCOV version 1.7