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