blob: 17271f8c84623aa3cb936509d89aa01e2094f2c2 [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/**
28 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up
29 * draws for eventual playback into a GrGpu. In theory one draw buffer could
30 * playback into another. When index or vertex buffers are used as geometry
31 * sources it is the callers the draw buffer only holds references to the
32 * buffers. It is the callers responsibility to ensure that the data is still
33 * valid when the draw buffer is played back into a GrGpu. Similarly, it is the
34 * caller's responsibility to ensure that all referenced textures, buffers,
35 * and rendertargets are associated in the GrGpu object that the buffer is
36 * played back into. The buffer requires VB and IB pools to store geometry.
37 */
38
reed@google.comac10a2d2010-12-22 21:39:39 +000039class GrInOrderDrawBuffer : public GrDrawTarget {
40public:
41
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000042 /**
43 * Creates a GrInOrderDrawBuffer
44 *
bsalomon@google.com471d4712011-08-23 15:45:25 +000045 * @param gpu the gpu object where this will be played back
46 * (possible indirectly). GrResources used with the draw
47 * buffer are created by this gpu object.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000048 * @param vertexPool pool where vertices for queued draws will be saved when
49 * the vertex source is either reserved or array.
50 * @param indexPool pool where indices for queued draws will be saved when
51 * the index source is either reserved or array.
52 */
bsalomon@google.com471d4712011-08-23 15:45:25 +000053 GrInOrderDrawBuffer(const GrGpu* gpu,
54 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com1c13c962011-02-14 16:51:21 +000055 GrIndexBufferAllocPool* indexPool);
reed@google.comac10a2d2010-12-22 21:39:39 +000056
57 virtual ~GrInOrderDrawBuffer();
58
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000059 /**
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000060 * Provides the buffer with an index buffer that can be used for quad rendering.
61 * The buffer may be able to batch consecutive drawRects if this is provided.
62 * @param indexBuffer index buffer with quad indices.
63 */
64 void setQuadIndexBuffer(const GrIndexBuffer* indexBuffer);
65
66 /**
bsalomon@google.com97805382012-03-13 14:32:07 +000067 * Empties the draw buffer of any queued up draws. This must not be called
68 * while inside an unbalanced pushGeometrySource().
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000069 */
70 void reset();
71
72 /**
bsalomon@google.com97805382012-03-13 14:32:07 +000073 * plays the queued up draws to another target. Does not empty this buffer
74 * so that it can be played back multiple times. This buffer must not have
75 * an active reserved vertex or index source. Any reserved geometry on
76 * the target will be finalized because it's geometry source will be pushed
77 * before playback and popped afterwards.
78 *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000079 * @return false if the playback trivially drew nothing because nothing was
80 * recorded.
81 *
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000082 * @param target the target to receive the playback
83 */
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000084 bool playback(GrDrawTarget* target);
bsalomon@google.com97805382012-03-13 14:32:07 +000085
86 /**
87 * A convenience method to do a playback followed by a reset. All the
88 * constraints and side-effects or playback() and reset apply().
89 */
90 void flushTo(GrDrawTarget* target) {
robertphillips@google.comc82a8b72012-06-21 20:15:48 +000091 if (fFlushing) {
92 // When creating SW-only clip masks, the GrClipMaskManager can
93 // cause a GrContext::flush (when copying the mask results back
94 // to the GPU). Without a guard this results in a recursive call
95 // to this method.
96 return;
97 }
98
99 fFlushing = true;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000100 if (this->playback(target)) {
101 this->reset();
102 }
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000103 fFlushing = false;
bsalomon@google.com97805382012-03-13 14:32:07 +0000104 }
105
106 /**
107 * This function allows the draw buffer to automatically flush itself to
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000108 * another target. This means the buffer may internally call
bsalomon@google.com97805382012-03-13 14:32:07 +0000109 * this->flushTo(target) when it is safe to do so.
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000110 *
bsalomon@google.com97805382012-03-13 14:32:07 +0000111 * When the auto flush target is set to NULL (as it initially is) the draw
112 * buffer will never automatically flush itself.
113 */
114 void setAutoFlushTarget(GrDrawTarget* target);
115
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000116 // overrides from GrDrawTarget
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000117 virtual void drawRect(const GrRect& rect,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000118 const SkMatrix* matrix = NULL,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000119 const GrRect* srcRects[] = NULL,
bsalomon@google.comb9086a02012-11-01 18:02:54 +0000120 const SkMatrix* srcMatrices[] = NULL) SK_OVERRIDE;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000121
bsalomon@google.com934c5702012-03-20 21:17:58 +0000122 virtual void drawIndexedInstances(GrPrimitiveType type,
123 int instanceCount,
124 int verticesPerInstance,
125 int indicesPerInstance)
126 SK_OVERRIDE;
127
reed@google.comac10a2d2010-12-22 21:39:39 +0000128 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000129 int* vertexCount,
bsalomon@google.com97805382012-03-13 14:32:07 +0000130 int* indexCount) const SK_OVERRIDE;
reed@google.comac10a2d2010-12-22 21:39:39 +0000131
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000132 virtual void clear(const GrIRect* rect,
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000133 GrColor color,
134 GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000135
bsalomon@google.com97805382012-03-13 14:32:07 +0000136protected:
bsalomon@google.com97805382012-03-13 14:32:07 +0000137 virtual void willReserveVertexAndIndexSpace(GrVertexLayout vertexLayout,
138 int vertexCount,
139 int indexCount) SK_OVERRIDE;
reed@google.comac10a2d2010-12-22 21:39:39 +0000140private:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000141 enum Cmd {
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000142 kDraw_Cmd = 1,
143 kStencilPath_Cmd = 2,
144 kSetState_Cmd = 3,
145 kSetClip_Cmd = 4,
146 kClear_Cmd = 5,
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000147 };
148
reed@google.comac10a2d2010-12-22 21:39:39 +0000149 struct Draw {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000150 GrPrimitiveType fPrimitiveType;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000151 int fStartVertex;
152 int fStartIndex;
153 int fVertexCount;
154 int fIndexCount;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000155 GrVertexLayout fVertexLayout;
156 const GrVertexBuffer* fVertexBuffer;
157 const GrIndexBuffer* fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000158 };
159
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000160 struct StencilPath {
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000161 StencilPath();
162
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000163 SkAutoTUnref<const GrPath> fPath;
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000164 SkStrokeRec fStroke;
sugoi@google.com12b4e272012-12-06 20:13:11 +0000165 SkPath::FillType fFill;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000166 };
167
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000168 struct Clear {
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000169 Clear() : fRenderTarget(NULL) {}
170 ~Clear() { GrSafeUnref(fRenderTarget); }
171
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000172 GrIRect fRect;
173 GrColor fColor;
174 GrRenderTarget* fRenderTarget;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000175 };
176
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000177 // overrides from GrDrawTarget
178 virtual void onDrawIndexed(GrPrimitiveType primitiveType,
179 int startVertex,
180 int startIndex,
181 int vertexCount,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000182 int indexCount) SK_OVERRIDE;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000183 virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
184 int startVertex,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000185 int vertexCount) SK_OVERRIDE;
sugoi@google.com5f74cf82012-12-17 21:16:45 +0000186 virtual void onStencilPath(const GrPath*, const SkStrokeRec& stroke, SkPath::FillType) SK_OVERRIDE;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000187 virtual bool onReserveVertexSpace(GrVertexLayout layout,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000188 int vertexCount,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000189 void** vertices) SK_OVERRIDE;
190 virtual bool onReserveIndexSpace(int indexCount,
191 void** indices) SK_OVERRIDE;
192 virtual void releaseReservedVertexSpace() SK_OVERRIDE;
193 virtual void releaseReservedIndexSpace() SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000194 virtual void onSetVertexSourceToArray(const void* vertexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000195 int vertexCount) SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000196 virtual void onSetIndexSourceToArray(const void* indexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000197 int indexCount) SK_OVERRIDE;
198 virtual void releaseVertexArray() SK_OVERRIDE;
199 virtual void releaseIndexArray() SK_OVERRIDE;
200 virtual void geometrySourceWillPush() SK_OVERRIDE;
201 virtual void geometrySourceWillPop(
202 const GeometrySrcState& restoredState) SK_OVERRIDE;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000203 virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000204
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000205 // we lazily record state and clip changes in order to skip clips and states
206 // that have no effect.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000207 bool needsNewState() const;
208 bool needsNewClip() const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000209
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000210 // these functions record a command
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000211 void recordState();
212 void recordDefaultState();
213 void recordClip();
214 void recordDefaultClip();
215 Draw* recordDraw();
216 StencilPath* recordStencilPath();
217 Clear* recordClear();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000218
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000219 // call this to invalidate the tracking data that is used to concatenate
bsalomon@google.com934c5702012-03-20 21:17:58 +0000220 // multiple draws into a single draw.
221 void resetDrawTracking();
222
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000223 enum {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000224 kCmdPreallocCnt = 32,
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000225 kDrawPreallocCnt = 8,
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000226 kStencilPathPreallocCnt = 8,
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000227 kStatePreallocCnt = 8,
228 kClipPreallocCnt = 8,
229 kClearPreallocCnt = 4,
230 kGeoPoolStatePreAllocCnt = 4,
231 };
reed@google.comac10a2d2010-12-22 21:39:39 +0000232
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000233 SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000234 GrSTAllocator<kDrawPreallocCnt, Draw> fDraws;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000235 GrSTAllocator<kStatePreallocCnt, StencilPath> fStencilPaths;
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000236 GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000237 GrSTAllocator<kClearPreallocCnt, Clear> fClears;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000238
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000239 GrSTAllocator<kClipPreallocCnt, SkClipStack> fClips;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000240 GrSTAllocator<kClipPreallocCnt, SkIPoint> fClipOrigins;
bsalomon@google.com97805382012-03-13 14:32:07 +0000241
242 GrDrawTarget* fAutoFlushTarget;
243
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000244 bool fClipSet;
245
bsalomon@google.com934c5702012-03-20 21:17:58 +0000246 GrVertexBufferAllocPool& fVertexPool;
247
248 GrIndexBufferAllocPool& fIndexPool;
249
250 // these are used to attempt to concatenate drawRect calls
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000251 GrVertexLayout fLastRectVertexLayout;
252 const GrIndexBuffer* fQuadIndexBuffer;
253 int fMaxQuads;
254 int fCurrQuad;
reed@google.comac10a2d2010-12-22 21:39:39 +0000255
bsalomon@google.com934c5702012-03-20 21:17:58 +0000256 // bookkeeping to attempt to concantenate drawIndexedInstances calls
257 struct {
258 int fVerticesPerInstance;
259 int fIndicesPerInstance;
260 void reset() {
261 fVerticesPerInstance = 0;
262 fIndicesPerInstance = 0;
263 }
264 } fInstancedDrawTracker;
bsalomon@google.com92669012011-09-27 19:10:05 +0000265
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000266 struct GeometryPoolState {
267 const GrVertexBuffer* fPoolVertexBuffer;
268 int fPoolStartVertex;
269 const GrIndexBuffer* fPoolIndexBuffer;
270 int fPoolStartIndex;
271 // caller may conservatively over reserve vertices / indices.
272 // we release unused space back to allocator if possible
273 // can only do this if there isn't an intervening pushGeometrySource()
274 size_t fUsedPoolVertexBytes;
275 size_t fUsedPoolIndexBytes;
276 };
bsalomon@google.com92669012011-09-27 19:10:05 +0000277 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
reed@google.comac10a2d2010-12-22 21:39:39 +0000278
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000279 bool fFlushing;
280
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000281 typedef GrDrawTarget INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000282};
283
284#endif