LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkBlitter_Sprite.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 59 94 62.8 %
Date: 2017-07-14 16:53:18 Functions: 8 13 61.5 %
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 "SkArenaAlloc.h"
       9             : #include "SkOpts.h"
      10             : #include "SkSpriteBlitter.h"
      11             : 
      12         118 : SkSpriteBlitter::SkSpriteBlitter(const SkPixmap& source)
      13         118 :     : fSource(source) {}
      14             : 
      15         118 : void SkSpriteBlitter::setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) {
      16         118 :     fDst = dst;
      17         118 :     fLeft = left;
      18         118 :     fTop = top;
      19         118 :     fPaint = &paint;
      20         118 : }
      21             : 
      22           0 : void SkSpriteBlitter::blitH(int x, int y, int width) {
      23           0 :     SkDEBUGFAIL("how did we get here?");
      24             : 
      25             :     // Fallback to blitRect.
      26           0 :     this->blitRect(x, y, width, 1);
      27           0 : }
      28             : 
      29           0 : void SkSpriteBlitter::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) {
      30           0 :     SkDEBUGFAIL("how did we get here?");
      31             : 
      32             :     // No fallback strategy.
      33           0 : }
      34             : 
      35           0 : void SkSpriteBlitter::blitV(int x, int y, int height, SkAlpha alpha) {
      36           0 :     SkDEBUGFAIL("how did we get here?");
      37             : 
      38             :     // Fall back to superclass if the code gets here in release mode.
      39           0 :     INHERITED::blitV(x, y, height, alpha);
      40           0 : }
      41             : 
      42           0 : void SkSpriteBlitter::blitMask(const SkMask& mask, const SkIRect& clip) {
      43           0 :     SkDEBUGFAIL("how did we get here?");
      44             : 
      45             :     // Fall back to superclass if the code gets here in release mode.
      46           0 :     INHERITED::blitMask(mask, clip);
      47           0 : }
      48             : 
      49             : ///////////////////////////////////////////////////////////////////////////////
      50             : 
      51             : //  Only valid if...
      52             : //      1. src == dst format
      53             : //      2. paint has no modifiers (i.e. alpha, colorfilter, etc.)
      54             : //      3. xfermode needs no blending: e.g. kSrc_Mode or kSrcOver_Mode + opaque src
      55             : //
      56          17 : class SkSpriteBlitter_Src_SrcOver final : public SkSpriteBlitter {
      57             : public:
      58         135 :     static bool Supports(const SkPixmap& dst, const SkPixmap& src, const SkPaint& paint) {
      59         135 :         if (dst.colorType() != src.colorType()) {
      60           0 :             return false;
      61             :         }
      62         135 :         if (dst.info().gammaCloseToSRGB() != src.info().gammaCloseToSRGB()) {
      63           0 :             return false;
      64             :         }
      65         135 :         if (paint.getMaskFilter() || paint.getColorFilter() || paint.getImageFilter()) {
      66           0 :             return false;
      67             :         }
      68         135 :         if (0xFF != paint.getAlpha()) {
      69          11 :             return false;
      70             :         }
      71         124 :         SkBlendMode mode = paint.getBlendMode();
      72         124 :         if (SkBlendMode::kSrc == mode) {
      73          28 :             return true;
      74             :         }
      75          96 :         if (SkBlendMode::kSrcOver == mode && src.isOpaque()) {
      76           6 :             return true;
      77             :         }
      78             : 
      79             :         // At this point memcpy can't be used. The following check for using SrcOver.
      80             : 
      81          90 :         if (dst.colorType() != kN32_SkColorType || !dst.info().gammaCloseToSRGB()) {
      82          90 :             return false;
      83             :         }
      84             : 
      85           0 :         return SkBlendMode::kSrcOver == mode;
      86             :     }
      87             : 
      88          17 :     SkSpriteBlitter_Src_SrcOver(const SkPixmap& src)
      89          17 :         : INHERITED(src) {}
      90             : 
      91          17 :     void setup(const SkPixmap& dst, int left, int top, const SkPaint& paint) override {
      92          17 :         SkASSERT(Supports(dst, fSource, paint));
      93          17 :         this->INHERITED::setup(dst, left, top, paint);
      94          17 :         SkBlendMode mode = paint.getBlendMode();
      95             : 
      96          17 :         SkASSERT(mode == SkBlendMode::kSrcOver || mode == SkBlendMode::kSrc);
      97             : 
      98          17 :         if (mode == SkBlendMode::kSrcOver && !fSource.isOpaque()) {
      99           0 :             fUseMemcpy = false;
     100             :         }
     101          17 :     }
     102             : 
     103          17 :     void blitRect(int x, int y, int width, int height) override {
     104          17 :         SkASSERT(fDst.colorType() == fSource.colorType());
     105          17 :         SkASSERT(fDst.info().gammaCloseToSRGB() == fSource.info().gammaCloseToSRGB());
     106          17 :         SkASSERT(width > 0 && height > 0);
     107             : 
     108          17 :         if (fUseMemcpy) {
     109          17 :             char* dst = (char*)fDst.writable_addr(x, y);
     110          17 :             const char* src = (const char*)fSource.addr(x - fLeft, y - fTop);
     111          17 :             const size_t dstRB = fDst.rowBytes();
     112          17 :             const size_t srcRB = fSource.rowBytes();
     113          17 :             const size_t bytesToCopy = width << fSource.shiftPerPixel();
     114             : 
     115       10533 :             while (height --> 0) {
     116        5258 :                 memcpy(dst, src, bytesToCopy);
     117        5258 :                 dst += dstRB;
     118        5258 :                 src += srcRB;
     119             :             }
     120             :         } else {
     121           0 :             uint32_t* dst       = fDst.writable_addr32(x, y);
     122           0 :             const uint32_t* src = fSource.addr32(x - fLeft, y - fTop);
     123           0 :             const int dstStride = fDst.rowBytesAsPixels();
     124           0 :             const int srcStride = fSource.rowBytesAsPixels();
     125             : 
     126           0 :             while (height --> 0) {
     127           0 :                 SkOpts::srcover_srgb_srgb(dst, src, width, width);
     128           0 :                 dst += dstStride;
     129           0 :                 src += srcStride;
     130             :             }
     131             :         }
     132          17 :     }
     133             : 
     134             : private:
     135             :     typedef SkSpriteBlitter INHERITED;
     136             : 
     137             :     bool fUseMemcpy {true};
     138             : };
     139             : 
     140             : // returning null means the caller will call SkBlitter::Choose() and
     141             : // have wrapped the source bitmap inside a shader
     142         118 : SkBlitter* SkBlitter::ChooseSprite(const SkPixmap& dst, const SkPaint& paint,
     143             :         const SkPixmap& source, int left, int top, SkArenaAlloc* allocator) {
     144             :     /*  We currently ignore antialiasing and filtertype, meaning we will take our
     145             :         special blitters regardless of these settings. Ignoring filtertype seems fine
     146             :         since by definition there is no scale in the matrix. Ignoring antialiasing is
     147             :         a bit of a hack, since we "could" pass in the fractional left/top for the bitmap,
     148             :         and respect that by blending the edges of the bitmap against the device. To support
     149             :         this we could either add more special blitters here, or detect antialiasing in the
     150             :         paint and return null if it is set, forcing the client to take the slow shader case
     151             :         (which does respect soft edges).
     152             :     */
     153         118 :     SkASSERT(allocator != nullptr);
     154             : 
     155             :     // Defer to the general code if the pixels are unpremultipled. This case is not common,
     156             :     // and this simplifies the code.
     157         118 :     if (source.alphaType() == kUnpremul_SkAlphaType) {
     158           0 :         return nullptr;
     159             :     }
     160             : 
     161         118 :     SkSpriteBlitter* blitter = nullptr;
     162             : 
     163         118 :     if (SkSpriteBlitter_Src_SrcOver::Supports(dst, source, paint)) {
     164          17 :         blitter = allocator->make<SkSpriteBlitter_Src_SrcOver>(source);
     165             :     } else {
     166         101 :         switch (dst.colorType()) {
     167             :             case kRGB_565_SkColorType:
     168           0 :                 blitter = SkSpriteBlitter::ChooseD16(source, paint, allocator);
     169           0 :                 break;
     170             :             case kN32_SkColorType:
     171         101 :                 if (dst.info().gammaCloseToSRGB()) {
     172           0 :                     blitter = SkSpriteBlitter::ChooseS32(source, paint, allocator);
     173             :                 } else {
     174         101 :                     blitter = SkSpriteBlitter::ChooseL32(source, paint, allocator);
     175             :                 }
     176         101 :                 break;
     177             :             case kRGBA_F16_SkColorType:
     178           0 :                 blitter = SkSpriteBlitter::ChooseF16(source, paint, allocator);
     179           0 :                 break;
     180             :             default:
     181           0 :                 break;
     182             :         }
     183             :     }
     184             : 
     185         118 :     if (blitter) {
     186         118 :         blitter->setup(dst, left, top, paint);
     187             :     }
     188         118 :     return blitter;
     189             : }

Generated by: LCOV version 1.13