OLD | NEW |
| (Empty) |
1 | |
2 /* | |
3 * Copyright 2012 Google Inc. | |
4 * | |
5 * Use of this source code is governed by a BSD-style license that can be | |
6 * found in the LICENSE file. | |
7 */ | |
8 | |
9 #ifndef SkPictureStateTree_DEFINED | |
10 #define SkPictureStateTree_DEFINED | |
11 | |
12 #include "SkTDArray.h" | |
13 #include "SkChunkAlloc.h" | |
14 #include "SkDeque.h" | |
15 #include "SkMatrix.h" | |
16 #include "SkRefCnt.h" | |
17 | |
18 class SkCanvas; | |
19 | |
20 /** | |
21 * Provides an interface that, given a sequence of draws into an SkPicture with
corresponding | |
22 * offsets, allows for playback of an arbitrary subset of the draws (note that Z
-order is only | |
23 * guaranteed if the draws are explicitly sorted). | |
24 */ | |
25 class SkPictureStateTree : public SkRefCnt { | |
26 private: | |
27 struct Node; | |
28 public: | |
29 SK_DECLARE_INST_COUNT(SkPictureStateTree) | |
30 | |
31 /** | |
32 * A draw call, stores offset into command buffer, a pointer to the matrix,
and a pointer to | |
33 * the node in the tree that corresponds to its clip/layer state | |
34 */ | |
35 struct Draw { | |
36 SkMatrix* fMatrix; | |
37 Node* fNode; | |
38 uint32_t fOffset; | |
39 bool operator<(const Draw& other) const { return fOffset < other.fOffset
; } | |
40 }; | |
41 | |
42 class Iterator; | |
43 | |
44 SkPictureStateTree(); | |
45 ~SkPictureStateTree(); | |
46 | |
47 /** | |
48 * Creates and returns a struct representing a draw at the given offset. | |
49 */ | |
50 Draw* appendDraw(size_t offset); | |
51 | |
52 /** | |
53 * Given a list of draws, and a canvas, initialize an iterator that produces
the correct | |
54 * sequence of offsets into the command buffer to carry out those calls with
correct | |
55 * matrix/clip state. This handles saves/restores, and does all necessary ma
trix setup. | |
56 */ | |
57 void initIterator(SkPictureStateTree::Iterator* iter, | |
58 const SkTDArray<void*>& draws, | |
59 SkCanvas* canvas); | |
60 | |
61 void appendSave(); | |
62 void appendSaveLayer(size_t offset); | |
63 void appendRestore(); | |
64 void appendTransform(const SkMatrix& trans); | |
65 void appendClip(size_t offset); | |
66 | |
67 /** | |
68 * Call this immediately after an appendRestore call that is associated | |
69 * a save or saveLayer that was removed from the command stream | |
70 * due to a command pattern optimization in SkPicture. | |
71 */ | |
72 void saveCollapsed(); | |
73 | |
74 /** | |
75 * Playback helper | |
76 */ | |
77 class Iterator { | |
78 public: | |
79 /** Returns the next op offset needed to create the drawing state | |
80 required by the queued up draw operation or the offset of the queued | |
81 up draw operation itself. In the latter case, the next draw operatio
n | |
82 will move into the queued up slot. | |
83 It retuns kDrawComplete when done. | |
84 TODO: this might be better named nextOp | |
85 */ | |
86 uint32_t nextDraw(); | |
87 static const uint32_t kDrawComplete = SK_MaxU32; | |
88 Iterator() : fValid(false) { } | |
89 bool isValid() const { return fValid; } | |
90 | |
91 private: | |
92 void init(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root); | |
93 | |
94 void setCurrentMatrix(const SkMatrix*); | |
95 | |
96 // The draws this iterator is associated with | |
97 const SkTDArray<void*>* fDraws; | |
98 | |
99 // canvas this is playing into (so we can insert saves/restores as neces
sary) | |
100 SkCanvas* fCanvas; | |
101 | |
102 // current state node | |
103 Node* fCurrentNode; | |
104 | |
105 // List of nodes whose state we need to apply to reach TargetNode | |
106 SkTDArray<Node*> fNodes; | |
107 | |
108 // The matrix of the canvas we're playing back into | |
109 SkMatrix fPlaybackMatrix; | |
110 | |
111 // Cache of current matrix, so we can avoid redundantly setting it | |
112 const SkMatrix* fCurrentMatrix; | |
113 | |
114 // current position in the array of draws | |
115 int fPlaybackIndex; | |
116 // Whether or not we need to do a save next iteration | |
117 bool fSave; | |
118 | |
119 // Whether or not this is a valid iterator (the default public construct
or sets this false) | |
120 bool fValid; | |
121 | |
122 uint32_t finish(); | |
123 | |
124 friend class SkPictureStateTree; | |
125 }; | |
126 | |
127 private: | |
128 | |
129 void appendNode(size_t offset); | |
130 | |
131 SkChunkAlloc fAlloc; | |
132 // Needed by saveCollapsed() because nodes do not currently store | |
133 // references to their children. If they did, we could just retrieve the | |
134 // last added child. | |
135 Node* fLastRestoredNode; | |
136 | |
137 // The currently active state | |
138 Draw fCurrentState; | |
139 // A stack of states for tracking save/restores | |
140 SkDeque fStateStack; | |
141 | |
142 // Represents a notable piece of state that requires an offset into the comm
and buffer, | |
143 // corresponding to a clip/saveLayer/etc call, to apply. | |
144 struct Node { | |
145 Node* fParent; | |
146 uint32_t fOffset; | |
147 uint16_t fLevel; | |
148 uint16_t fFlags; | |
149 SkMatrix* fMatrix; | |
150 enum Flags { | |
151 kSave_Flag = 0x1, | |
152 kSaveLayer_Flag = 0x2 | |
153 }; | |
154 }; | |
155 | |
156 Node fRoot; | |
157 SkMatrix fRootMatrix; | |
158 | |
159 typedef SkRefCnt INHERITED; | |
160 }; | |
161 | |
162 #endif | |
OLD | NEW |