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 "GrIndexBuffer.h" 15 #include "GrRenderTarget.h" 16 #include "GrPath.h" 17 #include "GrPathRange.h" 18 #include "GrSurface.h" 19 #include "GrVertexBuffer.h" 20 21 #include "SkClipStack.h" 22 #include "SkTemplates.h" 23 #include "SkTypes.h" 24 25 class GrGpu; 26 class GrIndexBufferAllocPool; 27 class GrVertexBufferAllocPool; 28 29 /** 30 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws for eventual 31 * playback into a GrGpu. In theory one draw buffer could playback into another. When index or 32 * vertex buffers are used as geometry sources it is the callers the draw buffer only holds 33 * references to the buffers. It is the callers responsibility to ensure that the data is still 34 * valid when the draw buffer is played back into a GrGpu. Similarly, it is the caller's 35 * responsibility to ensure that all referenced textures, buffers, and render-targets are associated 36 * in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to 37 * store geometry. 38 */ 39 class GrInOrderDrawBuffer : public GrDrawTarget { 40 public: 41 42 /** 43 * Creates a GrInOrderDrawBuffer 44 * 45 * @param gpu the gpu object that this draw buffer flushes to. 46 * @param vertexPool pool where vertices for queued draws will be saved when 47 * the vertex source is either reserved or array. 48 * @param indexPool pool where indices for queued draws will be saved when 49 * the index source is either reserved or array. 50 */ 51 GrInOrderDrawBuffer(GrGpu* gpu, 52 GrVertexBufferAllocPool* vertexPool, 53 GrIndexBufferAllocPool* indexPool); 54 55 virtual ~GrInOrderDrawBuffer(); 56 57 /** 58 * Empties the draw buffer of any queued up draws. This must not be called while inside an 59 * unbalanced pushGeometrySource(). The current draw state and clip are preserved. 60 */ 61 void reset(); 62 63 /** 64 * This plays the queued up draws to its GrGpu target. It also resets this object (i.e. flushing 65 * is destructive). This buffer must not have an active reserved vertex or index source. Any 66 * reserved geometry on the target will be finalized because it's geometry source will be pushed 67 * before flushing and popped afterwards. 68 */ 69 void flush(); 70 71 // tracking for draws 72 virtual DrawToken getCurrentDrawToken() { return DrawToken(this, fDrawID); } 73 74 // overrides from GrDrawTarget 75 virtual bool geometryHints(int* vertexCount, 76 int* indexCount) const SK_OVERRIDE; 77 virtual void clear(const SkIRect* rect, 78 GrColor color, 79 bool canIgnoreRect, 80 GrRenderTarget* renderTarget) SK_OVERRIDE; 81 82 virtual void discard(GrRenderTarget*) SK_OVERRIDE; 83 84 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE; 85 86 protected: 87 virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE; 88 89 private: 90 enum Cmd { 91 kDraw_Cmd = 1, 92 kStencilPath_Cmd = 2, 93 kSetState_Cmd = 3, 94 kSetClip_Cmd = 4, 95 kClear_Cmd = 5, 96 kCopySurface_Cmd = 6, 97 kDrawPath_Cmd = 7, 98 kDrawPaths_Cmd = 8, 99 }; 100 101 class Draw : public DrawInfo { 102 public: 103 Draw(const DrawInfo& info, const GrVertexBuffer* vb, const GrIndexBuffer* ib) 104 : DrawInfo(info) 105 , fVertexBuffer(vb) 106 , fIndexBuffer(ib) {} 107 108 const GrVertexBuffer* vertexBuffer() const { return fVertexBuffer.get(); } 109 const GrIndexBuffer* indexBuffer() const { return fIndexBuffer.get(); } 110 111 private: 112 GrPendingIOResource<const GrVertexBuffer, GrIORef::kRead_IOType> fVertexBuffer; 113 GrPendingIOResource<const GrIndexBuffer, GrIORef::kRead_IOType> fIndexBuffer; 114 }; 115 116 struct StencilPath : public ::SkNoncopyable { 117 StencilPath(const GrPath* path) : fPath(path) {} 118 119 const GrPath* path() const { return fPath.get(); } 120 121 SkPath::FillType fFill; 122 123 private: 124 GrPendingIOResource<const GrPath, GrIORef::kRead_IOType> fPath; 125 }; 126 127 struct DrawPath : public ::SkNoncopyable { 128 DrawPath(const GrPath* path) : fPath(path) {} 129 130 const GrPath* path() const { return fPath.get(); } 131 132 SkPath::FillType fFill; 133 GrDeviceCoordTexture fDstCopy; 134 135 private: 136 GrPendingIOResource<const GrPath, GrIORef::kRead_IOType> fPath; 137 }; 138 139 struct DrawPaths : public ::SkNoncopyable { 140 DrawPaths(const GrPathRange* pathRange) 141 : fPathRange(pathRange) {} 142 143 ~DrawPaths() { 144 if (fTransforms) { 145 SkDELETE_ARRAY(fTransforms); 146 } 147 if (fIndices) { 148 SkDELETE_ARRAY(fIndices); 149 } 150 } 151 152 const GrPathRange* pathRange() const { return fPathRange.get(); } 153 154 uint32_t* fIndices; 155 size_t fCount; 156 float* fTransforms; 157 PathTransformType fTransformsType; 158 SkPath::FillType fFill; 159 GrDeviceCoordTexture fDstCopy; 160 161 private: 162 GrPendingIOResource<const GrPathRange, GrIORef::kRead_IOType> fPathRange; 163 }; 164 165 // This is also used to record a discard by setting the color to GrColor_ILLEGAL 166 struct Clear : public ::SkNoncopyable { 167 Clear(GrRenderTarget* rt) : fRenderTarget(rt) {} 168 ~Clear() { } 169 GrRenderTarget* renderTarget() const { return fRenderTarget.get(); } 170 171 SkIRect fRect; 172 GrColor fColor; 173 bool fCanIgnoreRect; 174 175 private: 176 GrPendingIOResource<GrRenderTarget, GrIORef::kWrite_IOType> fRenderTarget; 177 }; 178 179 struct CopySurface : public ::SkNoncopyable { 180 CopySurface(GrSurface* dst, GrSurface* src) : fDst(dst), fSrc(src) {} 181 182 GrSurface* dst() const { return fDst.get(); } 183 GrSurface* src() const { return fSrc.get(); } 184 185 SkIPoint fDstPoint; 186 SkIRect fSrcRect; 187 188 private: 189 GrPendingIOResource<GrSurface, GrIORef::kWrite_IOType> fDst; 190 GrPendingIOResource<GrSurface, GrIORef::kRead_IOType> fSrc; 191 }; 192 193 struct Clip : public ::SkNoncopyable { 194 SkClipStack fStack; 195 SkIPoint fOrigin; 196 }; 197 198 // overrides from GrDrawTarget 199 virtual void onDraw(const DrawInfo&) SK_OVERRIDE; 200 virtual void onDrawRect(const SkRect& rect, 201 const SkRect* localRect, 202 const SkMatrix* localMatrix) SK_OVERRIDE; 203 204 virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE; 205 virtual void onDrawPath(const GrPath*, SkPath::FillType, 206 const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; 207 virtual void onDrawPaths(const GrPathRange*, 208 const uint32_t indices[], int count, 209 const float transforms[], PathTransformType, 210 SkPath::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE; 211 212 virtual bool onReserveVertexSpace(size_t vertexSize, 213 int vertexCount, 214 void** vertices) SK_OVERRIDE; 215 virtual bool onReserveIndexSpace(int indexCount, 216 void** indices) SK_OVERRIDE; 217 virtual void releaseReservedVertexSpace() SK_OVERRIDE; 218 virtual void releaseReservedIndexSpace() SK_OVERRIDE; 219 virtual void onSetVertexSourceToArray(const void* vertexArray, 220 int vertexCount) SK_OVERRIDE; 221 virtual void onSetIndexSourceToArray(const void* indexArray, 222 int indexCount) SK_OVERRIDE; 223 virtual void releaseVertexArray() SK_OVERRIDE; 224 virtual void releaseIndexArray() SK_OVERRIDE; 225 virtual void geometrySourceWillPush() SK_OVERRIDE; 226 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE; 227 virtual void willReserveVertexAndIndexSpace(int vertexCount, 228 int indexCount) SK_OVERRIDE; 229 virtual bool onCopySurface(GrSurface* dst, 230 GrSurface* src, 231 const SkIRect& srcRect, 232 const SkIPoint& dstPoint) SK_OVERRIDE; 233 virtual bool onCanCopySurface(GrSurface* dst, 234 GrSurface* src, 235 const SkIRect& srcRect, 236 const SkIPoint& dstPoint) SK_OVERRIDE; 237 238 bool quickInsideClip(const SkRect& devBounds); 239 240 virtual void didAddGpuTraceMarker() SK_OVERRIDE {} 241 virtual void didRemoveGpuTraceMarker() SK_OVERRIDE {} 242 243 // Attempts to concat instances from info onto the previous draw. info must represent an 244 // instanced draw. The caller must have already recorded a new draw state and clip if necessary. 245 int concatInstancedDraw(const DrawInfo& info); 246 247 // Determines whether the current draw operation requieres a new drawstate and if so records it. 248 void recordStateIfNecessary(); 249 // We lazily record clip changes in order to skip clips that have no effect. 250 bool needsNewClip() const; 251 252 // these functions record a command 253 void recordState(); 254 void recordClip(); 255 Draw* recordDraw(const DrawInfo&, const GrVertexBuffer*, const GrIndexBuffer*); 256 StencilPath* recordStencilPath(const GrPath*); 257 DrawPath* recordDrawPath(const GrPath*); 258 DrawPaths* recordDrawPaths(const GrPathRange*); 259 Clear* recordClear(GrRenderTarget*); 260 CopySurface* recordCopySurface(GrSurface* dst, GrSurface* src); 261 262 virtual bool isIssued(uint32_t drawID) { return drawID != fDrawID; } 263 void addToCmdBuffer(uint8_t cmd); 264 265 // TODO: Use a single allocator for commands and records 266 enum { 267 kCmdPreallocCnt = 32, 268 kDrawPreallocCnt = 16, 269 kStencilPathPreallocCnt = 8, 270 kDrawPathPreallocCnt = 8, 271 kDrawPathsPreallocCnt = 8, 272 kStatePreallocCnt = 8, 273 kClipPreallocCnt = 8, 274 kClearPreallocCnt = 8, 275 kGeoPoolStatePreAllocCnt = 4, 276 kCopySurfacePreallocCnt = 4, 277 }; 278 279 typedef GrTAllocator<Draw> DrawAllocator; 280 typedef GrTAllocator<StencilPath> StencilPathAllocator; 281 typedef GrTAllocator<DrawPath> DrawPathAllocator; 282 typedef GrTAllocator<DrawPaths> DrawPathsAllocator; 283 typedef GrTAllocator<GrDrawState> StateAllocator; 284 typedef GrTAllocator<Clear> ClearAllocator; 285 typedef GrTAllocator<CopySurface> CopySurfaceAllocator; 286 typedef GrTAllocator<Clip> ClipAllocator; 287 288 GrSTAllocator<kDrawPreallocCnt, Draw> fDraws; 289 GrSTAllocator<kStencilPathPreallocCnt, StencilPath> fStencilPaths; 290 GrSTAllocator<kDrawPathPreallocCnt, DrawPath> fDrawPath; 291 GrSTAllocator<kDrawPathsPreallocCnt, DrawPaths> fDrawPaths; 292 GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates; 293 GrSTAllocator<kClearPreallocCnt, Clear> fClears; 294 GrSTAllocator<kCopySurfacePreallocCnt, CopySurface> fCopySurfaces; 295 GrSTAllocator<kClipPreallocCnt, Clip> fClips; 296 297 SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers; 298 SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds; 299 GrDrawTarget* fDstGpu; 300 bool fClipSet; 301 302 enum ClipProxyState { 303 kUnknown_ClipProxyState, 304 kValid_ClipProxyState, 305 kInvalid_ClipProxyState 306 }; 307 308 ClipProxyState fClipProxyState; 309 SkRect fClipProxy; 310 GrVertexBufferAllocPool& fVertexPool; 311 GrIndexBufferAllocPool& fIndexPool; 312 313 struct GeometryPoolState { 314 const GrVertexBuffer* fPoolVertexBuffer; 315 int fPoolStartVertex; 316 const GrIndexBuffer* fPoolIndexBuffer; 317 int fPoolStartIndex; 318 // caller may conservatively over reserve vertices / indices. 319 // we release unused space back to allocator if possible 320 // can only do this if there isn't an intervening pushGeometrySource() 321 size_t fUsedPoolVertexBytes; 322 size_t fUsedPoolIndexBytes; 323 }; 324 325 typedef SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> GeoPoolStateStack; 326 327 GeoPoolStateStack fGeoPoolStateStack; 328 bool fFlushing; 329 uint32_t fDrawID; 330 331 typedef GrDrawTarget INHERITED; 332 }; 333 334 #endif 335