blob: a0880d247c8cc666ed7fe17cd99c709c2ea14b6b [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 /**
56 * Copies the draw state and clip from target to this draw buffer.
57 *
58 * @param target the target whose clip and state should be copied.
59 */
reed@google.comac10a2d2010-12-22 21:39:39 +000060 void initializeDrawStateAndClip(const GrDrawTarget& target);
61
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000062 /**
63 * Provides the buffer with an index buffer that can be used for quad rendering.
64 * The buffer may be able to batch consecutive drawRects if this is provided.
65 * @param indexBuffer index buffer with quad indices.
66 */
67 void setQuadIndexBuffer(const GrIndexBuffer* indexBuffer);
68
69 /**
bsalomon@google.com97805382012-03-13 14:32:07 +000070 * Empties the draw buffer of any queued up draws. This must not be called
71 * while inside an unbalanced pushGeometrySource().
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000072 */
73 void reset();
74
75 /**
bsalomon@google.com97805382012-03-13 14:32:07 +000076 * plays the queued up draws to another target. Does not empty this buffer
77 * so that it can be played back multiple times. This buffer must not have
78 * an active reserved vertex or index source. Any reserved geometry on
79 * the target will be finalized because it's geometry source will be pushed
80 * before playback and popped afterwards.
81 *
bsalomon@google.com86afc2a2011-02-16 16:12:19 +000082 * @param target the target to receive the playback
83 */
84 void 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) {
91 this->playback(target);
92 this->reset();
93 }
94
95 /**
96 * This function allows the draw buffer to automatically flush itself to
97 * another target. This means the buffer may internally call
98 * this->flushTo(target) when it is safe to do so.
99 *
100 * When the auto flush target is set to NULL (as it initially is) the draw
101 * buffer will never automatically flush itself.
102 */
103 void setAutoFlushTarget(GrDrawTarget* target);
104
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000105 // overrides from GrDrawTarget
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000106 virtual void drawRect(const GrRect& rect,
107 const GrMatrix* matrix = NULL,
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +0000108 StageMask stageEnableMask = 0,
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000109 const GrRect* srcRects[] = NULL,
bsalomon@google.com97805382012-03-13 14:32:07 +0000110 const GrMatrix* srcMatrices[] = NULL) SK_OVERRIDE;
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000111
bsalomon@google.com934c5702012-03-20 21:17:58 +0000112 virtual void drawIndexedInstances(GrPrimitiveType type,
113 int instanceCount,
114 int verticesPerInstance,
115 int indicesPerInstance)
116 SK_OVERRIDE;
117
reed@google.comac10a2d2010-12-22 21:39:39 +0000118 virtual bool geometryHints(GrVertexLayout vertexLayout,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000119 int* vertexCount,
bsalomon@google.com97805382012-03-13 14:32:07 +0000120 int* indexCount) const SK_OVERRIDE;
reed@google.comac10a2d2010-12-22 21:39:39 +0000121
bsalomon@google.com97805382012-03-13 14:32:07 +0000122 virtual void clear(const GrIRect* rect, GrColor color) SK_OVERRIDE;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000123
bsalomon@google.com97805382012-03-13 14:32:07 +0000124protected:
bsalomon@google.com97805382012-03-13 14:32:07 +0000125 virtual void willReserveVertexAndIndexSpace(GrVertexLayout vertexLayout,
126 int vertexCount,
127 int indexCount) SK_OVERRIDE;
reed@google.comac10a2d2010-12-22 21:39:39 +0000128private:
reed@google.comac10a2d2010-12-22 21:39:39 +0000129 struct Draw {
bsalomon@google.comffca4002011-02-22 20:34:01 +0000130 GrPrimitiveType fPrimitiveType;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000131 int fStartVertex;
132 int fStartIndex;
133 int fVertexCount;
134 int fIndexCount;
135 bool fStateChanged;
136 bool fClipChanged;
137 GrVertexLayout fVertexLayout;
138 const GrVertexBuffer* fVertexBuffer;
139 const GrIndexBuffer* fIndexBuffer;
reed@google.comac10a2d2010-12-22 21:39:39 +0000140 };
141
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000142 struct Clear {
143 int fBeforeDrawIdx;
bsalomon@google.com6aa25c32011-04-27 19:55:29 +0000144 GrIRect fRect;
bsalomon@google.com0b335c12011-04-25 19:17:44 +0000145 GrColor fColor;
146 };
147
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000148 // overrides from GrDrawTarget
149 virtual void onDrawIndexed(GrPrimitiveType primitiveType,
150 int startVertex,
151 int startIndex,
152 int vertexCount,
153 int indexCount);
154 virtual void onDrawNonIndexed(GrPrimitiveType primitiveType,
155 int startVertex,
156 int vertexCount);
157 virtual bool onReserveVertexSpace(GrVertexLayout layout,
158 int vertexCount,
159 void** vertices);
160 virtual bool onReserveIndexSpace(int indexCount, void** indices);
161 virtual void releaseReservedVertexSpace();
162 virtual void releaseReservedIndexSpace();
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000163 virtual void onSetVertexSourceToArray(const void* vertexArray,
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000164 int vertexCount);
bsalomon@google.combcdbbe62011-04-12 15:40:00 +0000165 virtual void onSetIndexSourceToArray(const void* indexArray,
166 int indexCount);
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000167 virtual void releaseVertexArray();
168 virtual void releaseIndexArray();
169 virtual void geometrySourceWillPush();
170 virtual void geometrySourceWillPop(const GeometrySrcState& restoredState);
171 virtual void clipWillBeSet(const GrClip& newClip);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000172
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000173 bool needsNewState() const;
174 bool needsNewClip() const;
reed@google.comac10a2d2010-12-22 21:39:39 +0000175
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000176 void pushState();
177 void pushClip();
bsalomon@google.com934c5702012-03-20 21:17:58 +0000178
179 // call this to invalidate the tracking data that is used to concatenate
180 // multiple draws into a single draw.
181 void resetDrawTracking();
182
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000183 enum {
184 kDrawPreallocCnt = 8,
185 kStatePreallocCnt = 8,
186 kClipPreallocCnt = 8,
187 kClearPreallocCnt = 4,
188 kGeoPoolStatePreAllocCnt = 4,
189 };
reed@google.comac10a2d2010-12-22 21:39:39 +0000190
bsalomon@google.com4b90c622011-09-28 17:52:15 +0000191 GrSTAllocator<kDrawPreallocCnt, Draw> fDraws;
192 GrSTAllocator<kStatePreallocCnt, SavedDrawState> fStates;
193 GrSTAllocator<kClearPreallocCnt, Clear> fClears;
194 GrSTAllocator<kClipPreallocCnt, GrClip> fClips;
bsalomon@google.com97805382012-03-13 14:32:07 +0000195
196 GrDrawTarget* fAutoFlushTarget;
197
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000198 bool fClipSet;
199
bsalomon@google.com934c5702012-03-20 21:17:58 +0000200 GrVertexBufferAllocPool& fVertexPool;
201
202 GrIndexBufferAllocPool& fIndexPool;
203
204 // these are used to attempt to concatenate drawRect calls
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000205 GrVertexLayout fLastRectVertexLayout;
206 const GrIndexBuffer* fQuadIndexBuffer;
207 int fMaxQuads;
208 int fCurrQuad;
reed@google.comac10a2d2010-12-22 21:39:39 +0000209
bsalomon@google.com934c5702012-03-20 21:17:58 +0000210 // bookkeeping to attempt to concantenate drawIndexedInstances calls
211 struct {
212 int fVerticesPerInstance;
213 int fIndicesPerInstance;
214 void reset() {
215 fVerticesPerInstance = 0;
216 fIndicesPerInstance = 0;
217 }
218 } fInstancedDrawTracker;
bsalomon@google.com92669012011-09-27 19:10:05 +0000219
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000220 struct GeometryPoolState {
221 const GrVertexBuffer* fPoolVertexBuffer;
222 int fPoolStartVertex;
223 const GrIndexBuffer* fPoolIndexBuffer;
224 int fPoolStartIndex;
225 // caller may conservatively over reserve vertices / indices.
226 // we release unused space back to allocator if possible
227 // can only do this if there isn't an intervening pushGeometrySource()
228 size_t fUsedPoolVertexBytes;
229 size_t fUsedPoolIndexBytes;
230 };
bsalomon@google.com92669012011-09-27 19:10:05 +0000231 SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
reed@google.comac10a2d2010-12-22 21:39:39 +0000232
bsalomon@google.com86afc2a2011-02-16 16:12:19 +0000233 typedef GrDrawTarget INHERITED;
reed@google.comac10a2d2010-12-22 21:39:39 +0000234};
235
236#endif