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