1 2 /* 3 * Copyright 2011 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 10 11 #ifndef GrInOrderDrawBuffer_DEFINED 12 #define GrInOrderDrawBuffer_DEFINED 13 14 #include "GrDrawTarget.h" 15 #include "GrAllocPool.h" 16 #include "GrAllocator.h" 17 #include "GrPath.h" 18 19 #include "SkClipStack.h" 20 #include "SkStrokeRec.h" 21 #include "SkTemplates.h" 22 23 class GrGpu; 24 class GrIndexBufferAllocPool; 25 class GrVertexBufferAllocPool; 26 27 /** 28 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws for eventual 29 * playback into a GrGpu. In theory one draw buffer could playback into another. When index or 30 * vertex buffers are used as geometry sources it is the callers the draw buffer only holds 31 * references to the buffers. It is the callers responsibility to ensure that the data is still 32 * valid when the draw buffer is played back into a GrGpu. Similarly, it is the caller's 33 * responsibility to ensure that all referenced textures, buffers, and render-targets are associated 34 * in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to 35 * store geometry. 36 */ 37 class GrInOrderDrawBuffer : public GrDrawTarget { 38 public: 39 40 /** 41 * Creates a GrInOrderDrawBuffer 42 * 43 * @param gpu the gpu object that this draw buffer flushes to. 44 * @param vertexPool pool where vertices for queued draws will be saved when 45 * the vertex source is either reserved or array. 46 * @param indexPool pool where indices for queued draws will be saved when 47 * the index source is either reserved or array. 48 */ 49 GrInOrderDrawBuffer(GrGpu* gpu, 50 GrVertexBufferAllocPool* vertexPool, 51 GrIndexBufferAllocPool* indexPool); 52 53 virtual ~GrInOrderDrawBuffer(); 54 55 /** 56 * Empties the draw buffer of any queued up draws. This must not be called while inside an 57 * unbalanced pushGeometrySource(). The current draw state and clip are preserved. 58 */ 59 void reset(); 60 61 /** 62 * This plays the queued up draws to its GrGpu target. It also resets this object (i.e. flushing 63 * is destructive). This buffer must not have an active reserved vertex or index source. Any 64 * reserved geometry on the target will be finalized because it's geometry source will be pushed 65 * before flushing and popped afterwards. 66 */ 67 void flush(); 68 69 // overrides from GrDrawTarget 70 virtual bool geometryHints(int* vertexCount, 71 int* indexCount) const SK_OVERRIDE; 72 virtual void clear(const SkIRect* rect, 73 GrColor color, 74 GrRenderTarget* renderTarget = NULL) SK_OVERRIDE; 75 76 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE; 77 78 79 protected: 80 virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE; 81 82 private: 83 enum Cmd { 84 kDraw_Cmd = 1, 85 kStencilPath_Cmd = 2, 86 kSetState_Cmd = 3, 87 kSetClip_Cmd = 4, 88 kClear_Cmd = 5, 89 kCopySurface_Cmd = 6, 90 }; 91 92 class DrawRecord : public DrawInfo { 93 public: 94 DrawRecord(const DrawInfo& info) : DrawInfo(info) {} 95 const GrVertexBuffer* fVertexBuffer; 96 const GrIndexBuffer* fIndexBuffer; 97 }; 98 99 struct StencilPath : GrNoncopyable { 100 StencilPath(); 101 102 SkAutoTUnref<const GrPath> fPath; 103 SkStrokeRec fStroke; 104 SkPath::FillType fFill; 105 }; 106 107 struct Clear : GrNoncopyable { 108 Clear() : fRenderTarget(NULL) {} 109 ~Clear() { GrSafeUnref(fRenderTarget); } 110 111 SkIRect fRect; 112 GrColor fColor; 113 GrRenderTarget* fRenderTarget; 114 }; 115 116 struct CopySurface : GrNoncopyable { 117 SkAutoTUnref<GrSurface> fDst; 118 SkAutoTUnref<GrSurface> fSrc; 119 SkIRect fSrcRect; 120 SkIPoint fDstPoint; 121 }; 122 123 // overrides from GrDrawTarget 124 virtual void onDraw(const DrawInfo&) SK_OVERRIDE; 125 virtual void onDrawRect(const SkRect& rect, 126 const SkMatrix* matrix, 127 const SkRect* localRect, 128 const SkMatrix* localMatrix) SK_OVERRIDE; 129 virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE; 130 virtual bool onReserveVertexSpace(size_t vertexSize, 131 int vertexCount, 132 void** vertices) SK_OVERRIDE; 133 virtual bool onReserveIndexSpace(int indexCount, 134 void** indices) SK_OVERRIDE; 135 virtual void releaseReservedVertexSpace() SK_OVERRIDE; 136 virtual void releaseReservedIndexSpace() SK_OVERRIDE; 137 virtual void onSetVertexSourceToArray(const void* vertexArray, 138 int vertexCount) SK_OVERRIDE; 139 virtual void onSetIndexSourceToArray(const void* indexArray, 140 int indexCount) SK_OVERRIDE; 141 virtual void releaseVertexArray() SK_OVERRIDE; 142 virtual void releaseIndexArray() SK_OVERRIDE; 143 virtual void geometrySourceWillPush() SK_OVERRIDE; 144 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE; 145 virtual void willReserveVertexAndIndexSpace(int vertexCount, 146 int indexCount) SK_OVERRIDE; 147 virtual bool onCopySurface(GrSurface* dst, 148 GrSurface* src, 149 const SkIRect& srcRect, 150 const SkIPoint& dstPoint) SK_OVERRIDE; 151 virtual bool onCanCopySurface(GrSurface* dst, 152 GrSurface* src, 153 const SkIRect& srcRect, 154 const SkIPoint& dstPoint) SK_OVERRIDE; 155 156 bool quickInsideClip(const SkRect& devBounds); 157 158 // Attempts to concat instances from info onto the previous draw. info must represent an 159 // instanced draw. The caller must have already recorded a new draw state and clip if necessary. 160 int concatInstancedDraw(const DrawInfo& info); 161 162 // we lazily record state and clip changes in order to skip clips and states that have no 163 // effect. 164 bool needsNewState() const; 165 bool needsNewClip() const; 166 167 // these functions record a command 168 void recordState(); 169 void recordClip(); 170 DrawRecord* recordDraw(const DrawInfo&); 171 StencilPath* recordStencilPath(); 172 Clear* recordClear(); 173 CopySurface* recordCopySurface(); 174 175 // TODO: Use a single allocator for commands and records 176 enum { 177 kCmdPreallocCnt = 32, 178 kDrawPreallocCnt = 8, 179 kStencilPathPreallocCnt = 8, 180 kStatePreallocCnt = 8, 181 kClipPreallocCnt = 8, 182 kClearPreallocCnt = 4, 183 kGeoPoolStatePreAllocCnt = 4, 184 kCopySurfacePreallocCnt = 4, 185 }; 186 187 SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds; 188 GrSTAllocator<kDrawPreallocCnt, DrawRecord> fDraws; 189 GrSTAllocator<kStatePreallocCnt, StencilPath> fStencilPaths; 190 GrSTAllocator<kStatePreallocCnt, GrDrawState::DeferredState> fStates; 191 GrSTAllocator<kClearPreallocCnt, Clear> fClears; 192 GrSTAllocator<kCopySurfacePreallocCnt, CopySurface> fCopySurfaces; 193 GrSTAllocator<kClipPreallocCnt, SkClipStack> fClips; 194 GrSTAllocator<kClipPreallocCnt, SkIPoint> fClipOrigins; 195 196 GrDrawTarget* fDstGpu; 197 198 bool fClipSet; 199 200 enum ClipProxyState { 201 kUnknown_ClipProxyState, 202 kValid_ClipProxyState, 203 kInvalid_ClipProxyState 204 }; 205 ClipProxyState fClipProxyState; 206 SkRect fClipProxy; 207 208 GrVertexBufferAllocPool& fVertexPool; 209 210 GrIndexBufferAllocPool& fIndexPool; 211 212 struct GeometryPoolState { 213 const GrVertexBuffer* fPoolVertexBuffer; 214 int fPoolStartVertex; 215 const GrIndexBuffer* fPoolIndexBuffer; 216 int fPoolStartIndex; 217 // caller may conservatively over reserve vertices / indices. 218 // we release unused space back to allocator if possible 219 // can only do this if there isn't an intervening pushGeometrySource() 220 size_t fUsedPoolVertexBytes; 221 size_t fUsedPoolIndexBytes; 222 }; 223 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack; 224 225 bool fFlushing; 226 227 typedef GrDrawTarget INHERITED; 228 }; 229 230 #endif 231