blob: 9e502c604794cf6f282865a08706e1c28709472a [file] [log] [blame]
bsalomon@google.com1c13c962011-02-14 16:51:21 +00001/*
epoger@google.comec3ed6a2011-07-28 14:26:00 +00002 * Copyright 2010 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
bsalomon@google.com1c13c962011-02-14 16:51:21 +00006 */
7
bsalomon@google.com1c13c962011-02-14 16:51:21 +00008#ifndef GrBufferAllocPool_DEFINED
9#define GrBufferAllocPool_DEFINED
10
Ben Wagnerd5148e32018-07-16 17:44:06 -040011#include "GrTypesPriv.h"
12#include "SkNoncopyable.h"
bsalomon@google.com49313f62011-09-14 13:54:05 +000013#include "SkTArray.h"
bsalomon@google.com21cbec42013-01-07 17:23:00 +000014#include "SkTDArray.h"
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +000015#include "SkTypes.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000016
cdalton397536c2016-03-25 12:15:03 -070017class GrBuffer;
bsalomon@google.com1c13c962011-02-14 16:51:21 +000018class GrGpu;
19
20/**
21 * A pool of geometry buffers tied to a GrGpu.
22 *
23 * The pool allows a client to make space for geometry and then put back excess
24 * space if it over allocated. When a client is ready to draw from the pool
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000025 * it calls unmap on the pool ensure buffers are ready for drawing. The pool
bsalomon@google.com1c13c962011-02-14 16:51:21 +000026 * can be reset after drawing is completed to recycle space.
27 *
28 * At creation time a minimum per-buffer size can be specified. Additionally,
29 * a number of buffers to preallocate can be specified. These will
30 * be allocated at the min size and kept around until the pool is destroyed.
31 */
commit-bot@chromium.orge3beb6b2014-04-07 19:34:38 +000032class GrBufferAllocPool : SkNoncopyable {
bsalomon@google.com11f0b512011-03-29 20:52:23 +000033public:
Brian Salomon58f153c2018-10-18 21:51:15 -040034 static constexpr size_t kDefaultBufferSize = 1 << 15;
35
bsalomon@google.com11f0b512011-03-29 20:52:23 +000036 /**
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000037 * Ensures all buffers are unmapped and have all data written to them.
bsalomon@google.com11f0b512011-03-29 20:52:23 +000038 * Call before drawing using buffers from the pool.
39 */
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000040 void unmap();
bsalomon@google.com11f0b512011-03-29 20:52:23 +000041
42 /**
43 * Invalidates all the data in the pool, unrefs non-preallocated buffers.
44 */
45 void reset();
46
47 /**
bsalomon@google.com11f0b512011-03-29 20:52:23 +000048 * Frees data from makeSpaces in LIFO order.
49 */
50 void putBack(size_t bytes);
51
bsalomon@google.com11f0b512011-03-29 20:52:23 +000052protected:
53 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +000054 * Constructor
55 *
56 * @param gpu The GrGpu used to create the buffers.
57 * @param bufferType The type of buffers to create.
Brian Salomon58f153c2018-10-18 21:51:15 -040058 * @param initialBuffer If non-null this should be a kDefaultBufferSize byte allocation.
59 * This parameter can be used to avoid malloc/free when all
60 * usages can be satisfied with default-sized buffers.
bsalomon@google.com1c13c962011-02-14 16:51:21 +000061 */
Brian Salomon58f153c2018-10-18 21:51:15 -040062 GrBufferAllocPool(GrGpu* gpu, GrBufferType bufferType, void* initialBuffer);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000063
Brian Salomon58f153c2018-10-18 21:51:15 -040064 virtual ~GrBufferAllocPool();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000065
bsalomon@google.com1c13c962011-02-14 16:51:21 +000066 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +000067 * Returns a block of memory to hold data. A buffer designated to hold the
68 * data is given to the caller. The buffer may or may not be locked. The
69 * returned ptr remains valid until any of the following:
70 * *makeSpace is called again.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000071 * *unmap is called.
bsalomon@google.com1c13c962011-02-14 16:51:21 +000072 * *reset is called.
73 * *this object is destroyed.
74 *
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000075 * Once unmap on the pool is called the data is guaranteed to be in the
bsalomon@google.com1c13c962011-02-14 16:51:21 +000076 * buffer at the offset indicated by offset. Until that time it may be
77 * in temporary storage and/or the buffer may be locked.
78 *
79 * @param size the amount of data to make space for
80 * @param alignment alignment constraint from start of buffer
81 * @param buffer returns the buffer that will hold the data.
82 * @param offset returns the offset into buffer of the data.
83 * @return pointer to where the client should write the data.
84 */
85 void* makeSpace(size_t size,
86 size_t alignment,
cdalton397536c2016-03-25 12:15:03 -070087 const GrBuffer** buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +000088 size_t* offset);
89
Brian Osman49b7b6f2017-06-20 14:43:58 -040090 /**
91 * Returns a block of memory to hold data. A buffer designated to hold the
92 * data is given to the caller. The buffer may or may not be locked. The
93 * returned ptr remains valid until any of the following:
94 * *makeSpace is called again.
95 * *unmap is called.
96 * *reset is called.
97 * *this object is destroyed.
98 *
99 * Once unmap on the pool is called the data is guaranteed to be in the
100 * buffer at the offset indicated by offset. Until that time it may be
101 * in temporary storage and/or the buffer may be locked.
102 *
103 * The caller requests a minimum number of bytes, but the block may be (much)
104 * larger. Assuming that a new block must be allocated, it will be fallbackSize bytes.
105 * The actual block size is returned in actualSize.
106 *
107 * @param minSize the minimum amount of data to make space for
108 * @param fallbackSize the amount of data to make space for if a new block is needed
109 * @param alignment alignment constraint from start of buffer
110 * @param buffer returns the buffer that will hold the data.
111 * @param offset returns the offset into buffer of the data.
112 * @param actualSize returns the capacity of the block
113 * @return pointer to where the client should write the data.
114 */
115 void* makeSpaceAtLeast(size_t minSize,
116 size_t fallbackSize,
117 size_t alignment,
118 const GrBuffer** buffer,
119 size_t* offset,
120 size_t* actualSize);
121
cdalton397536c2016-03-25 12:15:03 -0700122 GrBuffer* getBuffer(size_t size);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000123
124private:
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000125 struct BufferBlock {
cdalton397536c2016-03-25 12:15:03 -0700126 size_t fBytesFree;
127 GrBuffer* fBuffer;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000128 };
129
130 bool createBlock(size_t requestSize);
131 void destroyBlock();
robertphillips1b8e1b52015-06-24 06:54:10 -0700132 void deleteBlocks();
bsalomon3512eda2014-06-26 12:56:22 -0700133 void flushCpuData(const BufferBlock& block, size_t flushSize);
bsalomon7dea7b72015-08-19 08:26:51 -0700134 void* resetCpuData(size_t newSize);
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000135#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000136 void validate(bool unusedBlockAllowed = false) const;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000137#endif
Brian Salomon58f153c2018-10-18 21:51:15 -0400138 size_t fBytesInUse = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000139
Brian Salomon58f153c2018-10-18 21:51:15 -0400140 SkTArray<BufferBlock> fBlocks;
141 GrGpu* fGpu;
142 GrBufferType fBufferType;
143 void* fInitialCpuData = nullptr;
144 void* fCpuData = nullptr;
145 size_t fCpuDataSize = 0;
146 void* fBufferPtr = nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000147};
148
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000149/**
150 * A GrBufferAllocPool of vertex buffers
151 */
152class GrVertexBufferAllocPool : public GrBufferAllocPool {
153public:
154 /**
155 * Constructor
156 *
157 * @param gpu The GrGpu used to create the vertex buffers.
Brian Salomon58f153c2018-10-18 21:51:15 -0400158 * @param initialBuffer If non-null this should be a kDefaultBufferSize byte allocation.
159 * This parameter can be used to avoid malloc/free when all
160 * usages can be satisfied with default-sized buffers.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000161 */
Brian Salomon58f153c2018-10-18 21:51:15 -0400162 GrVertexBufferAllocPool(GrGpu* gpu, void* initialBuffer);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000163
164 /**
165 * Returns a block of memory to hold vertices. A buffer designated to hold
166 * the vertices given to the caller. The buffer may or may not be locked.
167 * The returned ptr remains valid until any of the following:
168 * *makeSpace is called again.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000169 * *unmap is called.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000170 * *reset is called.
171 * *this object is destroyed.
172 *
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000173 * Once unmap on the pool is called the vertices are guaranteed to be in
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000174 * the buffer at the offset indicated by startVertex. Until that time they
175 * may be in temporary storage and/or the buffer may be locked.
176 *
jvanverth@google.coma6338982013-01-31 21:34:25 +0000177 * @param vertexSize specifies size of a vertex to allocate space for
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000178 * @param vertexCount number of vertices to allocate space for
179 * @param buffer returns the vertex buffer that will hold the
180 * vertices.
181 * @param startVertex returns the offset into buffer of the first vertex.
182 * In units of the size of a vertex from layout param.
183 * @return pointer to first vertex.
184 */
jvanverth@google.coma6338982013-01-31 21:34:25 +0000185 void* makeSpace(size_t vertexSize,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000186 int vertexCount,
cdalton397536c2016-03-25 12:15:03 -0700187 const GrBuffer** buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000188 int* startVertex);
189
Brian Osman49b7b6f2017-06-20 14:43:58 -0400190 /**
191 * Returns a block of memory to hold vertices. A buffer designated to hold
192 * the vertices given to the caller. The buffer may or may not be locked.
193 * The returned ptr remains valid until any of the following:
194 * *makeSpace is called again.
195 * *unmap is called.
196 * *reset is called.
197 * *this object is destroyed.
198 *
199 * Once unmap on the pool is called the vertices are guaranteed to be in
200 * the buffer at the offset indicated by startVertex. Until that time they
201 * may be in temporary storage and/or the buffer may be locked.
202 *
203 * The caller requests a minimum number of vertices, but the block may be (much)
204 * larger. Assuming that a new block must be allocated, it will be sized to hold
205 * fallbackVertexCount vertices. The actual block size (in vertices) is returned in
206 * actualVertexCount.
207 *
208 * @param vertexSize specifies size of a vertex to allocate space for
209 * @param minVertexCount minimum number of vertices to allocate space for
210 * @param fallbackVertexCount number of vertices to allocate space for if a new block is needed
211 * @param buffer returns the vertex buffer that will hold the vertices.
212 * @param startVertex returns the offset into buffer of the first vertex.
213 * In units of the size of a vertex from layout param.
214 * @param actualVertexCount returns the capacity of the block (in vertices)
215 * @return pointer to first vertex.
216 */
217 void* makeSpaceAtLeast(size_t vertexSize,
218 int minVertexCount,
219 int fallbackVertexCount,
220 const GrBuffer** buffer,
221 int* startVertex,
222 int* actualVertexCount);
223
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000224private:
225 typedef GrBufferAllocPool INHERITED;
226};
227
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000228/**
229 * A GrBufferAllocPool of index buffers
230 */
231class GrIndexBufferAllocPool : public GrBufferAllocPool {
232public:
233 /**
234 * Constructor
235 *
236 * @param gpu The GrGpu used to create the index buffers.
Brian Salomon58f153c2018-10-18 21:51:15 -0400237 * @param initialBuffer If non-null this should be a kDefaultBufferSize byte allocation.
238 * This parameter can be used to avoid malloc/free when all
239 * usages can be satisfied with default-sized buffers.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000240 */
Brian Salomon58f153c2018-10-18 21:51:15 -0400241 GrIndexBufferAllocPool(GrGpu* gpu, void* initialBuffer);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000242
243 /**
244 * Returns a block of memory to hold indices. A buffer designated to hold
245 * the indices is given to the caller. The buffer may or may not be locked.
246 * The returned ptr remains valid until any of the following:
247 * *makeSpace is called again.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000248 * *unmap is called.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000249 * *reset is called.
250 * *this object is destroyed.
251 *
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000252 * Once unmap on the pool is called the indices are guaranteed to be in the
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000253 * buffer at the offset indicated by startIndex. Until that time they may be
254 * in temporary storage and/or the buffer may be locked.
255 *
256 * @param indexCount number of indices to allocate space for
257 * @param buffer returns the index buffer that will hold the indices.
258 * @param startIndex returns the offset into buffer of the first index.
259 * @return pointer to first index.
260 */
261 void* makeSpace(int indexCount,
cdalton397536c2016-03-25 12:15:03 -0700262 const GrBuffer** buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000263 int* startIndex);
264
Brian Osman49b7b6f2017-06-20 14:43:58 -0400265 /**
266 * Returns a block of memory to hold indices. A buffer designated to hold
267 * the indices is given to the caller. The buffer may or may not be locked.
268 * The returned ptr remains valid until any of the following:
269 * *makeSpace is called again.
270 * *unmap is called.
271 * *reset is called.
272 * *this object is destroyed.
273 *
274 * Once unmap on the pool is called the indices are guaranteed to be in the
275 * buffer at the offset indicated by startIndex. Until that time they may be
276 * in temporary storage and/or the buffer may be locked.
277 *
278 * The caller requests a minimum number of indices, but the block may be (much)
279 * larger. Assuming that a new block must be allocated, it will be sized to hold
280 * fallbackIndexCount indices. The actual block size (in indices) is returned in
281 * actualIndexCount.
282 *
283 * @param minIndexCount minimum number of indices to allocate space for
284 * @param fallbackIndexCount number of indices to allocate space for if a new block is needed
285 * @param buffer returns the index buffer that will hold the indices.
286 * @param startIndex returns the offset into buffer of the first index.
287 * @param actualIndexCount returns the capacity of the block (in indices)
288 * @return pointer to first index.
289 */
290 void* makeSpaceAtLeast(int minIndexCount,
291 int fallbackIndexCount,
292 const GrBuffer** buffer,
293 int* startIndex,
294 int* actualIndexCount);
295
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000296private:
297 typedef GrBufferAllocPool INHERITED;
298};
299
300#endif