Line data Source code
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 213 : const SkPixmap& getPixmap() const {
37 213 : SkASSERT(kDone_State != fState);
38 213 : SkASSERT(fCurrDst);
39 213 : return *fCurrDst;
40 : }
41 :
42 213 : const SkRasterClip& getRC() const {
43 213 : SkASSERT(kDone_State != fState);
44 213 : SkASSERT(fCurrRC);
45 213 : 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 213 : bool fitsInDelta(const SkIRect& r) const {
89 213 : return r.right() < fDelta && r.bottom() < fDelta;
90 : }
91 :
92 : bool computeCurrBitmapAndClip();
93 : };
94 :
95 : #endif
|