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;
23 class GrVertexBufferAllocPool;
26 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws for eventual
27 * playback into a GrGpu. In theory one draw buffer could playback into another. When index or
28 * vertex buffers are used as geometry sources it is the callers the draw buffer only holds
29 * references to the buffers. It is the callers responsibility to ensure that the data is still
30 * valid when the draw buffer is played back into a GrGpu. Similarly, it is the caller's
31 * responsibility to ensure that all referenced textures, buffers, and render-targets are associated
32 * in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to
35 class GrInOrderDrawBuffer : public GrDrawTarget {
39 * Creates a GrInOrderDrawBuffer
41 * @param gpu the gpu object that this draw buffer flushes to.
42 * @param vertexPool pool where vertices for queued draws will be saved when
43 * the vertex source is either reserved or array.
44 * @param indexPool pool where indices for queued draws will be saved when
45 * the index source is either reserved or array.
47 GrInOrderDrawBuffer(GrGpu* gpu,
48 GrVertexBufferAllocPool* vertexPool,
49 GrIndexBufferAllocPool* indexPool);
51 virtual ~GrInOrderDrawBuffer();
54 * Empties the draw buffer of any queued up draws. This must not be called while inside an
55 * unbalanced pushGeometrySource(). The current draw state and clip are preserved.
60 * This plays the queued up draws to its GrGpu target. It also resets this object (i.e. flushing
61 * is destructive). This buffer must not have an active reserved vertex or index source. Any
62 * reserved geometry on the target will be finalized because it's geometry source will be pushed
63 * before flushing and popped afterwards.
68 virtual DrawToken getCurrentDrawToken() { return DrawToken(this, fDrawID); }
70 // overrides from GrDrawTarget
71 virtual bool geometryHints(int* vertexCount,
72 int* indexCount) const SK_OVERRIDE;
73 virtual void clear(const SkIRect* rect,
76 GrRenderTarget* renderTarget) SK_OVERRIDE;
78 virtual void discard(GrRenderTarget*) SK_OVERRIDE;
80 virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
83 virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
97 class DrawRecord : public DrawInfo {
99 DrawRecord(const DrawInfo& info) : DrawInfo(info) {}
100 const GrVertexBuffer* fVertexBuffer;
101 const GrIndexBuffer* fIndexBuffer;
104 struct StencilPath : public ::SkNoncopyable {
107 SkAutoTUnref<const GrPath> fPath;
108 SkPath::FillType fFill;
111 struct DrawPath : public ::SkNoncopyable {
114 SkAutoTUnref<const GrPath> fPath;
115 SkPath::FillType fFill;
116 GrDeviceCoordTexture fDstCopy;
119 struct DrawPaths : public ::SkNoncopyable {
123 SkAutoTUnref<const GrPathRange> fPathRange;
127 PathTransformType fTransformsType;
128 SkPath::FillType fFill;
129 GrDeviceCoordTexture fDstCopy;
132 // This is also used to record a discard by setting the color to GrColor_ILLEGAL
133 struct Clear : public ::SkNoncopyable {
134 Clear() : fRenderTarget(NULL) {}
135 ~Clear() { SkSafeUnref(fRenderTarget); }
140 GrRenderTarget* fRenderTarget;
143 struct CopySurface : public ::SkNoncopyable {
144 SkAutoTUnref<GrSurface> fDst;
145 SkAutoTUnref<GrSurface> fSrc;
150 struct Clip : public ::SkNoncopyable {
155 // overrides from GrDrawTarget
156 virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
157 virtual void onDrawRect(const SkRect& rect,
158 const SkRect* localRect,
159 const SkMatrix* localMatrix) SK_OVERRIDE;
161 virtual void onStencilPath(const GrPath*, SkPath::FillType) SK_OVERRIDE;
162 virtual void onDrawPath(const GrPath*, SkPath::FillType,
163 const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
164 virtual void onDrawPaths(const GrPathRange*,
165 const uint32_t indices[], int count,
166 const float transforms[], PathTransformType,
167 SkPath::FillType, const GrDeviceCoordTexture*) SK_OVERRIDE;
169 virtual bool onReserveVertexSpace(size_t vertexSize,
171 void** vertices) SK_OVERRIDE;
172 virtual bool onReserveIndexSpace(int indexCount,
173 void** indices) SK_OVERRIDE;
174 virtual void releaseReservedVertexSpace() SK_OVERRIDE;
175 virtual void releaseReservedIndexSpace() SK_OVERRIDE;
176 virtual void onSetVertexSourceToArray(const void* vertexArray,
177 int vertexCount) SK_OVERRIDE;
178 virtual void onSetIndexSourceToArray(const void* indexArray,
179 int indexCount) SK_OVERRIDE;
180 virtual void releaseVertexArray() SK_OVERRIDE;
181 virtual void releaseIndexArray() SK_OVERRIDE;
182 virtual void geometrySourceWillPush() SK_OVERRIDE;
183 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
184 virtual void willReserveVertexAndIndexSpace(int vertexCount,
185 int indexCount) SK_OVERRIDE;
186 virtual bool onCopySurface(GrSurface* dst,
188 const SkIRect& srcRect,
189 const SkIPoint& dstPoint) SK_OVERRIDE;
190 virtual bool onCanCopySurface(GrSurface* dst,
192 const SkIRect& srcRect,
193 const SkIPoint& dstPoint) SK_OVERRIDE;
195 bool quickInsideClip(const SkRect& devBounds);
197 virtual void didAddGpuTraceMarker() SK_OVERRIDE {}
198 virtual void didRemoveGpuTraceMarker() SK_OVERRIDE {}
200 // Attempts to concat instances from info onto the previous draw. info must represent an
201 // instanced draw. The caller must have already recorded a new draw state and clip if necessary.
202 int concatInstancedDraw(const DrawInfo& info);
204 // Determines whether the current draw operation requieres a new drawstate and if so records it.
205 void recordStateIfNecessary();
206 // We lazily record clip changes in order to skip clips that have no effect.
207 bool needsNewClip() const;
209 // these functions record a command
212 DrawRecord* recordDraw(const DrawInfo&);
213 StencilPath* recordStencilPath();
214 DrawPath* recordDrawPath();
215 DrawPaths* recordDrawPaths();
216 Clear* recordClear();
217 CopySurface* recordCopySurface();
219 // TODO: Use a single allocator for commands and records
221 kCmdPreallocCnt = 32,
222 kDrawPreallocCnt = 16,
223 kStencilPathPreallocCnt = 8,
224 kDrawPathPreallocCnt = 8,
225 kDrawPathsPreallocCnt = 8,
226 kStatePreallocCnt = 8,
227 kClipPreallocCnt = 8,
228 kClearPreallocCnt = 8,
229 kGeoPoolStatePreAllocCnt = 4,
230 kCopySurfacePreallocCnt = 4,
233 typedef GrTAllocator<DrawRecord> DrawAllocator;
234 typedef GrTAllocator<StencilPath> StencilPathAllocator;
235 typedef GrTAllocator<DrawPath> DrawPathAllocator;
236 typedef GrTAllocator<DrawPaths> DrawPathsAllocator;
237 typedef GrTAllocator<GrDrawState> StateAllocator;
238 typedef GrTAllocator<Clear> ClearAllocator;
239 typedef GrTAllocator<CopySurface> CopySurfaceAllocator;
240 typedef GrTAllocator<Clip> ClipAllocator;
242 GrSTAllocator<kDrawPreallocCnt, DrawRecord> fDraws;
243 GrSTAllocator<kStencilPathPreallocCnt, StencilPath> fStencilPaths;
244 GrSTAllocator<kDrawPathPreallocCnt, DrawPath> fDrawPath;
245 GrSTAllocator<kDrawPathsPreallocCnt, DrawPaths> fDrawPaths;
246 GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
247 GrSTAllocator<kClearPreallocCnt, Clear> fClears;
248 GrSTAllocator<kCopySurfacePreallocCnt, CopySurface> fCopySurfaces;
249 GrSTAllocator<kClipPreallocCnt, Clip> fClips;
251 SkTArray<GrTraceMarkerSet, false> fGpuCmdMarkers;
253 SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
255 GrDrawTarget* fDstGpu;
259 enum ClipProxyState {
260 kUnknown_ClipProxyState,
261 kValid_ClipProxyState,
262 kInvalid_ClipProxyState
264 ClipProxyState fClipProxyState;
267 GrVertexBufferAllocPool& fVertexPool;
269 GrIndexBufferAllocPool& fIndexPool;
271 struct GeometryPoolState {
272 const GrVertexBuffer* fPoolVertexBuffer;
273 int fPoolStartVertex;
274 const GrIndexBuffer* fPoolIndexBuffer;
276 // caller may conservatively over reserve vertices / indices.
277 // we release unused space back to allocator if possible
278 // can only do this if there isn't an intervening pushGeometrySource()
279 size_t fUsedPoolVertexBytes;
280 size_t fUsedPoolIndexBytes;
282 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
284 virtual bool isIssued(uint32_t drawID) { return drawID != fDrawID; }
286 void addToCmdBuffer(uint8_t cmd);
291 typedef GrDrawTarget INHERITED;