• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(uint32_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(uint32_t offset);
61     void appendRestore();
62     void appendTransform(const SkMatrix& trans);
63     void appendClip(uint32_t offset);
64 
65     /**
66      * Playback helper
67      */
68     class Iterator {
69     public:
70         /** Returns the next offset into the picture stream, or kDrawComplete if complete. */
71         uint32_t draw();
72         static const uint32_t kDrawComplete = SK_MaxU32;
Iterator()73         Iterator() : fPlaybackMatrix(), fValid(false) { }
isValid()74         bool isValid() const { return fValid; }
75     private:
76         Iterator(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root);
77         // The draws this iterator is associated with
78         const SkTDArray<void*>* fDraws;
79 
80         // canvas this is playing into (so we can insert saves/restores as necessary)
81         SkCanvas* fCanvas;
82 
83         // current state node
84         Node* fCurrentNode;
85 
86         // List of nodes whose state we need to apply to reach TargetNode
87         SkTDArray<Node*> fNodes;
88 
89         // The matrix of the canvas we're playing back into
90         const SkMatrix fPlaybackMatrix;
91 
92         // Cache of current matrix, so we can avoid redundantly setting it
93         SkMatrix* fCurrentMatrix;
94 
95         // current position in the array of draws
96         int fPlaybackIndex;
97         // Whether or not we need to do a save next iteration
98         bool fSave;
99 
100         // Whether or not this is a valid iterator (the default public constructor sets this false)
101         bool fValid;
102 
103         friend class SkPictureStateTree;
104     };
105 
106 private:
107 
108     void appendNode(uint32_t offset);
109 
110     SkChunkAlloc fAlloc;
111     Node* fRoot;
112 
113     // The currently active state
114     Draw fCurrentState;
115     // A stack of states for tracking save/restores
116     SkDeque fStateStack;
117 
118     // Represents a notable piece of state that requires an offset into the command buffer,
119     // corresponding to a clip/saveLayer/etc call, to apply.
120     struct Node {
121         Node* fParent;
122         uint32_t fOffset;
123         uint16_t fLevel;
124         uint16_t fFlags;
125         SkMatrix* fMatrix;
126         enum Flags {
127             kSave_Flag      = 0x1,
128             kSaveLayer_Flag = 0x2
129         };
130     };
131 
132     typedef SkRefCnt INHERITED;
133 };
134 
135 #endif
136