|
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, returns an iterator that produces the correct sequence |
|
54 * of offsets into the command buffer to carry out those calls with correct matrix/clip state. |
|
55 * This handles saves/restores, and does all necessary matrix setup. |
|
56 */ |
|
57 Iterator getIterator(const SkTDArray<void*>& draws, SkCanvas* canvas); |
|
58 |
|
59 void appendSave(); |
|
60 void appendSaveLayer(size_t offset); |
|
61 void appendRestore(); |
|
62 void appendTransform(const SkMatrix& trans); |
|
63 void appendClip(size_t offset); |
|
64 |
|
65 /** |
|
66 * Call this immediately after an appendRestore call that is associated |
|
67 * a save or saveLayer that was removed from the command stream |
|
68 * due to a command pattern optimization in SkPicture. |
|
69 */ |
|
70 void saveCollapsed(); |
|
71 |
|
72 /** |
|
73 * Playback helper |
|
74 */ |
|
75 class Iterator { |
|
76 public: |
|
77 /** Returns the next offset into the picture stream, or kDrawComplete if complete. */ |
|
78 uint32_t draw(); |
|
79 static const uint32_t kDrawComplete = SK_MaxU32; |
|
80 Iterator() : fPlaybackMatrix(), fValid(false) { } |
|
81 bool isValid() const { return fValid; } |
|
82 private: |
|
83 Iterator(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root); |
|
84 // The draws this iterator is associated with |
|
85 const SkTDArray<void*>* fDraws; |
|
86 |
|
87 // canvas this is playing into (so we can insert saves/restores as necessary) |
|
88 SkCanvas* fCanvas; |
|
89 |
|
90 // current state node |
|
91 Node* fCurrentNode; |
|
92 |
|
93 // List of nodes whose state we need to apply to reach TargetNode |
|
94 SkTDArray<Node*> fNodes; |
|
95 |
|
96 // The matrix of the canvas we're playing back into |
|
97 const SkMatrix fPlaybackMatrix; |
|
98 |
|
99 // Cache of current matrix, so we can avoid redundantly setting it |
|
100 SkMatrix* fCurrentMatrix; |
|
101 |
|
102 // current position in the array of draws |
|
103 int fPlaybackIndex; |
|
104 // Whether or not we need to do a save next iteration |
|
105 bool fSave; |
|
106 |
|
107 // Whether or not this is a valid iterator (the default public constructor sets this false) |
|
108 bool fValid; |
|
109 |
|
110 friend class SkPictureStateTree; |
|
111 }; |
|
112 |
|
113 private: |
|
114 |
|
115 void appendNode(size_t offset); |
|
116 |
|
117 SkChunkAlloc fAlloc; |
|
118 // Needed by saveCollapsed() because nodes do not currently store |
|
119 // references to their children. If they did, we could just retrieve the |
|
120 // last added child. |
|
121 Node* fLastRestoredNode; |
|
122 |
|
123 // The currently active state |
|
124 Draw fCurrentState; |
|
125 // A stack of states for tracking save/restores |
|
126 SkDeque fStateStack; |
|
127 |
|
128 // Represents a notable piece of state that requires an offset into the command buffer, |
|
129 // corresponding to a clip/saveLayer/etc call, to apply. |
|
130 struct Node { |
|
131 Node* fParent; |
|
132 uint32_t fOffset; |
|
133 uint16_t fLevel; |
|
134 uint16_t fFlags; |
|
135 SkMatrix* fMatrix; |
|
136 enum Flags { |
|
137 kSave_Flag = 0x1, |
|
138 kSaveLayer_Flag = 0x2 |
|
139 }; |
|
140 }; |
|
141 |
|
142 Node fRoot; |
|
143 SkMatrix fRootMatrix; |
|
144 |
|
145 typedef SkRefCnt INHERITED; |
|
146 }; |
|
147 |
|
148 #endif |