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 * 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; Iterator()80 Iterator() : fPlaybackMatrix(), fValid(false) { } isValid()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(uint32_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 149