LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkBlitter.h (source / functions) Hit Total Coverage
Test: output.info Lines: 34 55 61.8 %
Date: 2017-07-14 16:53:18 Functions: 16 28 57.1 %
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             : #ifndef SkBlitter_DEFINED
       9             : #define SkBlitter_DEFINED
      10             : 
      11             : #include "SkAutoMalloc.h"
      12             : #include "SkBitmapProcShader.h"
      13             : #include "SkColor.h"
      14             : #include "SkRect.h"
      15             : #include "SkRegion.h"
      16             : #include "SkShader.h"
      17             : 
      18             : class SkArenaAlloc;
      19             : class SkMatrix;
      20             : class SkPaint;
      21             : class SkPixmap;
      22             : struct SkMask;
      23             : 
      24             : /** SkBlitter and its subclasses are responsible for actually writing pixels
      25             :     into memory. Besides efficiency, they handle clipping and antialiasing.
      26             :     A SkBlitter subclass contains all the context needed to generate pixels
      27             :     for the destination and how src/generated pixels map to the destination.
      28             :     The coordinates passed to the blitX calls are in destination pixel space.
      29             : */
      30        2033 : class SkBlitter {
      31             : public:
      32             :     virtual ~SkBlitter();
      33             : 
      34             :     /// Blit a horizontal run of one or more pixels.
      35             :     virtual void blitH(int x, int y, int width) = 0;
      36             : 
      37             :     /// Blit a horizontal run of antialiased pixels; runs[] is a *sparse*
      38             :     /// zero-terminated run-length encoding of spans of constant alpha values.
      39             :     /// The runs[] and antialias[] work together to represent long runs of pixels with the same
      40             :     /// alphas. The runs[] contains the number of pixels with the same alpha, and antialias[]
      41             :     /// contain the coverage value for that number of pixels. The runs[] (and antialias[]) are
      42             :     /// encoded in a clever way. The runs array is zero terminated, and has enough entries for
      43             :     /// each pixel plus one, in most cases some of the entries will not contain valid data. An entry
      44             :     /// in the runs array contains the number of pixels (np) that have the same alpha value. The
      45             :     /// next np value is found np entries away. For example, if runs[0] = 7, then the next valid
      46             :     /// entry will by at runs[7]. The runs array and antialias[] are coupled by index. So, if the
      47             :     /// np entry is at runs[45] = 12 then the alpha value can be found at antialias[45] = 0x88.
      48             :     /// This would mean to use an alpha value of 0x88 for the next 12 pixels starting at pixel 45.
      49             :     virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) = 0;
      50             : 
      51             :     /// Blit a vertical run of pixels with a constant alpha value.
      52             :     virtual void blitV(int x, int y, int height, SkAlpha alpha);
      53             : 
      54             :     /// Blit a solid rectangle one or more pixels wide.
      55             :     virtual void blitRect(int x, int y, int width, int height);
      56             : 
      57             :     /** Blit a rectangle with one alpha-blended column on the left,
      58             :         width (zero or more) opaque pixels, and one alpha-blended column
      59             :         on the right.
      60             :         The result will always be at least two pixels wide.
      61             :     */
      62             :     virtual void blitAntiRect(int x, int y, int width, int height,
      63             :                               SkAlpha leftAlpha, SkAlpha rightAlpha);
      64             : 
      65             :     /// Blit a pattern of pixels defined by a rectangle-clipped mask;
      66             :     /// typically used for text.
      67             :     virtual void blitMask(const SkMask&, const SkIRect& clip);
      68             : 
      69             :     /** If the blitter just sets a single value for each pixel, return the
      70             :         bitmap it draws into, and assign value. If not, return nullptr and ignore
      71             :         the value parameter.
      72             :     */
      73             :     virtual const SkPixmap* justAnOpaqueColor(uint32_t* value);
      74             : 
      75             :     // (x, y), (x + 1, y)
      76         294 :     virtual void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) {
      77             :         int16_t runs[3];
      78             :         uint8_t aa[2];
      79             : 
      80         294 :         runs[0] = 1;
      81         294 :         runs[1] = 1;
      82         294 :         runs[2] = 0;
      83         294 :         aa[0] = SkToU8(a0);
      84         294 :         aa[1] = SkToU8(a1);
      85         294 :         this->blitAntiH(x, y, aa, runs);
      86         294 :     }
      87             : 
      88             :     // (x, y), (x, y + 1)
      89           0 :     virtual void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) {
      90             :         int16_t runs[2];
      91             :         uint8_t aa[1];
      92             : 
      93           0 :         runs[0] = 1;
      94           0 :         runs[1] = 0;
      95           0 :         aa[0] = SkToU8(a0);
      96           0 :         this->blitAntiH(x, y, aa, runs);
      97             :         // reset in case the clipping blitter modified runs
      98           0 :         runs[0] = 1;
      99           0 :         runs[1] = 0;
     100           0 :         aa[0] = SkToU8(a1);
     101           0 :         this->blitAntiH(x, y + 1, aa, runs);
     102           0 :     }
     103             : 
     104             :     /**
     105             :      *  Special method just to identify the null blitter, which is returned
     106             :      *  from Choose() if the request cannot be fulfilled. Default impl
     107             :      *  returns false.
     108             :      */
     109             :     virtual bool isNullBlitter() const;
     110             : 
     111             :     /**
     112             :      * Special methods for blitters that can blit more than one row at a time.
     113             :      * This function returns the number of rows that this blitter could optimally
     114             :      * process at a time. It is still required to support blitting one scanline
     115             :      * at a time.
     116             :      */
     117         190 :     virtual int requestRowsPreserved() const { return 1; }
     118             : 
     119             :     /**
     120             :      * This function allocates memory for the blitter that the blitter then owns.
     121             :      * The memory can be used by the calling function at will, but it will be
     122             :      * released when the blitter's destructor is called. This function returns
     123             :      * nullptr if no persistent memory is needed by the blitter.
     124             :      */
     125         190 :     virtual void* allocBlitMemory(size_t sz) {
     126         190 :         return fBlitMemory.reset(sz, SkAutoMalloc::kReuse_OnShrink);
     127             :     }
     128             : 
     129             :     ///@name non-virtual helpers
     130             :     void blitMaskRegion(const SkMask& mask, const SkRegion& clip);
     131             :     void blitRectRegion(const SkIRect& rect, const SkRegion& clip);
     132             :     void blitRegion(const SkRegion& clip);
     133             :     ///@}
     134             : 
     135             :     /** @name Factories
     136             :         Return the correct blitter to use given the specified context.
     137             :      */
     138             :     static SkBlitter* Choose(const SkPixmap& dst,
     139             :                              const SkMatrix& matrix,
     140             :                              const SkPaint& paint,
     141             :                              SkArenaAlloc*,
     142             :                              bool drawCoverage = false);
     143             : 
     144             :     static SkBlitter* ChooseSprite(const SkPixmap& dst,
     145             :                                    const SkPaint&,
     146             :                                    const SkPixmap& src,
     147             :                                    int left, int top,
     148             :                                    SkArenaAlloc*);
     149             :     ///@}
     150             : 
     151             :     static SkShader::ContextRec::DstType PreferredShaderDest(const SkImageInfo&);
     152             : 
     153             : protected:
     154             :     SkAutoMalloc fBlitMemory;
     155             : };
     156             : 
     157             : /** This blitter silently never draws anything.
     158             : */
     159           0 : class SkNullBlitter : public SkBlitter {
     160             : public:
     161             :     void blitH(int x, int y, int width) override;
     162             :     void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
     163             :     void blitV(int x, int y, int height, SkAlpha alpha) override;
     164             :     void blitRect(int x, int y, int width, int height) override;
     165             :     void blitMask(const SkMask&, const SkIRect& clip) override;
     166             :     const SkPixmap* justAnOpaqueColor(uint32_t* value) override;
     167             :     bool isNullBlitter() const override;
     168             : };
     169             : 
     170             : /** Wraps another (real) blitter, and ensures that the real blitter is only
     171             :     called with coordinates that have been clipped by the specified clipRect.
     172             :     This means the caller need not perform the clipping ahead of time.
     173             : */
     174         452 : class SkRectClipBlitter : public SkBlitter {
     175             : public:
     176          26 :     void init(SkBlitter* blitter, const SkIRect& clipRect) {
     177          26 :         SkASSERT(!clipRect.isEmpty());
     178          26 :         fBlitter = blitter;
     179          26 :         fClipRect = clipRect;
     180          26 :     }
     181             : 
     182             :     void blitH(int x, int y, int width) override;
     183             :     void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
     184             :     void blitV(int x, int y, int height, SkAlpha alpha) override;
     185             :     void blitRect(int x, int y, int width, int height) override;
     186             :     virtual void blitAntiRect(int x, int y, int width, int height,
     187             :                      SkAlpha leftAlpha, SkAlpha rightAlpha) override;
     188             :     void blitMask(const SkMask&, const SkIRect& clip) override;
     189             :     const SkPixmap* justAnOpaqueColor(uint32_t* value) override;
     190             : 
     191          25 :     int requestRowsPreserved() const override {
     192          25 :         return fBlitter->requestRowsPreserved();
     193             :     }
     194             : 
     195          25 :     void* allocBlitMemory(size_t sz) override {
     196          25 :         return fBlitter->allocBlitMemory(sz);
     197             :     }
     198             : 
     199             : private:
     200             :     SkBlitter*  fBlitter;
     201             :     SkIRect     fClipRect;
     202             : };
     203             : 
     204             : /** Wraps another (real) blitter, and ensures that the real blitter is only
     205             :     called with coordinates that have been clipped by the specified clipRgn.
     206             :     This means the caller need not perform the clipping ahead of time.
     207             : */
     208         452 : class SkRgnClipBlitter : public SkBlitter {
     209             : public:
     210           0 :     void init(SkBlitter* blitter, const SkRegion* clipRgn) {
     211           0 :         SkASSERT(clipRgn && !clipRgn->isEmpty());
     212           0 :         fBlitter = blitter;
     213           0 :         fRgn = clipRgn;
     214           0 :     }
     215             : 
     216             :     void blitH(int x, int y, int width) override;
     217             :     void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
     218             :     void blitV(int x, int y, int height, SkAlpha alpha) override;
     219             :     void blitRect(int x, int y, int width, int height) override;
     220             :     void blitAntiRect(int x, int y, int width, int height,
     221             :                       SkAlpha leftAlpha, SkAlpha rightAlpha) override;
     222             :     void blitMask(const SkMask&, const SkIRect& clip) override;
     223             :     const SkPixmap* justAnOpaqueColor(uint32_t* value) override;
     224             : 
     225           0 :     int requestRowsPreserved() const override {
     226           0 :         return fBlitter->requestRowsPreserved();
     227             :     }
     228             : 
     229           0 :     void* allocBlitMemory(size_t sz) override {
     230           0 :         return fBlitter->allocBlitMemory(sz);
     231             :     }
     232             : 
     233             : private:
     234             :     SkBlitter*      fBlitter;
     235             :     const SkRegion* fRgn;
     236             : };
     237             : 
     238             : #ifdef SK_DEBUG
     239         452 : class SkRectClipCheckBlitter : public SkBlitter {
     240             : public:
     241         200 :     void init(SkBlitter* blitter, const SkIRect& clipRect) {
     242         200 :         SkASSERT(blitter);
     243         200 :         SkASSERT(!clipRect.isEmpty());
     244         200 :         fBlitter = blitter;
     245         200 :         fClipRect = clipRect;
     246         200 :     }
     247             : 
     248             :     void blitH(int x, int y, int width) override;
     249             :     void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override;
     250             :     void blitV(int x, int y, int height, SkAlpha alpha) override;
     251             :     void blitRect(int x, int y, int width, int height) override;
     252             :     void blitAntiRect(int x, int y, int width, int height,
     253             :                               SkAlpha leftAlpha, SkAlpha rightAlpha) override;
     254             :     void blitMask(const SkMask&, const SkIRect& clip) override;
     255             :     const SkPixmap* justAnOpaqueColor(uint32_t* value) override;
     256             :     void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override;
     257             :     void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override;
     258             : 
     259         165 :     int requestRowsPreserved() const override {
     260         165 :         return fBlitter->requestRowsPreserved();
     261             :     }
     262             : 
     263         165 :     void* allocBlitMemory(size_t sz) override {
     264         165 :         return fBlitter->allocBlitMemory(sz);
     265             :     }
     266             : 
     267             : private:
     268             :     SkBlitter*  fBlitter;
     269             :     SkIRect     fClipRect;
     270             : };
     271             : #endif
     272             : 
     273             : /** Factory to set up the appropriate most-efficient wrapper blitter
     274             :     to apply a clip. Returns a pointer to a member, so lifetime must
     275             :     be managed carefully.
     276             : */
     277           0 : class SkBlitterClipper {
     278             : public:
     279             :     SkBlitter*  apply(SkBlitter* blitter, const SkRegion* clip,
     280             :                       const SkIRect* bounds = nullptr);
     281             : 
     282             : private:
     283             :     SkNullBlitter       fNullBlitter;
     284             :     SkRectClipBlitter   fRectBlitter;
     285             :     SkRgnClipBlitter    fRgnBlitter;
     286             : };
     287             : 
     288             : #endif

Generated by: LCOV version 1.13