LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkBlitMask_D32.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 49 170 28.8 %
Date: 2017-07-14 16:53:18 Functions: 5 12 41.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2014 Google Inc.
       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 "SkBlitMask.h"
       9             : #include "SkColor.h"
      10             : #include "SkColorPriv.h"
      11             : #include "SkOpts.h"
      12             : 
      13         419 : SkBlitMask::BlitLCD16RowProc SkBlitMask::BlitLCD16RowFactory(bool isOpaque) {
      14         419 :     BlitLCD16RowProc proc = PlatformBlitRowProcs16(isOpaque);
      15         419 :     if (proc) {
      16         419 :         return proc;
      17             :     }
      18             : 
      19           0 :     if (isOpaque) {
      20           0 :         return  SkBlitLCD16OpaqueRow;
      21             :     } else {
      22           0 :         return  SkBlitLCD16Row;
      23             :     }
      24             : }
      25             : 
      26         419 : static void D32_LCD16_Proc(void* SK_RESTRICT dst, size_t dstRB,
      27             :                            const void* SK_RESTRICT mask, size_t maskRB,
      28             :                            SkColor color, int width, int height) {
      29             : 
      30         419 :     SkPMColor*        dstRow = (SkPMColor*)dst;
      31         419 :     const uint16_t* srcRow = (const uint16_t*)mask;
      32             :     SkPMColor       opaqueDst;
      33             : 
      34         419 :     SkBlitMask::BlitLCD16RowProc proc = nullptr;
      35         419 :     bool isOpaque = (0xFF == SkColorGetA(color));
      36         419 :     proc = SkBlitMask::BlitLCD16RowFactory(isOpaque);
      37         419 :     SkASSERT(proc != nullptr);
      38             : 
      39         419 :     if (isOpaque) {
      40         315 :         opaqueDst = SkPreMultiplyColor(color);
      41             :     } else {
      42         104 :         opaqueDst = 0;  // ignored
      43             :     }
      44             : 
      45        5533 :     do {
      46        5533 :         proc(dstRow, srcRow, color, width, opaqueDst);
      47        5533 :         dstRow = (SkPMColor*)((char*)dstRow + dstRB);
      48        5533 :         srcRow = (const uint16_t*)((const char*)srcRow + maskRB);
      49             :     } while (--height != 0);
      50         419 : }
      51             : 
      52             : ///////////////////////////////////////////////////////////////////////////////
      53             : 
      54         453 : bool SkBlitMask::BlitColor(const SkPixmap& device, const SkMask& mask,
      55             :                            const SkIRect& clip, SkColor color) {
      56         453 :     int x = clip.fLeft, y = clip.fTop;
      57             : 
      58         453 :     if (device.colorType() == kN32_SkColorType && mask.fFormat == SkMask::kA8_Format) {
      59         102 :         SkOpts::blit_mask_d32_a8(device.writable_addr32(x,y), device.rowBytes(),
      60          68 :                                  (const SkAlpha*)mask.getAddr(x,y), mask.fRowBytes,
      61          68 :                                  color, clip.width(), clip.height());
      62          34 :         return true;
      63             :     }
      64             : 
      65         419 :     if (device.colorType() == kN32_SkColorType && mask.fFormat == SkMask::kLCD16_Format) {
      66             :         // TODO: Is this reachable code?  Seems like no.
      67        1257 :         D32_LCD16_Proc(device.writable_addr32(x,y), device.rowBytes(),
      68         838 :                        mask.getAddr(x,y), mask.fRowBytes,
      69         419 :                        color, clip.width(), clip.height());
      70         419 :         return true;
      71             :     }
      72             : 
      73           0 :     return false;
      74             : }
      75             : 
      76             : ///////////////////////////////////////////////////////////////////////////////
      77             : ///////////////////////////////////////////////////////////////////////////////
      78             : 
      79           0 : static void BW_RowProc_Blend(
      80             :         SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
      81           0 :     const uint8_t* SK_RESTRICT mask = static_cast<const uint8_t*>(maskIn);
      82           0 :     int i, octuple = (count + 7) >> 3;
      83           0 :     for (i = 0; i < octuple; ++i) {
      84           0 :         int m = *mask++;
      85           0 :         if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
      86           0 :         if (m & 0x40) { dst[1] = SkPMSrcOver(src[1], dst[1]); }
      87           0 :         if (m & 0x20) { dst[2] = SkPMSrcOver(src[2], dst[2]); }
      88           0 :         if (m & 0x10) { dst[3] = SkPMSrcOver(src[3], dst[3]); }
      89           0 :         if (m & 0x08) { dst[4] = SkPMSrcOver(src[4], dst[4]); }
      90           0 :         if (m & 0x04) { dst[5] = SkPMSrcOver(src[5], dst[5]); }
      91           0 :         if (m & 0x02) { dst[6] = SkPMSrcOver(src[6], dst[6]); }
      92           0 :         if (m & 0x01) { dst[7] = SkPMSrcOver(src[7], dst[7]); }
      93           0 :         src += 8;
      94           0 :         dst += 8;
      95             :     }
      96           0 :     count &= 7;
      97           0 :     if (count > 0) {
      98           0 :         int m = *mask;
      99           0 :         do {
     100           0 :             if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
     101           0 :             m <<= 1;
     102           0 :             src += 1;
     103           0 :             dst += 1;
     104             :         } while (--count > 0);
     105             :     }
     106           0 : }
     107             : 
     108           0 : static void BW_RowProc_Opaque(
     109             :         SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
     110           0 :     const uint8_t* SK_RESTRICT mask = static_cast<const uint8_t*>(maskIn);
     111           0 :     int i, octuple = (count + 7) >> 3;
     112           0 :     for (i = 0; i < octuple; ++i) {
     113           0 :         int m = *mask++;
     114           0 :         if (m & 0x80) { dst[0] = src[0]; }
     115           0 :         if (m & 0x40) { dst[1] = src[1]; }
     116           0 :         if (m & 0x20) { dst[2] = src[2]; }
     117           0 :         if (m & 0x10) { dst[3] = src[3]; }
     118           0 :         if (m & 0x08) { dst[4] = src[4]; }
     119           0 :         if (m & 0x04) { dst[5] = src[5]; }
     120           0 :         if (m & 0x02) { dst[6] = src[6]; }
     121           0 :         if (m & 0x01) { dst[7] = src[7]; }
     122           0 :         src += 8;
     123           0 :         dst += 8;
     124             :     }
     125           0 :     count &= 7;
     126           0 :     if (count > 0) {
     127           0 :         int m = *mask;
     128           0 :         do {
     129           0 :             if (m & 0x80) { dst[0] = SkPMSrcOver(src[0], dst[0]); }
     130           0 :             m <<= 1;
     131           0 :             src += 1;
     132           0 :             dst += 1;
     133             :         } while (--count > 0);
     134             :     }
     135           0 : }
     136             : 
     137           0 : static void A8_RowProc_Blend(
     138             :         SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
     139           0 :     const uint8_t* SK_RESTRICT mask = static_cast<const uint8_t*>(maskIn);
     140           0 :     for (int i = 0; i < count; ++i) {
     141           0 :         if (mask[i]) {
     142           0 :             dst[i] = SkBlendARGB32(src[i], dst[i], mask[i]);
     143             :         }
     144             :     }
     145           0 : }
     146             : 
     147          90 : static void A8_RowProc_Opaque(
     148             :         SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
     149          90 :     const uint8_t* SK_RESTRICT mask = static_cast<const uint8_t*>(maskIn);
     150       23190 :     for (int i = 0; i < count; ++i) {
     151       23100 :         int m = mask[i];
     152       23100 :         if (m) {
     153       22330 :             m += (m >> 7);
     154       22330 :             dst[i] = SkPMLerp(src[i], dst[i], m);
     155             :         }
     156             :     }
     157          90 : }
     158             : 
     159           0 : static int upscale31To255(int value) {
     160           0 :     value = (value << 3) | (value >> 2);
     161           0 :     return value;
     162             : }
     163             : 
     164           0 : static int src_alpha_blend(int src, int dst, int srcA, int mask) {
     165             : 
     166           0 :     return dst + SkAlphaMul(src - SkAlphaMul(srcA, dst), mask);
     167             : }
     168             : 
     169           0 : static void LCD16_RowProc_Blend(
     170             :         SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
     171           0 :     const uint16_t* SK_RESTRICT mask = static_cast<const uint16_t*>(maskIn);
     172           0 :     for (int i = 0; i < count; ++i) {
     173           0 :         uint16_t m = mask[i];
     174           0 :         if (0 == m) {
     175           0 :             continue;
     176             :         }
     177             : 
     178           0 :         SkPMColor s = src[i];
     179           0 :         SkPMColor d = dst[i];
     180             : 
     181           0 :         int srcA = SkGetPackedA32(s);
     182           0 :         int srcR = SkGetPackedR32(s);
     183           0 :         int srcG = SkGetPackedG32(s);
     184           0 :         int srcB = SkGetPackedB32(s);
     185             : 
     186           0 :         srcA += srcA >> 7;
     187             : 
     188             :         /*  We want all of these in 5bits, hence the shifts in case one of them
     189             :          *  (green) is 6bits.
     190             :          */
     191           0 :         int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5);
     192           0 :         int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5);
     193           0 :         int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5);
     194             : 
     195           0 :         maskR = upscale31To255(maskR);
     196           0 :         maskG = upscale31To255(maskG);
     197           0 :         maskB = upscale31To255(maskB);
     198             : 
     199           0 :         int dstR = SkGetPackedR32(d);
     200           0 :         int dstG = SkGetPackedG32(d);
     201           0 :         int dstB = SkGetPackedB32(d);
     202             : 
     203             :         // LCD blitting is only supported if the dst is known/required
     204             :         // to be opaque
     205           0 :         dst[i] = SkPackARGB32(0xFF,
     206           0 :                               src_alpha_blend(srcR, dstR, srcA, maskR),
     207           0 :                               src_alpha_blend(srcG, dstG, srcA, maskG),
     208           0 :                               src_alpha_blend(srcB, dstB, srcA, maskB));
     209             :     }
     210           0 : }
     211             : 
     212           0 : static void LCD16_RowProc_Opaque(
     213             :         SkPMColor* SK_RESTRICT dst, const void* maskIn, const SkPMColor* SK_RESTRICT src, int count) {
     214           0 :     const uint16_t* SK_RESTRICT mask = static_cast<const uint16_t*>(maskIn);
     215           0 :     for (int i = 0; i < count; ++i) {
     216           0 :         uint16_t m = mask[i];
     217           0 :         if (0 == m) {
     218           0 :             continue;
     219             :         }
     220             : 
     221           0 :         SkPMColor s = src[i];
     222           0 :         SkPMColor d = dst[i];
     223             : 
     224           0 :         int srcR = SkGetPackedR32(s);
     225           0 :         int srcG = SkGetPackedG32(s);
     226           0 :         int srcB = SkGetPackedB32(s);
     227             : 
     228             :         /*  We want all of these in 5bits, hence the shifts in case one of them
     229             :          *  (green) is 6bits.
     230             :          */
     231           0 :         int maskR = SkGetPackedR16(m) >> (SK_R16_BITS - 5);
     232           0 :         int maskG = SkGetPackedG16(m) >> (SK_G16_BITS - 5);
     233           0 :         int maskB = SkGetPackedB16(m) >> (SK_B16_BITS - 5);
     234             : 
     235             :         // Now upscale them to 0..32, so we can use blend32
     236           0 :         maskR = SkUpscale31To32(maskR);
     237           0 :         maskG = SkUpscale31To32(maskG);
     238           0 :         maskB = SkUpscale31To32(maskB);
     239             : 
     240           0 :         int dstR = SkGetPackedR32(d);
     241           0 :         int dstG = SkGetPackedG32(d);
     242           0 :         int dstB = SkGetPackedB32(d);
     243             : 
     244             :         // LCD blitting is only supported if the dst is known/required
     245             :         // to be opaque
     246           0 :         dst[i] = SkPackARGB32(0xFF,
     247           0 :                               SkBlend32(srcR, dstR, maskR),
     248           0 :                               SkBlend32(srcG, dstG, maskG),
     249           0 :                               SkBlend32(srcB, dstB, maskB));
     250             :     }
     251           0 : }
     252             : 
     253          61 : SkBlitMask::RowProc SkBlitMask::RowFactory(SkColorType ct,
     254             :                                            SkMask::Format format,
     255             :                                            RowFlags flags) {
     256             : // make this opt-in until chrome can rebaseline
     257          61 :     RowProc proc = PlatformRowProcs(ct, format, flags);
     258          61 :     if (proc) {
     259           0 :         return proc;
     260             :     }
     261             : 
     262             :     static const RowProc gProcs[] = {
     263             :         // need X coordinate to handle BW
     264             :         false ? (RowProc)BW_RowProc_Blend : nullptr, // suppress unused warning
     265             :         false ? (RowProc)BW_RowProc_Opaque : nullptr, // suppress unused warning
     266             :         (RowProc)A8_RowProc_Blend,      (RowProc)A8_RowProc_Opaque,
     267             :         (RowProc)LCD16_RowProc_Blend,   (RowProc)LCD16_RowProc_Opaque,
     268             :     };
     269             : 
     270             :     int index;
     271          61 :     switch (ct) {
     272             :         case kN32_SkColorType:
     273          61 :             switch (format) {
     274           0 :                 case SkMask::kBW_Format:    index = 0; break;
     275          61 :                 case SkMask::kA8_Format:    index = 2; break;
     276           0 :                 case SkMask::kLCD16_Format: index = 4; break;
     277             :                 default:
     278           0 :                     return nullptr;
     279             :             }
     280          61 :             if (flags & kSrcIsOpaque_RowFlag) {
     281          61 :                 index |= 1;
     282             :             }
     283          61 :             SkASSERT((size_t)index < SK_ARRAY_COUNT(gProcs));
     284          61 :             return gProcs[index];
     285             :         default:
     286           0 :             break;
     287             :     }
     288           0 :     return nullptr;
     289             : }

Generated by: LCOV version 1.13