LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkSpriteBlitter_ARGB32.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 36 161 22.4 %
Date: 2017-07-14 16:53:18 Functions: 4 28 14.3 %
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 "SkSpriteBlitter.h"
       9             : #include "SkArenaAlloc.h"
      10             : #include "SkBlitRow.h"
      11             : #include "SkColorFilter.h"
      12             : #include "SkColorPriv.h"
      13             : #include "SkTemplates.h"
      14             : #include "SkUtils.h"
      15             : #include "SkXfermodePriv.h"
      16             : 
      17             : ///////////////////////////////////////////////////////////////////////////////
      18             : 
      19         101 : class Sprite_D32_S32 : public SkSpriteBlitter {
      20             : public:
      21         101 :     Sprite_D32_S32(const SkPixmap& src, U8CPU alpha)  : INHERITED(src) {
      22         101 :         SkASSERT(src.colorType() == kN32_SkColorType);
      23             : 
      24         101 :         unsigned flags32 = 0;
      25         101 :         if (255 != alpha) {
      26          11 :             flags32 |= SkBlitRow::kGlobalAlpha_Flag32;
      27             :         }
      28         101 :         if (!src.isOpaque()) {
      29         101 :             flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32;
      30             :         }
      31             : 
      32         101 :         fProc32 = SkBlitRow::Factory32(flags32);
      33         101 :         fAlpha = alpha;
      34         101 :     }
      35             : 
      36         103 :     void blitRect(int x, int y, int width, int height) override {
      37         103 :         SkASSERT(width > 0 && height > 0);
      38         103 :         uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y);
      39         103 :         const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop);
      40         103 :         size_t dstRB = fDst.rowBytes();
      41         103 :         size_t srcRB = fSource.rowBytes();
      42         103 :         SkBlitRow::Proc32 proc = fProc32;
      43         103 :         U8CPU             alpha = fAlpha;
      44             : 
      45        3916 :         do {
      46        3916 :             proc(dst, src, width, alpha);
      47        3916 :             dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
      48        3916 :             src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
      49             :         } while (--height != 0);
      50         103 :     }
      51             : 
      52             : private:
      53             :     SkBlitRow::Proc32   fProc32;
      54             :     U8CPU               fAlpha;
      55             : 
      56             :     typedef SkSpriteBlitter INHERITED;
      57             : };
      58             : 
      59             : ///////////////////////////////////////////////////////////////////////////////
      60             : 
      61             : class Sprite_D32_XferFilter : public SkSpriteBlitter {
      62             : public:
      63           0 :     Sprite_D32_XferFilter(const SkPixmap& source, const SkPaint& paint) : SkSpriteBlitter(source) {
      64           0 :         fColorFilter = paint.getColorFilter();
      65           0 :         SkSafeRef(fColorFilter);
      66             : 
      67           0 :         fXfermode = SkXfermode::Peek(paint.getBlendMode());
      68             : 
      69           0 :         fBufferSize = 0;
      70           0 :         fBuffer = nullptr;
      71             : 
      72           0 :         unsigned flags32 = 0;
      73           0 :         if (255 != paint.getAlpha()) {
      74           0 :             flags32 |= SkBlitRow::kGlobalAlpha_Flag32;
      75             :         }
      76           0 :         if (!source.isOpaque()) {
      77           0 :             flags32 |= SkBlitRow::kSrcPixelAlpha_Flag32;
      78             :         }
      79             : 
      80           0 :         fProc32 = SkBlitRow::Factory32(flags32);
      81           0 :         fAlpha = paint.getAlpha();
      82           0 :     }
      83             : 
      84           0 :     ~Sprite_D32_XferFilter() override {
      85           0 :         delete[] fBuffer;
      86           0 :         SkSafeUnref(fColorFilter);
      87           0 :     }
      88             : 
      89           0 :     void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override {
      90           0 :         this->INHERITED::setup(dst, left, top, paint);
      91             : 
      92           0 :         int width = dst.width();
      93           0 :         if (width > fBufferSize) {
      94           0 :             fBufferSize = width;
      95           0 :             delete[] fBuffer;
      96           0 :             fBuffer = new SkPMColor[width];
      97             :         }
      98           0 :     }
      99             : 
     100             : protected:
     101             :     SkColorFilter*      fColorFilter;
     102             :     SkXfermode*         fXfermode;
     103             :     int                 fBufferSize;
     104             :     SkPMColor*          fBuffer;
     105             :     SkBlitRow::Proc32   fProc32;
     106             :     U8CPU               fAlpha;
     107             : 
     108             : private:
     109             :     typedef SkSpriteBlitter INHERITED;
     110             : };
     111             : 
     112             : ///////////////////////////////////////////////////////////////////////////////
     113             : 
     114           0 : class Sprite_D32_S32A_XferFilter : public Sprite_D32_XferFilter {
     115             : public:
     116           0 :     Sprite_D32_S32A_XferFilter(const SkPixmap& source, const SkPaint& paint)
     117           0 :         : Sprite_D32_XferFilter(source, paint) {}
     118             : 
     119           0 :     void blitRect(int x, int y, int width, int height) override {
     120           0 :         SkASSERT(width > 0 && height > 0);
     121           0 :         uint32_t* SK_RESTRICT dst = fDst.writable_addr32(x, y);
     122           0 :         const uint32_t* SK_RESTRICT src = fSource.addr32(x - fLeft, y - fTop);
     123           0 :         size_t dstRB = fDst.rowBytes();
     124           0 :         size_t srcRB = fSource.rowBytes();
     125           0 :         SkColorFilter* colorFilter = fColorFilter;
     126           0 :         SkXfermode* xfermode = fXfermode;
     127             : 
     128           0 :         do {
     129           0 :             const SkPMColor* tmp = src;
     130             : 
     131           0 :             if (colorFilter) {
     132           0 :                 colorFilter->filterSpan(src, width, fBuffer);
     133           0 :                 tmp = fBuffer;
     134             :             }
     135             : 
     136           0 :             if (xfermode) {
     137           0 :                 xfermode->xfer32(dst, tmp, width, nullptr);
     138             :             } else {
     139           0 :                 fProc32(dst, tmp, width, fAlpha);
     140             :             }
     141             : 
     142           0 :             dst = (uint32_t* SK_RESTRICT)((char*)dst + dstRB);
     143           0 :             src = (const uint32_t* SK_RESTRICT)((const char*)src + srcRB);
     144             :         } while (--height != 0);
     145           0 :     }
     146             : 
     147             : private:
     148             :     typedef Sprite_D32_XferFilter INHERITED;
     149             : };
     150             : 
     151           0 : static void fillbuffer(SkPMColor* SK_RESTRICT dst,
     152             :                        const SkPMColor16* SK_RESTRICT src, int count) {
     153           0 :     SkASSERT(count > 0);
     154             : 
     155           0 :     do {
     156           0 :         *dst++ = SkPixel4444ToPixel32(*src++);
     157             :     } while (--count != 0);
     158           0 : }
     159             : 
     160           0 : class Sprite_D32_S4444_XferFilter : public Sprite_D32_XferFilter {
     161             : public:
     162           0 :     Sprite_D32_S4444_XferFilter(const SkPixmap& source, const SkPaint& paint)
     163           0 :         : Sprite_D32_XferFilter(source, paint) {}
     164             : 
     165           0 :     void blitRect(int x, int y, int width, int height) override {
     166           0 :         SkASSERT(width > 0 && height > 0);
     167           0 :         SkPMColor* SK_RESTRICT dst = fDst.writable_addr32(x, y);
     168           0 :         const SkPMColor16* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop);
     169           0 :         size_t dstRB = fDst.rowBytes();
     170           0 :         size_t srcRB = fSource.rowBytes();
     171           0 :         SkPMColor* SK_RESTRICT buffer = fBuffer;
     172           0 :         SkColorFilter* colorFilter = fColorFilter;
     173           0 :         SkXfermode* xfermode = fXfermode;
     174             : 
     175           0 :         do {
     176           0 :             fillbuffer(buffer, src, width);
     177             : 
     178           0 :             if (colorFilter) {
     179           0 :                 colorFilter->filterSpan(buffer, width, buffer);
     180             :             }
     181           0 :             if (xfermode) {
     182           0 :                 xfermode->xfer32(dst, buffer, width, nullptr);
     183             :             } else {
     184           0 :                 fProc32(dst, buffer, width, fAlpha);
     185             :             }
     186             : 
     187           0 :             dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
     188           0 :             src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
     189             :         } while (--height != 0);
     190           0 :     }
     191             : 
     192             : private:
     193             :     typedef Sprite_D32_XferFilter INHERITED;
     194             : };
     195             : 
     196             : ///////////////////////////////////////////////////////////////////////////////
     197             : 
     198           0 : static void src_row(SkPMColor* SK_RESTRICT dst,
     199             :                     const SkPMColor16* SK_RESTRICT src, int count) {
     200           0 :     do {
     201           0 :         *dst = SkPixel4444ToPixel32(*src);
     202           0 :         src += 1;
     203           0 :         dst += 1;
     204             :     } while (--count != 0);
     205           0 : }
     206             : 
     207           0 : class Sprite_D32_S4444_Opaque : public SkSpriteBlitter {
     208             : public:
     209           0 :     Sprite_D32_S4444_Opaque(const SkPixmap& source) : SkSpriteBlitter(source) {}
     210             : 
     211           0 :     void blitRect(int x, int y, int width, int height) override {
     212           0 :         SkASSERT(width > 0 && height > 0);
     213           0 :         SkPMColor* SK_RESTRICT dst = fDst.writable_addr32(x, y);
     214           0 :         const SkPMColor16* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop);
     215           0 :         size_t dstRB = fDst.rowBytes();
     216           0 :         size_t srcRB = fSource.rowBytes();
     217             : 
     218           0 :         do {
     219           0 :             src_row(dst, src, width);
     220           0 :             dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
     221           0 :             src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
     222             :         } while (--height != 0);
     223           0 :     }
     224             : };
     225             : 
     226           0 : static void srcover_row(SkPMColor* SK_RESTRICT dst,
     227             :                         const SkPMColor16* SK_RESTRICT src, int count) {
     228           0 :     do {
     229           0 :         *dst = SkPMSrcOver(SkPixel4444ToPixel32(*src), *dst);
     230           0 :         src += 1;
     231           0 :         dst += 1;
     232             :     } while (--count != 0);
     233           0 : }
     234             : 
     235           0 : class Sprite_D32_S4444 : public SkSpriteBlitter {
     236             : public:
     237           0 :     Sprite_D32_S4444(const SkPixmap& source) : SkSpriteBlitter(source) {}
     238             : 
     239           0 :     void blitRect(int x, int y, int width, int height) override {
     240           0 :         SkASSERT(width > 0 && height > 0);
     241           0 :         SkPMColor* SK_RESTRICT dst = fDst.writable_addr32(x, y);
     242           0 :         const SkPMColor16* SK_RESTRICT src = fSource.addr16(x - fLeft, y - fTop);
     243           0 :         size_t dstRB = fDst.rowBytes();
     244           0 :         size_t srcRB = fSource.rowBytes();
     245             : 
     246           0 :         do {
     247           0 :             srcover_row(dst, src, width);
     248           0 :             dst = (SkPMColor* SK_RESTRICT)((char*)dst + dstRB);
     249           0 :             src = (const SkPMColor16* SK_RESTRICT)((const char*)src + srcRB);
     250             :         } while (--height != 0);
     251           0 :     }
     252             : };
     253             : 
     254             : ///////////////////////////////////////////////////////////////////////////////
     255             : 
     256         101 : SkSpriteBlitter* SkSpriteBlitter::ChooseL32(const SkPixmap& source, const SkPaint& paint,
     257             :                                             SkArenaAlloc* allocator) {
     258         101 :     SkASSERT(allocator != nullptr);
     259             : 
     260         101 :     if (paint.getMaskFilter() != nullptr) {
     261           0 :         return nullptr;
     262             :     }
     263             : 
     264         101 :     U8CPU       alpha = paint.getAlpha();
     265         101 :     bool isSrcOver = paint.isSrcOver();
     266         101 :     SkColorFilter* filter = paint.getColorFilter();
     267         101 :     SkSpriteBlitter* blitter = nullptr;
     268             : 
     269         101 :     switch (source.colorType()) {
     270             :         case kARGB_4444_SkColorType:
     271           0 :             if (alpha != 0xFF) {
     272           0 :                 return nullptr;    // we only have opaque sprites
     273             :             }
     274           0 :             if (!isSrcOver || filter) {
     275           0 :                 blitter = allocator->make<Sprite_D32_S4444_XferFilter>(source, paint);
     276           0 :             } else if (source.isOpaque()) {
     277           0 :                 blitter = allocator->make<Sprite_D32_S4444_Opaque>(source);
     278             :             } else {
     279           0 :                 blitter = allocator->make<Sprite_D32_S4444>(source);
     280             :             }
     281           0 :             break;
     282             :         case kN32_SkColorType:
     283         101 :             if (!isSrcOver || filter) {
     284           0 :                 if (255 == alpha) {
     285             :                     // this can handle xfermode or filter, but not alpha
     286           0 :                     blitter = allocator->make<Sprite_D32_S32A_XferFilter>(source, paint);
     287             :                 }
     288             :             } else {
     289             :                 // this can handle alpha, but not xfermode or filter
     290         101 :                 blitter = allocator->make<Sprite_D32_S32>(source, alpha);
     291             :             }
     292         101 :             break;
     293             :         default:
     294           0 :             break;
     295             :     }
     296         101 :     return blitter;
     297             : }

Generated by: LCOV version 1.13