blob: d42ef564237fe769f0ef921d4ff4b8444c1ac778 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkTypes.h"
12#include "include/private/GrTypesPriv.h"
13#include "include/private/SkNoncopyable.h"
14#include "include/private/SkTArray.h"
15#include "include/private/SkTDArray.h"
16#include "src/gpu/GrCpuBuffer.h"
17#include "src/gpu/GrNonAtomicRef.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000018
bsalomon@google.com1c13c962011-02-14 16:51:21 +000019class GrGpu;
20
21/**
22 * A pool of geometry buffers tied to a GrGpu.
23 *
24 * The pool allows a client to make space for geometry and then put back excess
25 * space if it over allocated. When a client is ready to draw from the pool
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000026 * it calls unmap on the pool ensure buffers are ready for drawing. The pool
bsalomon@google.com1c13c962011-02-14 16:51:21 +000027 * can be reset after drawing is completed to recycle space.
28 *
29 * At creation time a minimum per-buffer size can be specified. Additionally,
30 * a number of buffers to preallocate can be specified. These will
31 * be allocated at the min size and kept around until the pool is destroyed.
32 */
commit-bot@chromium.orge3beb6b2014-04-07 19:34:38 +000033class GrBufferAllocPool : SkNoncopyable {
bsalomon@google.com11f0b512011-03-29 20:52:23 +000034public:
Brian Salomon58f153c2018-10-18 21:51:15 -040035 static constexpr size_t kDefaultBufferSize = 1 << 15;
36
bsalomon@google.com11f0b512011-03-29 20:52:23 +000037 /**
Brian Salomon601ac802019-02-07 13:37:16 -050038 * A cache object that can be shared by multiple GrBufferAllocPool instances. It caches
39 * cpu buffer allocations to avoid reallocating them.
40 */
41 class CpuBufferCache : public GrNonAtomicRef<CpuBufferCache> {
42 public:
43 static sk_sp<CpuBufferCache> Make(int maxBuffersToCache);
44
45 sk_sp<GrCpuBuffer> makeBuffer(size_t size, bool mustBeInitialized);
46 void releaseAll();
47
48 private:
49 CpuBufferCache(int maxBuffersToCache);
50
51 struct Buffer {
52 sk_sp<GrCpuBuffer> fBuffer;
53 bool fCleared = false;
54 };
55 std::unique_ptr<Buffer[]> fBuffers;
56 int fMaxBuffersToCache = 0;
57 };
58
59 /**
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000060 * Ensures all buffers are unmapped and have all data written to them.
bsalomon@google.com11f0b512011-03-29 20:52:23 +000061 * Call before drawing using buffers from the pool.
62 */
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000063 void unmap();
bsalomon@google.com11f0b512011-03-29 20:52:23 +000064
65 /**
66 * Invalidates all the data in the pool, unrefs non-preallocated buffers.
67 */
68 void reset();
69
70 /**
bsalomon@google.com11f0b512011-03-29 20:52:23 +000071 * Frees data from makeSpaces in LIFO order.
72 */
73 void putBack(size_t bytes);
74
bsalomon@google.com11f0b512011-03-29 20:52:23 +000075protected:
76 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +000077 * Constructor
78 *
79 * @param gpu The GrGpu used to create the buffers.
80 * @param bufferType The type of buffers to create.
Brian Salomon601ac802019-02-07 13:37:16 -050081 * @param cpuBufferCache If non-null a cache for client side array buffers
82 * or staging buffers used before data is uploaded to
83 * GPU buffer objects.
bsalomon@google.com1c13c962011-02-14 16:51:21 +000084 */
Brian Salomon601ac802019-02-07 13:37:16 -050085 GrBufferAllocPool(GrGpu* gpu, GrGpuBufferType bufferType, sk_sp<CpuBufferCache> cpuBufferCache);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000086
Brian Salomon58f153c2018-10-18 21:51:15 -040087 virtual ~GrBufferAllocPool();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000088
bsalomon@google.com1c13c962011-02-14 16:51:21 +000089 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +000090 * Returns a block of memory to hold data. A buffer designated to hold the
91 * data is given to the caller. The buffer may or may not be locked. The
92 * returned ptr remains valid until any of the following:
93 * *makeSpace is called again.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000094 * *unmap is called.
bsalomon@google.com1c13c962011-02-14 16:51:21 +000095 * *reset is called.
96 * *this object is destroyed.
97 *
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000098 * Once unmap on the pool is called the data is guaranteed to be in the
bsalomon@google.com1c13c962011-02-14 16:51:21 +000099 * buffer at the offset indicated by offset. Until that time it may be
100 * in temporary storage and/or the buffer may be locked.
101 *
102 * @param size the amount of data to make space for
103 * @param alignment alignment constraint from start of buffer
104 * @param buffer returns the buffer that will hold the data.
105 * @param offset returns the offset into buffer of the data.
106 * @return pointer to where the client should write the data.
107 */
Brian Salomon12d22642019-01-29 14:38:50 -0500108 void* makeSpace(size_t size, size_t alignment, sk_sp<const GrBuffer>* buffer, size_t* offset);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000109
Brian Osman49b7b6f2017-06-20 14:43:58 -0400110 /**
111 * Returns a block of memory to hold data. A buffer designated to hold the
112 * data is given to the caller. The buffer may or may not be locked. The
113 * returned ptr remains valid until any of the following:
114 * *makeSpace is called again.
115 * *unmap is called.
116 * *reset is called.
117 * *this object is destroyed.
118 *
119 * Once unmap on the pool is called the data is guaranteed to be in the
120 * buffer at the offset indicated by offset. Until that time it may be
121 * in temporary storage and/or the buffer may be locked.
122 *
123 * The caller requests a minimum number of bytes, but the block may be (much)
124 * larger. Assuming that a new block must be allocated, it will be fallbackSize bytes.
125 * The actual block size is returned in actualSize.
126 *
127 * @param minSize the minimum amount of data to make space for
128 * @param fallbackSize the amount of data to make space for if a new block is needed
129 * @param alignment alignment constraint from start of buffer
130 * @param buffer returns the buffer that will hold the data.
131 * @param offset returns the offset into buffer of the data.
132 * @param actualSize returns the capacity of the block
133 * @return pointer to where the client should write the data.
134 */
135 void* makeSpaceAtLeast(size_t minSize,
136 size_t fallbackSize,
137 size_t alignment,
Brian Salomon12d22642019-01-29 14:38:50 -0500138 sk_sp<const GrBuffer>* buffer,
Brian Osman49b7b6f2017-06-20 14:43:58 -0400139 size_t* offset,
140 size_t* actualSize);
141
Brian Salomon12d22642019-01-29 14:38:50 -0500142 sk_sp<GrBuffer> getBuffer(size_t size);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000143
144private:
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000145 struct BufferBlock {
Brian Salomon12d22642019-01-29 14:38:50 -0500146 size_t fBytesFree;
147 sk_sp<GrBuffer> fBuffer;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000148 };
149
150 bool createBlock(size_t requestSize);
151 void destroyBlock();
robertphillips1b8e1b52015-06-24 06:54:10 -0700152 void deleteBlocks();
bsalomon3512eda2014-06-26 12:56:22 -0700153 void flushCpuData(const BufferBlock& block, size_t flushSize);
Brian Salomon601ac802019-02-07 13:37:16 -0500154 void resetCpuData(size_t newSize);
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000155#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000156 void validate(bool unusedBlockAllowed = false) const;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000157#endif
Brian Salomon58f153c2018-10-18 21:51:15 -0400158 size_t fBytesInUse = 0;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000159
Brian Salomon58f153c2018-10-18 21:51:15 -0400160 SkTArray<BufferBlock> fBlocks;
Brian Salomon601ac802019-02-07 13:37:16 -0500161 sk_sp<CpuBufferCache> fCpuBufferCache;
162 sk_sp<GrCpuBuffer> fCpuStagingBuffer;
Brian Salomon58f153c2018-10-18 21:51:15 -0400163 GrGpu* fGpu;
Brian Salomonae64c192019-02-05 09:41:37 -0500164 GrGpuBufferType fBufferType;
Brian Salomon58f153c2018-10-18 21:51:15 -0400165 void* fBufferPtr = nullptr;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000166};
167
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000168/**
169 * A GrBufferAllocPool of vertex buffers
170 */
171class GrVertexBufferAllocPool : public GrBufferAllocPool {
172public:
173 /**
174 * Constructor
175 *
176 * @param gpu The GrGpu used to create the vertex buffers.
Brian Salomon601ac802019-02-07 13:37:16 -0500177 * @param cpuBufferCache If non-null a cache for client side array buffers
178 * or staging buffers used before data is uploaded to
179 * GPU buffer objects.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000180 */
Brian Salomon601ac802019-02-07 13:37:16 -0500181 GrVertexBufferAllocPool(GrGpu* gpu, sk_sp<CpuBufferCache> cpuBufferCache);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000182
183 /**
184 * Returns a block of memory to hold vertices. A buffer designated to hold
185 * the vertices given to the caller. The buffer may or may not be locked.
186 * The returned ptr remains valid until any of the following:
187 * *makeSpace is called again.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000188 * *unmap is called.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000189 * *reset is called.
190 * *this object is destroyed.
191 *
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000192 * Once unmap on the pool is called the vertices are guaranteed to be in
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000193 * the buffer at the offset indicated by startVertex. Until that time they
194 * may be in temporary storage and/or the buffer may be locked.
195 *
jvanverth@google.coma6338982013-01-31 21:34:25 +0000196 * @param vertexSize specifies size of a vertex to allocate space for
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000197 * @param vertexCount number of vertices to allocate space for
198 * @param buffer returns the vertex buffer that will hold the
199 * vertices.
200 * @param startVertex returns the offset into buffer of the first vertex.
201 * In units of the size of a vertex from layout param.
202 * @return pointer to first vertex.
203 */
jvanverth@google.coma6338982013-01-31 21:34:25 +0000204 void* makeSpace(size_t vertexSize,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000205 int vertexCount,
Brian Salomon12d22642019-01-29 14:38:50 -0500206 sk_sp<const GrBuffer>* buffer,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000207 int* startVertex);
208
Brian Osman49b7b6f2017-06-20 14:43:58 -0400209 /**
210 * Returns a block of memory to hold vertices. A buffer designated to hold
211 * the vertices given to the caller. The buffer may or may not be locked.
212 * The returned ptr remains valid until any of the following:
213 * *makeSpace is called again.
214 * *unmap is called.
215 * *reset is called.
216 * *this object is destroyed.
217 *
218 * Once unmap on the pool is called the vertices are guaranteed to be in
219 * the buffer at the offset indicated by startVertex. Until that time they
220 * may be in temporary storage and/or the buffer may be locked.
221 *
222 * The caller requests a minimum number of vertices, but the block may be (much)
223 * larger. Assuming that a new block must be allocated, it will be sized to hold
224 * fallbackVertexCount vertices. The actual block size (in vertices) is returned in
225 * actualVertexCount.
226 *
227 * @param vertexSize specifies size of a vertex to allocate space for
228 * @param minVertexCount minimum number of vertices to allocate space for
229 * @param fallbackVertexCount number of vertices to allocate space for if a new block is needed
230 * @param buffer returns the vertex buffer that will hold the vertices.
231 * @param startVertex returns the offset into buffer of the first vertex.
232 * In units of the size of a vertex from layout param.
233 * @param actualVertexCount returns the capacity of the block (in vertices)
234 * @return pointer to first vertex.
235 */
236 void* makeSpaceAtLeast(size_t vertexSize,
237 int minVertexCount,
238 int fallbackVertexCount,
Brian Salomon12d22642019-01-29 14:38:50 -0500239 sk_sp<const GrBuffer>* buffer,
Brian Osman49b7b6f2017-06-20 14:43:58 -0400240 int* startVertex,
241 int* actualVertexCount);
242
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000243private:
244 typedef GrBufferAllocPool INHERITED;
245};
246
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000247/**
248 * A GrBufferAllocPool of index buffers
249 */
250class GrIndexBufferAllocPool : public GrBufferAllocPool {
251public:
252 /**
253 * Constructor
254 *
255 * @param gpu The GrGpu used to create the index buffers.
Brian Salomon601ac802019-02-07 13:37:16 -0500256 * @param cpuBufferCache If non-null a cache for client side array buffers
257 * or staging buffers used before data is uploaded to
258 * GPU buffer objects.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000259 */
Brian Salomon601ac802019-02-07 13:37:16 -0500260 GrIndexBufferAllocPool(GrGpu* gpu, sk_sp<CpuBufferCache> cpuBufferCache);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000261
262 /**
263 * Returns a block of memory to hold indices. A buffer designated to hold
264 * the indices is given to the caller. The buffer may or may not be locked.
265 * The returned ptr remains valid until any of the following:
266 * *makeSpace is called again.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000267 * *unmap is called.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000268 * *reset is called.
269 * *this object is destroyed.
270 *
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000271 * Once unmap on the pool is called the indices are guaranteed to be in the
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000272 * buffer at the offset indicated by startIndex. Until that time they may be
273 * in temporary storage and/or the buffer may be locked.
274 *
275 * @param indexCount number of indices to allocate space for
276 * @param buffer returns the index buffer that will hold the indices.
277 * @param startIndex returns the offset into buffer of the first index.
278 * @return pointer to first index.
279 */
Brian Salomon12d22642019-01-29 14:38:50 -0500280 void* makeSpace(int indexCount, sk_sp<const GrBuffer>* buffer, int* startIndex);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000281
Brian Osman49b7b6f2017-06-20 14:43:58 -0400282 /**
283 * Returns a block of memory to hold indices. A buffer designated to hold
284 * the indices is given to the caller. The buffer may or may not be locked.
285 * The returned ptr remains valid until any of the following:
286 * *makeSpace is called again.
287 * *unmap is called.
288 * *reset is called.
289 * *this object is destroyed.
290 *
291 * Once unmap on the pool is called the indices are guaranteed to be in the
292 * buffer at the offset indicated by startIndex. Until that time they may be
293 * in temporary storage and/or the buffer may be locked.
294 *
295 * The caller requests a minimum number of indices, but the block may be (much)
296 * larger. Assuming that a new block must be allocated, it will be sized to hold
297 * fallbackIndexCount indices. The actual block size (in indices) is returned in
298 * actualIndexCount.
299 *
300 * @param minIndexCount minimum number of indices to allocate space for
301 * @param fallbackIndexCount number of indices to allocate space for if a new block is needed
302 * @param buffer returns the index buffer that will hold the indices.
303 * @param startIndex returns the offset into buffer of the first index.
304 * @param actualIndexCount returns the capacity of the block (in indices)
305 * @return pointer to first index.
306 */
307 void* makeSpaceAtLeast(int minIndexCount,
308 int fallbackIndexCount,
Brian Salomon12d22642019-01-29 14:38:50 -0500309 sk_sp<const GrBuffer>* buffer,
Brian Osman49b7b6f2017-06-20 14:43:58 -0400310 int* startIndex,
311 int* actualIndexCount);
312
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000313private:
314 typedef GrBufferAllocPool INHERITED;
315};
316
317#endif