• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 SkBitmap& base, const SkRasterClip&,
34                    const SkIRect& bounds, bool aa);
35     ~SkDeviceLooper();
36 
getBitmap()37     const SkBitmap& getBitmap() const {
38         SkASSERT(kDone_State != fState);
39         SkASSERT(fCurrBitmap);
40         return *fCurrBitmap;
41     }
42 
getRC()43     const SkRasterClip& getRC() const {
44         SkASSERT(kDone_State != fState);
45         SkASSERT(fCurrRC);
46         return *fCurrRC;
47     }
48 
49     void mapRect(SkRect* dst, const SkRect& src) const;
50     void mapMatrix(SkMatrix* dst, const SkMatrix& src) const;
51 
52     /**
53      *  Call next to setup the looper to return a valid coordinate chunk.
54      *  Each time this returns true, it is safe to call mapRect() and
55      *  mapMatrix(), to convert from "global" coordinate values to ones that
56      *  are local to this chunk.
57      *
58      *  When next() returns false, the list of chunks is done, and mapRect()
59      *  and mapMatrix() should no longer be called.
60      */
61     bool next();
62 
63 private:
64     const SkBitmap&     fBaseBitmap;
65     const SkRasterClip& fBaseRC;
66 
67     enum State {
68         kDone_State,    // iteration is complete, getters will assert
69         kSimple_State,  // no translate/clip mods needed
70         kComplex_State
71     };
72 
73     // storage for our tiled versions. Perhaps could use SkTLazy
74     SkBitmap            fSubsetBitmap;
75     SkRasterClip        fSubsetRC;
76 
77     const SkBitmap*     fCurrBitmap;
78     const SkRasterClip* fCurrRC;
79     SkIRect             fClippedBounds;
80     SkIPoint            fCurrOffset;
81     int                 fDelta;
82     State               fState;
83 
84     enum Delta {
85         kBW_Delta = 1 << 14,        // 16K, gives room to spare for fixedpoint
86         kAA_Delta = kBW_Delta >> 2  // supersample 4x
87     };
88 
fitsInDelta(const SkIRect & r)89     bool fitsInDelta(const SkIRect& r) const {
90         return r.right() < fDelta && r.bottom() < fDelta;
91     }
92 
93     bool computeCurrBitmapAndClip();
94 };
95 
96 #endif
97