2 * Copyright 2011 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrInOrderDrawBuffer_DEFINED
9 #define GrInOrderDrawBuffer_DEFINED
11 #include "GrDrawTarget.h"
12 #include "GrAllocPool.h"
13 #include "GrAllocator.h"
16 #include "SkClipStack.h"
17 #include "SkTemplates.h"
21 class GrIndexBufferAllocPool;
22 class GrVertexBufferAllocPool;
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
34 class GrInOrderDrawBuffer : public GrDrawTarget {
38 * Creates a GrInOrderDrawBuffer
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.
46 GrInOrderDrawBuffer(GrGpu* gpu,
47 GrVertexBufferAllocPool* vertexPool,
48 GrIndexBufferAllocPool* indexPool);
50 virtual ~GrInOrderDrawBuffer();
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.
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.
67 virtual DrawToken getCurrentDrawToken() { return DrawToken(this, fDrawID); }
69 // overrides from GrDrawTarget
70 virtual bool geometryHints(int* vertexCount,
71 int* indexCount) const SK_OVERRIDE;
72 virtual void clear(const SkIRect* rect,
75 GrRenderTarget* renderTarget) SK_OVERRIDE;
77 virtual void discard(GrRenderTarget*) SK_OVERRIDE;
79 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
82 virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
96 class DrawRecord : public DrawInfo {
98 DrawRecord(const DrawInfo& info) : DrawInfo(info) {}
99 const GrVertexBuffer* fVertexBuffer;
100 const GrIndexBuffer* fIndexBuffer;
103 struct StencilPath : public ::SkNoncopyable {
106 SkAutoTUnref<const GrPath> fPath;
107 SkPath::FillType fFill;
110 struct DrawPath : public ::SkNoncopyable {
113 SkAutoTUnref<const GrPath> fPath;
114 SkPath::FillType fFill;
115 GrDeviceCoordTexture fDstCopy;
118 struct DrawPaths : public ::SkNoncopyable {
123 const GrPath** fPaths;
124 SkMatrix* fTransforms;
125 SkPath::FillType fFill;
126 SkStrokeRec::Style fStroke;
127 GrDeviceCoordTexture fDstCopy;
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); }
138 GrRenderTarget* fRenderTarget;
141 struct CopySurface : public ::SkNoncopyable {
142 SkAutoTUnref<GrSurface> fDst;
143 SkAutoTUnref<GrSurface> fSrc;
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;
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;
162 virtual bool onReserveVertexSpace(size_t vertexSize,
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,
181 const SkIRect& srcRect,
182 const SkIPoint& dstPoint) SK_OVERRIDE;
183 virtual bool onCanCopySurface(GrSurface* dst,
185 const SkIRect& srcRect,
186 const SkIPoint& dstPoint) SK_OVERRIDE;
188 bool quickInsideClip(const SkRect& devBounds);
190 virtual void didAddGpuTraceMarker() SK_OVERRIDE {}
191 virtual void didRemoveGpuTraceMarker() SK_OVERRIDE {}
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);
197 // we lazily record state and clip changes in order to skip clips and states that have no
199 bool needsNewState() const;
200 bool needsNewClip() const;
202 // these functions record a command
205 DrawRecord* recordDraw(const DrawInfo&);
206 StencilPath* recordStencilPath();
207 DrawPath* recordDrawPath();
208 DrawPaths* recordDrawPaths();
209 Clear* recordClear();
210 CopySurface* recordCopySurface();
212 // TODO: Use a single allocator for commands and records
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,
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;
238 GrDrawTarget* fDstGpu;
242 enum ClipProxyState {
243 kUnknown_ClipProxyState,
244 kValid_ClipProxyState,
245 kInvalid_ClipProxyState
247 ClipProxyState fClipProxyState;
250 GrVertexBufferAllocPool& fVertexPool;
252 GrIndexBufferAllocPool& fIndexPool;
254 struct GeometryPoolState {
255 const GrVertexBuffer* fPoolVertexBuffer;
256 int fPoolStartVertex;
257 const GrIndexBuffer* fPoolIndexBuffer;
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;
265 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
267 virtual bool isIssued(uint32_t drawID) { return drawID != fDrawID; }
269 void addToCmdBuffer(uint8_t cmd);
274 typedef GrDrawTarget INHERITED;