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