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) SK_OVERRIDE; 76 77 virtual void discard(GrRenderTarget*) SK_OVERRIDE; 78 79 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE; 80 81 protected: 82 virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE; 83 84 private: 85 enum Cmd { 86 kDraw_Cmd = 1, 87 kStencilPath_Cmd = 2, 88 kSetState_Cmd = 3, 89 kSetClip_Cmd = 4, 90 kClear_Cmd = 5, 91 kCopySurface_Cmd = 6, 92 kDrawPath_Cmd = 7, 93 kDrawPaths_Cmd = 8, 94 }; 95 96 class DrawRecord : public DrawInfo { 97 public: 98 DrawRecord(const DrawInfo& info) : DrawInfo(info) {} 99 const GrVertexBuffer* fVertexBuffer; 100 const GrIndexBuffer* fIndexBuffer; 101 }; 102 103 struct StencilPath : public ::SkNoncopyable { 104 StencilPath(); 105 106 SkAutoTUnref<const GrPath> fPath; 107 SkPath::FillType fFill; 108 }; 109 110 struct DrawPath : public ::SkNoncopyable { 111 DrawPath(); 112 113 SkAutoTUnref<const GrPath> fPath; 114 SkPath::FillType fFill; 115 GrDeviceCoordTexture fDstCopy; 116 }; 117 118 struct DrawPaths : public ::SkNoncopyable { 119 DrawPaths(); 120 ~DrawPaths(); 121 122 int fPathCount; 123 const GrPath** fPaths; 124 SkMatrix* fTransforms; 125 SkPath::FillType fFill; 126 SkStrokeRec::Style fStroke; 127 GrDeviceCoordTexture fDstCopy; 128 }; 129 130 // This is also used to record a discard by setting the color to GrColor_ILLEGAL 131 struct Clear : public ::SkNoncopyable { 132 Clear() : fRenderTarget(NULL) {} 133 ~Clear() { SkSafeUnref(fRenderTarget); } 134 135 SkIRect fRect; 136 GrColor fColor; 137 bool fCanIgnoreRect; 138 GrRenderTarget* fRenderTarget; 139 }; 140 141 struct CopySurface : public ::SkNoncopyable { 142 SkAutoTUnref<GrSurface> fDst; 143 SkAutoTUnref<GrSurface> fSrc; 144 SkIRect fSrcRect; 145 SkIPoint fDstPoint; 146 }; 147 148 // overrides from GrDrawTarget 149 virtual void onDraw(const DrawInfo&) SK_OVERRIDE; 150 virtual void onDrawRect(const SkRect& rect, 151 const SkMatrix* matrix, 152 const SkRect* localRect, 153 const SkMatrix* localMatrix) SK_OVERRIDE; 154 155 virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; 156 virtual void onDrawPath(const GrPath*, SkPath::FillType, 157 const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; 158 virtual void onDrawPaths(int, const GrPath**, const SkMatrix*, 159 SkPath::FillType, SkStrokeRec::Style, 160 const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; 161 162 virtual bool onReserveVertexSpace(size_t vertexSize, 163 int vertexCount, 164 void** vertices) SK_OVERRIDE; 165 virtual bool onReserveIndexSpace(int indexCount, 166 void** indices) SK_OVERRIDE; 167 virtual void releaseReservedVertexSpace() SK_OVERRIDE; 168 virtual void releaseReservedIndexSpace() SK_OVERRIDE; 169 virtual void onSetVertexSourceToArray(const void* vertexArray, 170 int vertexCount) SK_OVERRIDE; 171 virtual void onSetIndexSourceToArray(const void* indexArray, 172 int indexCount) SK_OVERRIDE; 173 virtual void releaseVertexArray() SK_OVERRIDE; 174 virtual void releaseIndexArray() SK_OVERRIDE; 175 virtual void geometrySourceWillPush() SK_OVERRIDE; 176 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE; 177 virtual void willReserveVertexAndIndexSpace(int vertexCount, 178 int indexCount) SK_OVERRIDE; 179 virtual bool onCopySurface(GrSurface* dst, 180 GrSurface* src, 181 const SkIRect& srcRect, 182 const SkIPoint& dstPoint) SK_OVERRIDE; 183 virtual bool onCanCopySurface(GrSurface* dst, 184 GrSurface* src, 185 const SkIRect& srcRect, 186 const SkIPoint& dstPoint) SK_OVERRIDE; 187 188 bool quickInsideClip(const SkRect& devBounds); 189 190 virtual void didAddGpuTraceMarker() SK_OVERRIDE {} 191 virtual void didRemoveGpuTraceMarker() SK_OVERRIDE {} 192 193 // Attempts to concat instances from info onto the previous draw. info must represent an 194 // instanced draw. The caller must have already recorded a new draw state and clip if necessary. 195 int concatInstancedDraw(const DrawInfo& info); 196 197 // we lazily record state and clip changes in order to skip clips and states that have no 198 // effect. 199 bool needsNewState() const; 200 bool needsNewClip() const; 201 202 // these functions record a command 203 void recordState(); 204 void recordClip(); 205 DrawRecord* recordDraw(const DrawInfo&); 206 StencilPath* recordStencilPath(); 207 DrawPath* recordDrawPath(); 208 DrawPaths* recordDrawPaths(); 209 Clear* recordClear(); 210 CopySurface* recordCopySurface(); 211 212 // TODO: Use a single allocator for commands and records 213 enum { 214 kCmdPreallocCnt = 32, 215 kDrawPreallocCnt = 8, 216 kStencilPathPreallocCnt = 8, 217 kDrawPathPreallocCnt = 8, 218 kDrawPathsPreallocCnt = 8, 219 kStatePreallocCnt = 8, 220 kClipPreallocCnt = 8, 221 kClearPreallocCnt = 4, 222 kGeoPoolStatePreAllocCnt = 4, 223 kCopySurfacePreallocCnt = 4, 224 }; 225 226 SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds; 227 GrSTAllocator<kDrawPreallocCnt, DrawRecord> fDraws; 228 GrSTAllocator<kStencilPathPreallocCnt, StencilPath> fStencilPaths; 229 GrSTAllocator<kDrawPathPreallocCnt, DrawPath> fDrawPath; 230 GrSTAllocator<kDrawPathsPreallocCnt, DrawPaths> fDrawPaths; 231 GrSTAllocator<kStatePreallocCnt, GrDrawState::DeferredState> fStates; 232 GrSTAllocator<kClearPreallocCnt, Clear> fClears; 233 GrSTAllocator<kCopySurfacePreallocCnt, CopySurface> fCopySurfaces; 234 GrSTAllocator<kClipPreallocCnt, SkClipStack> fClips; 235 GrSTAllocator<kClipPreallocCnt, SkIPoint> fClipOrigins; 236 SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers; 237 238 GrDrawTarget* fDstGpu; 239 240 bool fClipSet; 241 242 enum ClipProxyState { 243 kUnknown_ClipProxyState, 244 kValid_ClipProxyState, 245 kInvalid_ClipProxyState 246 }; 247 ClipProxyState fClipProxyState; 248 SkRect fClipProxy; 249 250 GrVertexBufferAllocPool& fVertexPool; 251 252 GrIndexBufferAllocPool& fIndexPool; 253 254 struct GeometryPoolState { 255 const GrVertexBuffer* fPoolVertexBuffer; 256 int fPoolStartVertex; 257 const GrIndexBuffer* fPoolIndexBuffer; 258 int fPoolStartIndex; 259 // caller may conservatively over reserve vertices / indices. 260 // we release unused space back to allocator if possible 261 // can only do this if there isn't an intervening pushGeometrySource() 262 size_t fUsedPoolVertexBytes; 263 size_t fUsedPoolIndexBytes; 264 }; 265 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack; 266 267 virtual bool isIssued(uint32_t drawID) { return drawID != fDrawID; } 268 269 void addToCmdBuffer(uint8_t cmd); 270 271 bool fFlushing; 272 uint32_t fDrawID; 273 274 typedef GrDrawTarget INHERITED; 275 }; 276 277 #endif 278