1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkPictureStateTree.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,148 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2012 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 +#ifndef SkPictureStateTree_DEFINED 1.13 +#define SkPictureStateTree_DEFINED 1.14 + 1.15 +#include "SkTDArray.h" 1.16 +#include "SkChunkAlloc.h" 1.17 +#include "SkDeque.h" 1.18 +#include "SkMatrix.h" 1.19 +#include "SkRefCnt.h" 1.20 + 1.21 +class SkCanvas; 1.22 + 1.23 +/** 1.24 + * Provides an interface that, given a sequence of draws into an SkPicture with corresponding 1.25 + * offsets, allows for playback of an arbitrary subset of the draws (note that Z-order is only 1.26 + * guaranteed if the draws are explicitly sorted). 1.27 + */ 1.28 +class SkPictureStateTree : public SkRefCnt { 1.29 +private: 1.30 + struct Node; 1.31 +public: 1.32 + SK_DECLARE_INST_COUNT(SkPictureStateTree) 1.33 + 1.34 + /** 1.35 + * A draw call, stores offset into command buffer, a pointer to the matrix, and a pointer to 1.36 + * the node in the tree that corresponds to its clip/layer state 1.37 + */ 1.38 + struct Draw { 1.39 + SkMatrix* fMatrix; 1.40 + Node* fNode; 1.41 + uint32_t fOffset; 1.42 + bool operator<(const Draw& other) const { return fOffset < other.fOffset; } 1.43 + }; 1.44 + 1.45 + class Iterator; 1.46 + 1.47 + SkPictureStateTree(); 1.48 + ~SkPictureStateTree(); 1.49 + 1.50 + /** 1.51 + * Creates and returns a struct representing a draw at the given offset. 1.52 + */ 1.53 + Draw* appendDraw(size_t offset); 1.54 + 1.55 + /** 1.56 + * Given a list of draws, and a canvas, returns an iterator that produces the correct sequence 1.57 + * of offsets into the command buffer to carry out those calls with correct matrix/clip state. 1.58 + * This handles saves/restores, and does all necessary matrix setup. 1.59 + */ 1.60 + Iterator getIterator(const SkTDArray<void*>& draws, SkCanvas* canvas); 1.61 + 1.62 + void appendSave(); 1.63 + void appendSaveLayer(size_t offset); 1.64 + void appendRestore(); 1.65 + void appendTransform(const SkMatrix& trans); 1.66 + void appendClip(size_t offset); 1.67 + 1.68 + /** 1.69 + * Call this immediately after an appendRestore call that is associated 1.70 + * a save or saveLayer that was removed from the command stream 1.71 + * due to a command pattern optimization in SkPicture. 1.72 + */ 1.73 + void saveCollapsed(); 1.74 + 1.75 + /** 1.76 + * Playback helper 1.77 + */ 1.78 + class Iterator { 1.79 + public: 1.80 + /** Returns the next offset into the picture stream, or kDrawComplete if complete. */ 1.81 + uint32_t draw(); 1.82 + static const uint32_t kDrawComplete = SK_MaxU32; 1.83 + Iterator() : fPlaybackMatrix(), fValid(false) { } 1.84 + bool isValid() const { return fValid; } 1.85 + private: 1.86 + Iterator(const SkTDArray<void*>& draws, SkCanvas* canvas, Node* root); 1.87 + // The draws this iterator is associated with 1.88 + const SkTDArray<void*>* fDraws; 1.89 + 1.90 + // canvas this is playing into (so we can insert saves/restores as necessary) 1.91 + SkCanvas* fCanvas; 1.92 + 1.93 + // current state node 1.94 + Node* fCurrentNode; 1.95 + 1.96 + // List of nodes whose state we need to apply to reach TargetNode 1.97 + SkTDArray<Node*> fNodes; 1.98 + 1.99 + // The matrix of the canvas we're playing back into 1.100 + const SkMatrix fPlaybackMatrix; 1.101 + 1.102 + // Cache of current matrix, so we can avoid redundantly setting it 1.103 + SkMatrix* fCurrentMatrix; 1.104 + 1.105 + // current position in the array of draws 1.106 + int fPlaybackIndex; 1.107 + // Whether or not we need to do a save next iteration 1.108 + bool fSave; 1.109 + 1.110 + // Whether or not this is a valid iterator (the default public constructor sets this false) 1.111 + bool fValid; 1.112 + 1.113 + friend class SkPictureStateTree; 1.114 + }; 1.115 + 1.116 +private: 1.117 + 1.118 + void appendNode(size_t offset); 1.119 + 1.120 + SkChunkAlloc fAlloc; 1.121 + // Needed by saveCollapsed() because nodes do not currently store 1.122 + // references to their children. If they did, we could just retrieve the 1.123 + // last added child. 1.124 + Node* fLastRestoredNode; 1.125 + 1.126 + // The currently active state 1.127 + Draw fCurrentState; 1.128 + // A stack of states for tracking save/restores 1.129 + SkDeque fStateStack; 1.130 + 1.131 + // Represents a notable piece of state that requires an offset into the command buffer, 1.132 + // corresponding to a clip/saveLayer/etc call, to apply. 1.133 + struct Node { 1.134 + Node* fParent; 1.135 + uint32_t fOffset; 1.136 + uint16_t fLevel; 1.137 + uint16_t fFlags; 1.138 + SkMatrix* fMatrix; 1.139 + enum Flags { 1.140 + kSave_Flag = 0x1, 1.141 + kSaveLayer_Flag = 0x2 1.142 + }; 1.143 + }; 1.144 + 1.145 + Node fRoot; 1.146 + SkMatrix fRootMatrix; 1.147 + 1.148 + typedef SkRefCnt INHERITED; 1.149 +}; 1.150 + 1.151 +#endif