blob: 61fa9e2a86df89d8029382ce3bd49528658861ab [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"
17#include "GrClip.h"
18
bsalomon@google.com471d4712011-08-23 15:45:25 +000019class GrGpu;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000020class GrIndexBufferAllocPool;
bsalomon@google.com471d4712011-08-23 15:45:25 +000021class GrVertexBufferAllocPool;
reed@google.comac10a2d2010-12-22 21:39:39 +000022
bsalomon@google.com1c13c962011-02-14 16:51:21 +000023/**
24 * GrInOrderDrawBuffer is an implementation of GrDrawTarget that queues up
25 * draws for eventual playback into a GrGpu. In theory one draw buffer could
26 * playback into another. When index or vertex buffers are used as geometry
27 * sources it is the callers the draw buffer only holds references to the
28 * 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
30 * caller's responsibility to ensure that all referenced textures, buffers,
31 * and rendertargets are associated in the GrGpu object that the buffer is
32 * played back into. The buffer requires VB and IB pools to store geometry.
33 */
34
reed@google.comac10a2d2010-12-22 21:39:39 +000035class GrInOrderDrawBuffer : public GrDrawTarget {
36public:
37
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000038 /**
39 * Creates a GrInOrderDrawBuffer
40 *
bsalomon@google.com471d4712011-08-23 15:45:25 +000041 * @param gpu the gpu object where this will be played back
42 * (possible indirectly). GrResources used with the draw
43 * buffer are created by this gpu object.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000044 * @param vertexPool pool where vertices for queued draws will be saved when
45 * the vertex source is either reserved or array.
46 * @param indexPool pool where indices for queued draws will be saved when
47 * the index source is either reserved or array.
48 */
bsalomon@google.com471d4712011-08-23 15:45:25 +000049 GrInOrderDrawBuffer(const GrGpu* gpu,
50 GrVertexBufferAllocPool* vertexPool,
bsalomon@google.com1c13c962011-02-14 16:51:21 +000051 GrIndexBufferAllocPool* indexPool);
reed@google.comac10a2d2010-12-22 21:39:39 +000052
53 virtual ~GrInOrderDrawBuffer();
54
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000055 /**
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000056 * Provides the buffer with an index buffer that can be used for quad rendering.
57 * The buffer may be able to batch consecutive drawRects if this is provided.
58 * @param indexBuffer index buffer with quad indices.
59 */
60 void setQuadIndexBuffer(const GrIndexBuffer* indexBuffer);
61
62 /**
bsalomon@google.com97805382012-03-13 14:32:07 +000063 * Empties the draw buffer of any queued up draws. This must not be called
64 * while inside an unbalanced pushGeometrySource().
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000065 */
66 void reset();
67
68 /**
bsalomon@google.com97805382012-03-13 14:32:07 +000069 * plays the queued up draws to another target. Does not empty this buffer
70 * so that it can be played back multiple times. This buffer must not have
71 * an active reserved vertex or index source. Any reserved geometry on
72 * the target will be finalized because it's geometry source will be pushed
73 * before playback and popped afterwards.
74 *
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000075 * @return false if the playback trivially drew nothing because nothing was
76 * recorded.
77 *
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000078 * @param target the target to receive the playback
79 */
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000080 bool playback(GrDrawTarget* target);
bsalomon@google.com97805382012-03-13 14:32:07 +000081
82 /**
83 * A convenience method to do a playback followed by a reset. All the
84 * constraints and side-effects or playback() and reset apply().
85 */
86 void flushTo(GrDrawTarget* target) {
robertphillips@google.comc82a8b72012-06-21 20:15:48 +000087 if (fFlushing) {
88 // When creating SW-only clip masks, the GrClipMaskManager can
89 // cause a GrContext::flush (when copying the mask results back
90 // to the GPU). Without a guard this results in a recursive call
91 // to this method.
92 return;
93 }
94
95 fFlushing = true;
bsalomon@google.coma4f6b102012-06-26 21:04:22 +000096 if (this->playback(target)) {
97 this->reset();
98 }
robertphillips@google.comc82a8b72012-06-21 20:15:48 +000099 fFlushing = false;
bsalomon@google.com97805382012-03-13 14:32:07 +0000100 }
101
102 /**
103 * This function allows the draw buffer to automatically flush itself to
104 * another target. This means the buffer may internally call
105 * this->flushTo(target) when it is safe to do so.
106 *
107 * When the auto flush target is set to NULL (as it initially is) the draw
108 * buffer will never automatically flush itself.
109 */
110 void setAutoFlushTarget(GrDrawTarget* target);
111
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000112 // overrides from GrDrawTarget
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000113 virtual void drawRect(const GrRect& rect,
114 const GrMatrix* matrix = NULL,
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +0000115 StageMask stageEnableMask = 0,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000116 const GrRect* srcRects[] = NULL,
bsalomon@google.com97805382012-03-13 14:32:07 +0000117 const GrMatrix* srcMatrices[] = NULL) SK_OVERRIDE;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000118
bsalomon@google.com934c5702012-03-20 21:17:58 +0000119 virtual void drawIndexedInstances(GrPrimitiveType type,
120 int instanceCount,
121 int verticesPerInstance,
122 int indicesPerInstance)
123 SK_OVERRIDE;
124
reed@google.comac10a2d2010-12-22 21:39:39 +0000125 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000126 int* vertexCount,
bsalomon@google.com97805382012-03-13 14:32:07 +0000127 int* indexCount) const SK_OVERRIDE;
reed@google.comac10a2d2010-12-22 21:39:39 +0000128
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000129 virtual void clear(const GrIRect* rect,
130 GrColor color,
131 GrRenderTarget* renderTarget = NULL) SK_OVERRIDE;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000132
bsalomon@google.com97805382012-03-13 14:32:07 +0000133protected:
bsalomon@google.com97805382012-03-13 14:32:07 +0000134 virtual void willReserveVertexAndIndexSpace(GrVertexLayout vertexLayout,
135 int vertexCount,
136 int indexCount) SK_OVERRIDE;
reed@google.comac10a2d2010-12-22 21:39:39 +0000137private:
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000138 enum Cmd {
139 kDraw_Cmd = 1,
140 kSetState_Cmd = 2,
141 kSetClip_Cmd = 3,
142 kClear_Cmd = 4,
143 };
144
reed@google.comac10a2d2010-12-22 21:39:39 +0000145 struct Draw {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000146 GrPrimitiveType fPrimitiveType;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000147 int fStartVertex;
148 int fStartIndex;
149 int fVertexCount;
150 int fIndexCount;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000151 GrVertexLayout fVertexLayout;
152 const GrVertexBuffer* fVertexBuffer;
153 const GrIndexBuffer* fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000154 };
155
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000156 struct Clear {
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000157 Clear() : fRenderTarget(NULL) {}
158 ~Clear() { GrSafeUnref(fRenderTarget); }
159
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000160 GrIRect fRect;
161 GrColor fColor;
162 GrRenderTarget* fRenderTarget;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000163 };
164
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000165 // overrides from GrDrawTarget
166 virtual void onDrawIndexed(GrPrimitiveType primitiveType,
167 int startVertex,
168 int startIndex,
169 int vertexCount,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000170 int indexCount) SK_OVERRIDE;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000171 virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
172 int startVertex,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000173 int vertexCount) SK_OVERRIDE;
bsalomon@google.com64aef2b2012-06-11 15:36:13 +0000174 virtual void onStencilPath(const GrPath&, GrPathFill) SK_OVERRIDE;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000175 virtual bool onReserveVertexSpace(GrVertexLayout layout,
176 int vertexCount,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000177 void** vertices) SK_OVERRIDE;
178 virtual bool onReserveIndexSpace(int indexCount,
179 void** indices) SK_OVERRIDE;
180 virtual void releaseReservedVertexSpace() SK_OVERRIDE;
181 virtual void releaseReservedIndexSpace() SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000182 virtual void onSetVertexSourceToArray(const void* vertexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000183 int vertexCount) SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000184 virtual void onSetIndexSourceToArray(const void* indexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000185 int indexCount) SK_OVERRIDE;
186 virtual void releaseVertexArray() SK_OVERRIDE;
187 virtual void releaseIndexArray() SK_OVERRIDE;
188 virtual void geometrySourceWillPush() SK_OVERRIDE;
189 virtual void geometrySourceWillPop(
190 const GeometrySrcState& restoredState) SK_OVERRIDE;
191 virtual void clipWillBeSet(const GrClip& newClip) SK_OVERRIDE;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000192
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000193 // we lazily record state and clip changes in order to skip clips and states
194 // that have no effect.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000195 bool needsNewState() const;
196 bool needsNewClip() const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000197
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000198 // these functions record a command
199 void recordState();
200 void recordDefaultState();
201 void recordClip();
202 void recordDefaultClip();
203 Draw* recordDraw();
204 Clear* recordClear();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000205
206 // call this to invalidate the tracking data that is used to concatenate
207 // multiple draws into a single draw.
208 void resetDrawTracking();
209
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000210 enum {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000211 kCmdPreallocCnt = 32,
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000212 kDrawPreallocCnt = 8,
213 kStatePreallocCnt = 8,
214 kClipPreallocCnt = 8,
215 kClearPreallocCnt = 4,
216 kGeoPoolStatePreAllocCnt = 4,
217 };
reed@google.comac10a2d2010-12-22 21:39:39 +0000218
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000219 SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000220 GrSTAllocator<kDrawPreallocCnt, Draw> fDraws;
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000221 GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000222 GrSTAllocator<kClearPreallocCnt, Clear> fClears;
223 GrSTAllocator<kClipPreallocCnt, GrClip> fClips;
bsalomon@google.com97805382012-03-13 14:32:07 +0000224
225 GrDrawTarget* fAutoFlushTarget;
226
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000227 bool fClipSet;
228
bsalomon@google.com934c5702012-03-20 21:17:58 +0000229 GrVertexBufferAllocPool& fVertexPool;
230
231 GrIndexBufferAllocPool& fIndexPool;
232
233 // these are used to attempt to concatenate drawRect calls
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000234 GrVertexLayout fLastRectVertexLayout;
235 const GrIndexBuffer* fQuadIndexBuffer;
236 int fMaxQuads;
237 int fCurrQuad;
reed@google.comac10a2d2010-12-22 21:39:39 +0000238
bsalomon@google.com934c5702012-03-20 21:17:58 +0000239 // bookkeeping to attempt to concantenate drawIndexedInstances calls
240 struct {
241 int fVerticesPerInstance;
242 int fIndicesPerInstance;
243 void reset() {
244 fVerticesPerInstance = 0;
245 fIndicesPerInstance = 0;
246 }
247 } fInstancedDrawTracker;
bsalomon@google.com92669012011-09-27 19:10:05 +0000248
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000249 struct GeometryPoolState {
250 const GrVertexBuffer* fPoolVertexBuffer;
251 int fPoolStartVertex;
252 const GrIndexBuffer* fPoolIndexBuffer;
253 int fPoolStartIndex;
254 // caller may conservatively over reserve vertices / indices.
255 // we release unused space back to allocator if possible
256 // can only do this if there isn't an intervening pushGeometrySource()
257 size_t fUsedPoolVertexBytes;
258 size_t fUsedPoolIndexBytes;
259 };
bsalomon@google.com92669012011-09-27 19:10:05 +0000260 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
reed@google.comac10a2d2010-12-22 21:39:39 +0000261
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000262 bool fFlushing;
263
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000264 typedef GrDrawTarget INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000265};
266
267#endif