blob: 08dd774c270e1300dcac137a8f2310f9d16bb83b [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"
bsalomon@google.comded4f4b2012-06-28 18:48:06 +000020#include "SkTemplates.h"
21
bsalomon@google.com471d4712011-08-23 15:45:25 +000022class GrGpu;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000023class GrIndexBufferAllocPool;
bsalomon@google.com471d4712011-08-23 15:45:25 +000024class GrVertexBufferAllocPool;
reed@google.comac10a2d2010-12-22 21:39:39 +000025
bsalomon@google.com1c13c962011-02-14 16:51:21 +000026/**
27 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up
28 * draws for eventual playback into a GrGpu. In theory one draw buffer could
29 * playback into another. When index or vertex buffers are used as geometry
30 * sources it is the callers the draw buffer only holds references to the
31 * 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
33 * caller's responsibility to ensure that all referenced textures, buffers,
34 * and rendertargets are associated in the GrGpu object that the buffer is
35 * played back into. The buffer requires VB and IB pools to store geometry.
36 */
37
reed@google.comac10a2d2010-12-22 21:39:39 +000038class GrInOrderDrawBuffer : public GrDrawTarget {
39public:
40
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000041 /**
42 * Creates a GrInOrderDrawBuffer
43 *
bsalomon@google.com471d4712011-08-23 15:45:25 +000044 * @param gpu the gpu object where this will be played back
45 * (possible indirectly). GrResources used with the draw
46 * buffer are created by this gpu object.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000047 * @param vertexPool pool where vertices for queued draws will be saved when
48 * the vertex source is either reserved or array.
49 * @param indexPool pool where indices for queued draws will be saved when
50 * the index source is either reserved or array.
51 */
bsalomon@google.com471d4712011-08-23 15:45:25 +000052 GrInOrderDrawBuffer(const GrGpu* gpu,
53 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com1c13c962011-02-14 16:51:21 +000054 GrIndexBufferAllocPool* indexPool);
reed@google.comac10a2d2010-12-22 21:39:39 +000055
56 virtual ~GrInOrderDrawBuffer();
57
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000058 /**
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000059 * Provides the buffer with an index buffer that can be used for quad rendering.
60 * The buffer may be able to batch consecutive drawRects if this is provided.
61 * @param indexBuffer index buffer with quad indices.
62 */
63 void setQuadIndexBuffer(const GrIndexBuffer* indexBuffer);
64
65 /**
bsalomon@google.com97805382012-03-13 14:32:07 +000066 * Empties the draw buffer of any queued up draws. This must not be called
67 * while inside an unbalanced pushGeometrySource().
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000068 */
69 void reset();
70
71 /**
bsalomon@google.com97805382012-03-13 14:32:07 +000072 * plays the queued up draws to another target. Does not empty this buffer
73 * so that it can be played back multiple times. This buffer must not have
74 * an active reserved vertex or index source. Any reserved geometry on
75 * the target will be finalized because it's geometry source will be pushed
76 * before playback and popped afterwards.
77 *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000078 * @return false if the playback trivially drew nothing because nothing was
79 * recorded.
80 *
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000081 * @param target the target to receive the playback
82 */
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000083 bool playback(GrDrawTarget* target);
bsalomon@google.com97805382012-03-13 14:32:07 +000084
85 /**
86 * A convenience method to do a playback followed by a reset. All the
87 * constraints and side-effects or playback() and reset apply().
88 */
89 void flushTo(GrDrawTarget* target) {
robertphillips@google.comc82a8b72012-06-21 20:15:48 +000090 if (fFlushing) {
91 // When creating SW-only clip masks, the GrClipMaskManager can
92 // cause a GrContext::flush (when copying the mask results back
93 // to the GPU). Without a guard this results in a recursive call
94 // to this method.
95 return;
96 }
97
98 fFlushing = true;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000099 if (this->playback(target)) {
100 this->reset();
101 }
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000102 fFlushing = false;
bsalomon@google.com97805382012-03-13 14:32:07 +0000103 }
104
105 /**
106 * This function allows the draw buffer to automatically flush itself to
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000107 * another target. This means the buffer may internally call
bsalomon@google.com97805382012-03-13 14:32:07 +0000108 * this->flushTo(target) when it is safe to do so.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000109 *
bsalomon@google.com97805382012-03-13 14:32:07 +0000110 * When the auto flush target is set to NULL (as it initially is) the draw
111 * buffer will never automatically flush itself.
112 */
113 void setAutoFlushTarget(GrDrawTarget* target);
114
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000115 // overrides from GrDrawTarget
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000116 virtual void drawRect(const GrRect& rect,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000117 const GrMatrix* matrix = NULL,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000118 const GrRect* srcRects[] = NULL,
bsalomon@google.com97805382012-03-13 14:32:07 +0000119 const GrMatrix* srcMatrices[] = NULL) SK_OVERRIDE;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000120
bsalomon@google.com934c5702012-03-20 21:17:58 +0000121 virtual void drawIndexedInstances(GrPrimitiveType type,
122 int instanceCount,
123 int verticesPerInstance,
124 int indicesPerInstance)
125 SK_OVERRIDE;
126
reed@google.comac10a2d2010-12-22 21:39:39 +0000127 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000128 int* vertexCount,
bsalomon@google.com97805382012-03-13 14:32:07 +0000129 int* indexCount) const SK_OVERRIDE;
reed@google.comac10a2d2010-12-22 21:39:39 +0000130
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000131 virtual void clear(const GrIRect* rect,
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000132 GrColor color,
133 GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000134
bsalomon@google.com97805382012-03-13 14:32:07 +0000135protected:
bsalomon@google.com97805382012-03-13 14:32:07 +0000136 virtual void willReserveVertexAndIndexSpace(GrVertexLayout vertexLayout,
137 int vertexCount,
138 int indexCount) SK_OVERRIDE;
reed@google.comac10a2d2010-12-22 21:39:39 +0000139private:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000140 enum Cmd {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000141 kDraw_Cmd = 1,
142 kStencilPath_Cmd = 2,
143 kSetState_Cmd = 3,
144 kSetClip_Cmd = 4,
145 kClear_Cmd = 5,
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000146 };
147
reed@google.comac10a2d2010-12-22 21:39:39 +0000148 struct Draw {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000149 GrPrimitiveType fPrimitiveType;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000150 int fStartVertex;
151 int fStartIndex;
152 int fVertexCount;
153 int fIndexCount;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000154 GrVertexLayout fVertexLayout;
155 const GrVertexBuffer* fVertexBuffer;
156 const GrIndexBuffer* fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000157 };
158
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000159 struct StencilPath {
160 SkAutoTUnref<const GrPath> fPath;
161 GrPathFill fFill;
162 };
163
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000164 struct Clear {
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000165 Clear() : fRenderTarget(NULL) {}
166 ~Clear() { GrSafeUnref(fRenderTarget); }
167
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000168 GrIRect fRect;
169 GrColor fColor;
170 GrRenderTarget* fRenderTarget;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000171 };
172
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000173 // overrides from GrDrawTarget
174 virtual void onDrawIndexed(GrPrimitiveType primitiveType,
175 int startVertex,
176 int startIndex,
177 int vertexCount,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000178 int indexCount) SK_OVERRIDE;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000179 virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
180 int startVertex,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000181 int vertexCount) SK_OVERRIDE;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000182 virtual void onStencilPath(const GrPath*, GrPathFill) SK_OVERRIDE;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000183 virtual bool onReserveVertexSpace(GrVertexLayout layout,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000184 int vertexCount,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000185 void** vertices) SK_OVERRIDE;
186 virtual bool onReserveIndexSpace(int indexCount,
187 void** indices) SK_OVERRIDE;
188 virtual void releaseReservedVertexSpace() SK_OVERRIDE;
189 virtual void releaseReservedIndexSpace() SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000190 virtual void onSetVertexSourceToArray(const void* vertexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000191 int vertexCount) SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000192 virtual void onSetIndexSourceToArray(const void* indexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000193 int indexCount) SK_OVERRIDE;
194 virtual void releaseVertexArray() SK_OVERRIDE;
195 virtual void releaseIndexArray() SK_OVERRIDE;
196 virtual void geometrySourceWillPush() SK_OVERRIDE;
197 virtual void geometrySourceWillPop(
198 const GeometrySrcState& restoredState) SK_OVERRIDE;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000199 virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000200
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000201 // we lazily record state and clip changes in order to skip clips and states
202 // that have no effect.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000203 bool needsNewState() const;
204 bool needsNewClip() const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000205
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000206 // these functions record a command
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000207 void recordState();
208 void recordDefaultState();
209 void recordClip();
210 void recordDefaultClip();
211 Draw* recordDraw();
212 StencilPath* recordStencilPath();
213 Clear* recordClear();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000214
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000215 // call this to invalidate the tracking data that is used to concatenate
bsalomon@google.com934c5702012-03-20 21:17:58 +0000216 // multiple draws into a single draw.
217 void resetDrawTracking();
218
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000219 enum {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000220 kCmdPreallocCnt = 32,
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000221 kDrawPreallocCnt = 8,
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000222 kStencilPathPreallocCnt = 8,
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000223 kStatePreallocCnt = 8,
224 kClipPreallocCnt = 8,
225 kClearPreallocCnt = 4,
226 kGeoPoolStatePreAllocCnt = 4,
227 };
reed@google.comac10a2d2010-12-22 21:39:39 +0000228
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000229 SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000230 GrSTAllocator<kDrawPreallocCnt, Draw> fDraws;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000231 GrSTAllocator<kStatePreallocCnt, StencilPath> fStencilPaths;
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000232 GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000233 GrSTAllocator<kClearPreallocCnt, Clear> fClears;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000234
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000235 GrSTAllocator<kClipPreallocCnt, SkClipStack> fClips;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000236 GrSTAllocator<kClipPreallocCnt, SkIPoint> fClipOrigins;
bsalomon@google.com97805382012-03-13 14:32:07 +0000237
238 GrDrawTarget* fAutoFlushTarget;
239
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000240 bool fClipSet;
241
bsalomon@google.com934c5702012-03-20 21:17:58 +0000242 GrVertexBufferAllocPool& fVertexPool;
243
244 GrIndexBufferAllocPool& fIndexPool;
245
246 // these are used to attempt to concatenate drawRect calls
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000247 GrVertexLayout fLastRectVertexLayout;
248 const GrIndexBuffer* fQuadIndexBuffer;
249 int fMaxQuads;
250 int fCurrQuad;
reed@google.comac10a2d2010-12-22 21:39:39 +0000251
bsalomon@google.com934c5702012-03-20 21:17:58 +0000252 // bookkeeping to attempt to concantenate drawIndexedInstances calls
253 struct {
254 int fVerticesPerInstance;
255 int fIndicesPerInstance;
256 void reset() {
257 fVerticesPerInstance = 0;
258 fIndicesPerInstance = 0;
259 }
260 } fInstancedDrawTracker;
bsalomon@google.com92669012011-09-27 19:10:05 +0000261
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000262 struct GeometryPoolState {
263 const GrVertexBuffer* fPoolVertexBuffer;
264 int fPoolStartVertex;
265 const GrIndexBuffer* fPoolIndexBuffer;
266 int fPoolStartIndex;
267 // caller may conservatively over reserve vertices / indices.
268 // we release unused space back to allocator if possible
269 // can only do this if there isn't an intervening pushGeometrySource()
270 size_t fUsedPoolVertexBytes;
271 size_t fUsedPoolIndexBytes;
272 };
bsalomon@google.com92669012011-09-27 19:10:05 +0000273 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
reed@google.comac10a2d2010-12-22 21:39:39 +0000274
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000275 bool fFlushing;
276
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000277 typedef GrDrawTarget INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000278};
279
280#endif