Home | History | Annotate | Download | only in core
      1 /*
      2  * Copyright 2013 Google Inc.
      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 SkDeviceLooper_DEFINED
      9 #define SkDeviceLooper_DEFINED
     10 
     11 #include "SkBitmap.h"
     12 #include "SkMatrix.h"
     13 #include "SkRasterClip.h"
     14 
     15 /**
     16  *  Helper class to manage "tiling" a large coordinate space into managable
     17  *  chunks, where managable means areas that are <= some max critical coordinate
     18  *  size.
     19  *
     20  *  The constructor takes an antialiasing bool, which affects what this maximum
     21  *  allowable size is: If we're drawing BW, then we need coordinates to stay
     22  *  safely within fixed-point range (we use +- 16K, to give ourselves room to
     23  *  add/subtract two fixed values and still be in range. If we're drawing AA,
     24  *  then we reduce that size by the amount that the supersampler scan converter
     25  *  needs (at the moment, that is 4X, so the "safe" range is +- 4K).
     26  *
     27  *  For performance reasons, the class first checks to see if any help is needed
     28  *  at all, and if not (i.e. the specified bounds and base bitmap area already
     29  *  in the safe-zone, then the class does nothing (effectively).
     30  */
     31 class SkDeviceLooper {
     32 public:
     33     SkDeviceLooper(const SkPixmap& base, const SkRasterClip&, const SkIRect& bounds, bool aa);
     34     ~SkDeviceLooper();
     35 
     36     const SkPixmap& getPixmap() const {
     37         SkASSERT(kDone_State != fState);
     38         SkASSERT(fCurrDst);
     39         return *fCurrDst;
     40     }
     41 
     42     const SkRasterClip& getRC() const {
     43         SkASSERT(kDone_State != fState);
     44         SkASSERT(fCurrRC);
     45         return *fCurrRC;
     46     }
     47 
     48     void mapRect(SkRect* dst, const SkRect& src) const;
     49     void mapMatrix(SkMatrix* dst, const SkMatrix& src) const;
     50 
     51     /**
     52      *  Call next to setup the looper to return a valid coordinate chunk.
     53      *  Each time this returns true, it is safe to call mapRect() and
     54      *  mapMatrix(), to convert from "global" coordinate values to ones that
     55      *  are local to this chunk.
     56      *
     57      *  When next() returns false, the list of chunks is done, and mapRect()
     58      *  and mapMatrix() should no longer be called.
     59      */
     60     bool next();
     61 
     62 private:
     63     const SkPixmap&     fBaseDst;
     64     const SkRasterClip& fBaseRC;
     65 
     66     enum State {
     67         kDone_State,    // iteration is complete, getters will assert
     68         kSimple_State,  // no translate/clip mods needed
     69         kComplex_State
     70     };
     71 
     72     // storage for our tiled versions. Perhaps could use SkTLazy
     73     SkPixmap            fSubsetDst;
     74     SkRasterClip        fSubsetRC;
     75 
     76     const SkPixmap*     fCurrDst;
     77     const SkRasterClip* fCurrRC;
     78     SkIRect             fClippedBounds;
     79     SkIPoint            fCurrOffset;
     80     int                 fDelta;
     81     State               fState;
     82 
     83     enum Delta {
     84         kBW_Delta = 1 << 14,        // 16K, gives room to spare for fixedpoint
     85         kAA_Delta = kBW_Delta >> 2  // supersample 4x
     86     };
     87 
     88     bool fitsInDelta(const SkIRect& r) const {
     89         return r.right() < fDelta && r.bottom() < fDelta;
     90     }
     91 
     92     bool computeCurrBitmapAndClip();
     93 };
     94 
     95 #endif
     96