Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / core / SkPictureStateTree.h
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 nextDraw();
79         static const uint32_t kDrawComplete = SK_MaxU32;
80         Iterator() : fPlaybackMatrix(), fValid(false) { }
81         bool isValid() const { return fValid; }
82
83     private:
84         Iterator(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root);
85
86         void setCurrentMatrix(const SkMatrix*);
87
88         // The draws this iterator is associated with
89         const SkTDArray<void*>* fDraws;
90
91         // canvas this is playing into (so we can insert saves/restores as necessary)
92         SkCanvas* fCanvas;
93
94         // current state node
95         Node* fCurrentNode;
96
97         // List of nodes whose state we need to apply to reach TargetNode
98         SkTDArray<Node*> fNodes;
99
100         // The matrix of the canvas we're playing back into
101         const SkMatrix fPlaybackMatrix;
102
103         // Cache of current matrix, so we can avoid redundantly setting it
104         const SkMatrix* fCurrentMatrix;
105
106         // current position in the array of draws
107         int fPlaybackIndex;
108         // Whether or not we need to do a save next iteration
109         bool fSave;
110
111         // Whether or not this is a valid iterator (the default public constructor sets this false)
112         bool fValid;
113
114         friend class SkPictureStateTree;
115     };
116
117 private:
118
119     void appendNode(size_t offset);
120
121     SkChunkAlloc fAlloc;
122     // Needed by saveCollapsed() because nodes do not currently store
123     // references to their children.  If they did, we could just retrieve the
124     // last added child.
125     Node* fLastRestoredNode;
126
127     // The currently active state
128     Draw fCurrentState;
129     // A stack of states for tracking save/restores
130     SkDeque fStateStack;
131
132     // Represents a notable piece of state that requires an offset into the command buffer,
133     // corresponding to a clip/saveLayer/etc call, to apply.
134     struct Node {
135         Node* fParent;
136         uint32_t fOffset;
137         uint16_t fLevel;
138         uint16_t fFlags;
139         SkMatrix* fMatrix;
140         enum Flags {
141             kSave_Flag      = 0x1,
142             kSaveLayer_Flag = 0x2
143         };
144     };
145
146     Node fRoot;
147     SkMatrix fRootMatrix;
148
149     typedef SkRefCnt INHERITED;
150 };
151
152 #endif