blob: 21011c9650e5d88af6a7adc01ca0a26e82258768 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
reed@google.comac10a2d2010-12-22 21:39:39 +00002/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00003 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
reed@google.comac10a2d2010-12-22 21:39:39 +00007 */
8
9
epoger@google.comec3ed6a2011-07-28 14:26:00 +000010
reed@google.comac10a2d2010-12-22 21:39:39 +000011#ifndef GrInOrderDrawBuffer_DEFINED
12#define GrInOrderDrawBuffer_DEFINED
13
14#include "GrDrawTarget.h"
15#include "GrAllocPool.h"
16#include "GrAllocator.h"
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000017#include "GrPath.h"
reed@google.comac10a2d2010-12-22 21:39:39 +000018
robertphillips@google.com641f8b12012-07-31 19:15:58 +000019#include "SkClipStack.h"
sugoi@google.com5f74cf82012-12-17 21:16:45 +000020#include "SkStrokeRec.h"
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000021#include "SkTemplates.h"
22
bsalomon@google.com471d4712011-08-23 15:45:25 +000023class GrGpu;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000024class GrIndexBufferAllocPool;
bsalomon@google.com471d4712011-08-23 15:45:25 +000025class GrVertexBufferAllocPool;
reed@google.comac10a2d2010-12-22 21:39:39 +000026
bsalomon@google.com1c13c962011-02-14 16:51:21 +000027/**
bsalomon@google.com55e4a202013-01-11 13:54:21 +000028 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up draws for eventual
29 * playback into a GrGpu. In theory one draw buffer could playback into another. When index or
30 * vertex buffers are used as geometry sources it is the callers the draw buffer only holds
31 * references to the buffers. It is the callers responsibility to ensure that the data is still
32 * valid when the draw buffer is played back into a GrGpu. Similarly, it is the caller's
33 * responsibility to ensure that all referenced textures, buffers, and render-targets are associated
34 * in the GrGpu object that the buffer is played back into. The buffer requires VB and IB pools to
35 * store geometry.
bsalomon@google.com1c13c962011-02-14 16:51:21 +000036 */
reed@google.comac10a2d2010-12-22 21:39:39 +000037class GrInOrderDrawBuffer : public GrDrawTarget {
38public:
39
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000040 /**
41 * Creates a GrInOrderDrawBuffer
42 *
bsalomon@google.com471d4712011-08-23 15:45:25 +000043 * @param gpu the gpu object where this will be played back
44 * (possible indirectly). GrResources used with the draw
45 * buffer are created by this gpu object.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000046 * @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 */
bsalomon@google.com471d4712011-08-23 15:45:25 +000051 GrInOrderDrawBuffer(const GrGpu* gpu,
52 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com1c13c962011-02-14 16:51:21 +000053 GrIndexBufferAllocPool* indexPool);
reed@google.comac10a2d2010-12-22 21:39:39 +000054
55 virtual ~GrInOrderDrawBuffer();
56
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000057 /**
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000058 * Provides the buffer with an index buffer that can be used for quad rendering.
59 * The buffer may be able to batch consecutive drawRects if this is provided.
60 * @param indexBuffer index buffer with quad indices.
61 */
62 void setQuadIndexBuffer(const GrIndexBuffer* indexBuffer);
63
64 /**
bsalomon@google.com55e4a202013-01-11 13:54:21 +000065 * Empties the draw buffer of any queued up draws. This must not be called while inside an
66 * unbalanced pushGeometrySource(). The current draw state and clip are preserved.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000067 */
68 void reset();
69
70 /**
bsalomon@google.com55e4a202013-01-11 13:54:21 +000071 * This plays the queued up draws to another target. It also resets this object (i.e. flushing
72 * is destructive). This buffer must not have an active reserved vertex or index source. Any
73 * reserved geometry on the target will be finalized because it's geometry source will be pushed
74 * before flushing and popped afterwards.
bsalomon@google.com97805382012-03-13 14:32:07 +000075 *
bsalomon@google.com55e4a202013-01-11 13:54:21 +000076 * @return false if the playback trivially drew nothing because nothing was recorded.
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000077 *
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000078 * @param target the target to receive the playback
79 */
bsalomon@google.com55e4a202013-01-11 13:54:21 +000080 bool flushTo(GrDrawTarget* target);
bsalomon@google.com97805382012-03-13 14:32:07 +000081
82 /**
bsalomon@google.com55e4a202013-01-11 13:54:21 +000083 * This function allows the draw buffer to automatically flush itself to another target. This
84 * means the buffer may internally call this->flushTo(target) when it is safe to do so.
rmistry@google.comfbfcd562012-08-23 18:09:54 +000085 *
bsalomon@google.com55e4a202013-01-11 13:54:21 +000086 * When the auto flush target is set to NULL (as it initially is) the draw buffer will never
87 * automatically flush itself.
bsalomon@google.com97805382012-03-13 14:32:07 +000088 */
89 void setAutoFlushTarget(GrDrawTarget* target);
90
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000091 // overrides from GrDrawTarget
rmistry@google.comfbfcd562012-08-23 18:09:54 +000092 virtual void drawRect(const GrRect& rect,
bsalomon@google.comb9086a02012-11-01 18:02:54 +000093 const SkMatrix* matrix = NULL,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000094 const GrRect* srcRects[] = NULL,
bsalomon@google.comb9086a02012-11-01 18:02:54 +000095 const SkMatrix* srcMatrices[] = NULL) SK_OVERRIDE;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000096
bsalomon@google.com934c5702012-03-20 21:17:58 +000097 virtual void drawIndexedInstances(GrPrimitiveType type,
98 int instanceCount,
99 int verticesPerInstance,
100 int indicesPerInstance)
101 SK_OVERRIDE;
102
jvanverth@google.coma6338982013-01-31 21:34:25 +0000103 virtual bool geometryHints(size_t vertexSize,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000104 int* vertexCount,
bsalomon@google.com97805382012-03-13 14:32:07 +0000105 int* indexCount) const SK_OVERRIDE;
reed@google.comac10a2d2010-12-22 21:39:39 +0000106
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000107 virtual void clear(const GrIRect* rect,
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000108 GrColor color,
109 GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000110
bsalomon@google.com97805382012-03-13 14:32:07 +0000111protected:
bsalomon@google.com02ddc8b2013-01-28 15:35:28 +0000112 virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
113
reed@google.comac10a2d2010-12-22 21:39:39 +0000114private:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000115 enum Cmd {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000116 kDraw_Cmd = 1,
117 kStencilPath_Cmd = 2,
118 kSetState_Cmd = 3,
119 kSetClip_Cmd = 4,
120 kClear_Cmd = 5,
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000121 };
122
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000123 // TODO: Make this derive from DrawInfo
124 struct DrawRecord {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000125 GrPrimitiveType fPrimitiveType;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000126 int fStartVertex;
127 int fStartIndex;
128 int fVertexCount;
129 int fIndexCount;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000130 GrVertexLayout fVertexLayout;
131 const GrVertexBuffer* fVertexBuffer;
132 const GrIndexBuffer* fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000133 };
134
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000135 struct StencilPath {
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000136 StencilPath();
137
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000138 SkAutoTUnref<const GrPath> fPath;
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000139 SkStrokeRec fStroke;
sugoi@google.com12b4e272012-12-06 20:13:11 +0000140 SkPath::FillType fFill;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000141 };
142
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000143 struct Clear {
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000144 Clear() : fRenderTarget(NULL) {}
145 ~Clear() { GrSafeUnref(fRenderTarget); }
146
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000147 GrIRect fRect;
148 GrColor fColor;
149 GrRenderTarget* fRenderTarget;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000150 };
151
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000152 // overrides from GrDrawTarget
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000153 virtual void onDraw(const DrawInfo&) SK_OVERRIDE;
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000154 virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE;
jvanverth@google.coma6338982013-01-31 21:34:25 +0000155 virtual bool onReserveVertexSpace(size_t vertexSize,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000156 int vertexCount,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000157 void** vertices) SK_OVERRIDE;
158 virtual bool onReserveIndexSpace(int indexCount,
159 void** indices) SK_OVERRIDE;
160 virtual void releaseReservedVertexSpace() SK_OVERRIDE;
161 virtual void releaseReservedIndexSpace() SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000162 virtual void onSetVertexSourceToArray(const void* vertexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000163 int vertexCount) SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000164 virtual void onSetIndexSourceToArray(const void* indexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000165 int indexCount) SK_OVERRIDE;
166 virtual void releaseVertexArray() SK_OVERRIDE;
167 virtual void releaseIndexArray() SK_OVERRIDE;
168 virtual void geometrySourceWillPush() SK_OVERRIDE;
bsalomon@google.com02ddc8b2013-01-28 15:35:28 +0000169 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
jvanverth@google.coma6338982013-01-31 21:34:25 +0000170 virtual void willReserveVertexAndIndexSpace(size_t vertexSize,
bsalomon@google.com02ddc8b2013-01-28 15:35:28 +0000171 int vertexCount,
172 int indexCount) SK_OVERRIDE;
173
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000174
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000175 // we lazily record state and clip changes in order to skip clips and states
176 // that have no effect.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000177 bool needsNewState() const;
178 bool needsNewClip() const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000179
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000180 // these functions record a command
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000181 void recordState();
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000182 void recordClip();
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000183 DrawRecord* recordDraw();
184 DrawRecord* recordDraw(const DrawInfo&);
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000185 StencilPath* recordStencilPath();
186 Clear* recordClear();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000187
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000188 // call this to invalidate the tracking data that is used to concatenate
bsalomon@google.com934c5702012-03-20 21:17:58 +0000189 // multiple draws into a single draw.
190 void resetDrawTracking();
191
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000192 enum {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000193 kCmdPreallocCnt = 32,
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000194 kDrawPreallocCnt = 8,
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000195 kStencilPathPreallocCnt = 8,
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000196 kStatePreallocCnt = 8,
197 kClipPreallocCnt = 8,
198 kClearPreallocCnt = 4,
199 kGeoPoolStatePreAllocCnt = 4,
200 };
reed@google.comac10a2d2010-12-22 21:39:39 +0000201
bsalomon@google.comca432082013-01-23 19:53:46 +0000202 SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
bsalomon@google.com74749cd2013-01-30 16:12:41 +0000203 GrSTAllocator<kDrawPreallocCnt, DrawRecord> fDraws;
bsalomon@google.comca432082013-01-23 19:53:46 +0000204 GrSTAllocator<kStatePreallocCnt, StencilPath> fStencilPaths;
205 GrSTAllocator<kStatePreallocCnt, GrDrawState::DeferredState> fStates;
206 GrSTAllocator<kClearPreallocCnt, Clear> fClears;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000207
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000208 GrSTAllocator<kClipPreallocCnt, SkClipStack> fClips;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000209 GrSTAllocator<kClipPreallocCnt, SkIPoint> fClipOrigins;
bsalomon@google.com97805382012-03-13 14:32:07 +0000210
211 GrDrawTarget* fAutoFlushTarget;
212
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000213 bool fClipSet;
214
bsalomon@google.com934c5702012-03-20 21:17:58 +0000215 GrVertexBufferAllocPool& fVertexPool;
216
217 GrIndexBufferAllocPool& fIndexPool;
218
219 // these are used to attempt to concatenate drawRect calls
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000220 GrVertexLayout fLastRectVertexLayout;
221 const GrIndexBuffer* fQuadIndexBuffer;
222 int fMaxQuads;
223 int fCurrQuad;
reed@google.comac10a2d2010-12-22 21:39:39 +0000224
bsalomon@google.com55e4a202013-01-11 13:54:21 +0000225 // bookkeeping to attempt to concatenate drawIndexedInstances calls
bsalomon@google.com934c5702012-03-20 21:17:58 +0000226 struct {
227 int fVerticesPerInstance;
228 int fIndicesPerInstance;
229 void reset() {
230 fVerticesPerInstance = 0;
231 fIndicesPerInstance = 0;
232 }
233 } fInstancedDrawTracker;
bsalomon@google.com92669012011-09-27 19:10:05 +0000234
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000235 struct GeometryPoolState {
236 const GrVertexBuffer* fPoolVertexBuffer;
237 int fPoolStartVertex;
238 const GrIndexBuffer* fPoolIndexBuffer;
239 int fPoolStartIndex;
240 // caller may conservatively over reserve vertices / indices.
241 // we release unused space back to allocator if possible
242 // can only do this if there isn't an intervening pushGeometrySource()
243 size_t fUsedPoolVertexBytes;
244 size_t fUsedPoolIndexBytes;
245 };
bsalomon@google.com92669012011-09-27 19:10:05 +0000246 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
reed@google.comac10a2d2010-12-22 21:39:39 +0000247
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000248 bool fFlushing;
249
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000250 typedef GrDrawTarget INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000251};
252
253#endif