blob: 20f0c84583cf84ddc056cbcf6c9f3dc24964d402 [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.com12b4e272012-12-06 20:13:11 +000020#include "SkStroke.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 {
161 SkAutoTUnref<const GrPath> fPath;
sugoi@google.com12b4e272012-12-06 20:13:11 +0000162 SkStroke fStroke;
163 SkPath::FillType fFill;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000164 };
165
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000166 struct Clear {
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000167 Clear() : fRenderTarget(NULL) {}
168 ~Clear() { GrSafeUnref(fRenderTarget); }
169
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000170 GrIRect fRect;
171 GrColor fColor;
172 GrRenderTarget* fRenderTarget;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000173 };
174
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000175 // overrides from GrDrawTarget
176 virtual void onDrawIndexed(GrPrimitiveType primitiveType,
177 int startVertex,
178 int startIndex,
179 int vertexCount,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000180 int indexCount) SK_OVERRIDE;
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000181 virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
182 int startVertex,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000183 int vertexCount) SK_OVERRIDE;
sugoi@google.com12b4e272012-12-06 20:13:11 +0000184 virtual void onStencilPath(const GrPath*, const SkStroke& stroke, SkPath::FillType) SK_OVERRIDE;
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000185 virtual bool onReserveVertexSpace(GrVertexLayout layout,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000186 int vertexCount,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000187 void** vertices) SK_OVERRIDE;
188 virtual bool onReserveIndexSpace(int indexCount,
189 void** indices) SK_OVERRIDE;
190 virtual void releaseReservedVertexSpace() SK_OVERRIDE;
191 virtual void releaseReservedIndexSpace() SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000192 virtual void onSetVertexSourceToArray(const void* vertexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000193 int vertexCount) SK_OVERRIDE;
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000194 virtual void onSetIndexSourceToArray(const void* indexArray,
bsalomon@google.com13f1b6f2012-05-31 12:52:43 +0000195 int indexCount) SK_OVERRIDE;
196 virtual void releaseVertexArray() SK_OVERRIDE;
197 virtual void releaseIndexArray() SK_OVERRIDE;
198 virtual void geometrySourceWillPush() SK_OVERRIDE;
199 virtual void geometrySourceWillPop(
200 const GeometrySrcState& restoredState) SK_OVERRIDE;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000201 virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000202
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000203 // we lazily record state and clip changes in order to skip clips and states
204 // that have no effect.
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000205 bool needsNewState() const;
206 bool needsNewClip() const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000207
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000208 // these functions record a command
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000209 void recordState();
210 void recordDefaultState();
211 void recordClip();
212 void recordDefaultClip();
213 Draw* recordDraw();
214 StencilPath* recordStencilPath();
215 Clear* recordClear();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000216
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000217 // call this to invalidate the tracking data that is used to concatenate
bsalomon@google.com934c5702012-03-20 21:17:58 +0000218 // multiple draws into a single draw.
219 void resetDrawTracking();
220
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000221 enum {
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000222 kCmdPreallocCnt = 32,
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000223 kDrawPreallocCnt = 8,
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000224 kStencilPathPreallocCnt = 8,
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000225 kStatePreallocCnt = 8,
226 kClipPreallocCnt = 8,
227 kClearPreallocCnt = 4,
228 kGeoPoolStatePreAllocCnt = 4,
229 };
reed@google.comac10a2d2010-12-22 21:39:39 +0000230
bsalomon@google.coma4f6b102012-06-26 21:04:22 +0000231 SkSTArray<kCmdPreallocCnt, uint8_t, true> fCmds;
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000232 GrSTAllocator<kDrawPreallocCnt, Draw> fDraws;
bsalomon@google.comded4f4b2012-06-28 18:48:06 +0000233 GrSTAllocator<kStatePreallocCnt, StencilPath> fStencilPaths;
bsalomon@google.com873ea0c2012-03-30 15:55:32 +0000234 GrSTAllocator<kStatePreallocCnt, GrDrawState> fStates;
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000235 GrSTAllocator<kClearPreallocCnt, Clear> fClears;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000236
robertphillips@google.com641f8b12012-07-31 19:15:58 +0000237 GrSTAllocator<kClipPreallocCnt, SkClipStack> fClips;
robertphillips@google.combeb1af72012-07-26 18:52:16 +0000238 GrSTAllocator<kClipPreallocCnt, SkIPoint> fClipOrigins;
bsalomon@google.com97805382012-03-13 14:32:07 +0000239
240 GrDrawTarget* fAutoFlushTarget;
241
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000242 bool fClipSet;
243
bsalomon@google.com934c5702012-03-20 21:17:58 +0000244 GrVertexBufferAllocPool& fVertexPool;
245
246 GrIndexBufferAllocPool& fIndexPool;
247
248 // these are used to attempt to concatenate drawRect calls
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000249 GrVertexLayout fLastRectVertexLayout;
250 const GrIndexBuffer* fQuadIndexBuffer;
251 int fMaxQuads;
252 int fCurrQuad;
reed@google.comac10a2d2010-12-22 21:39:39 +0000253
bsalomon@google.com934c5702012-03-20 21:17:58 +0000254 // bookkeeping to attempt to concantenate drawIndexedInstances calls
255 struct {
256 int fVerticesPerInstance;
257 int fIndicesPerInstance;
258 void reset() {
259 fVerticesPerInstance = 0;
260 fIndicesPerInstance = 0;
261 }
262 } fInstancedDrawTracker;
bsalomon@google.com92669012011-09-27 19:10:05 +0000263
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000264 struct GeometryPoolState {
265 const GrVertexBuffer* fPoolVertexBuffer;
266 int fPoolStartVertex;
267 const GrIndexBuffer* fPoolIndexBuffer;
268 int fPoolStartIndex;
269 // caller may conservatively over reserve vertices / indices.
270 // we release unused space back to allocator if possible
271 // can only do this if there isn't an intervening pushGeometrySource()
272 size_t fUsedPoolVertexBytes;
273 size_t fUsedPoolIndexBytes;
274 };
bsalomon@google.com92669012011-09-27 19:10:05 +0000275 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
reed@google.comac10a2d2010-12-22 21:39:39 +0000276
robertphillips@google.comc82a8b72012-06-21 20:15:48 +0000277 bool fFlushing;
278
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000279 typedef GrDrawTarget INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000280};
281
282#endif