Upstream version 5.34.104.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 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