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