blob: cd5d1971da5722dcc0597788150e038c7f1c1354 [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
bsalomon@google.com49313f62011-09-14 13:54:05 +000011#include "SkTArray.h"
bsalomon@google.com21cbec42013-01-07 17:23:00 +000012#include "SkTDArray.h"
commit-bot@chromium.orga0b40282013-09-18 13:00:55 +000013#include "SkTypes.h"
bsalomon@google.com1c13c962011-02-14 16:51:21 +000014
15class GrGeometryBuffer;
16class GrGpu;
17
18/**
19 * A pool of geometry buffers tied to a GrGpu.
20 *
21 * The pool allows a client to make space for geometry and then put back excess
22 * space if it over allocated. When a client is ready to draw from the pool
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000023 * it calls unmap on the pool ensure buffers are ready for drawing. The pool
bsalomon@google.com1c13c962011-02-14 16:51:21 +000024 * can be reset after drawing is completed to recycle space.
25 *
26 * At creation time a minimum per-buffer size can be specified. Additionally,
27 * a number of buffers to preallocate can be specified. These will
28 * be allocated at the min size and kept around until the pool is destroyed.
29 */
commit-bot@chromium.orge3beb6b2014-04-07 19:34:38 +000030class GrBufferAllocPool : SkNoncopyable {
bsalomon@google.com11f0b512011-03-29 20:52:23 +000031public:
32 /**
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000033 * Ensures all buffers are unmapped and have all data written to them.
bsalomon@google.com11f0b512011-03-29 20:52:23 +000034 * Call before drawing using buffers from the pool.
35 */
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000036 void unmap();
bsalomon@google.com11f0b512011-03-29 20:52:23 +000037
38 /**
39 * Invalidates all the data in the pool, unrefs non-preallocated buffers.
40 */
41 void reset();
42
43 /**
bsalomon@google.com11f0b512011-03-29 20:52:23 +000044 * Frees data from makeSpaces in LIFO order.
45 */
46 void putBack(size_t bytes);
47
bsalomon@google.com11f0b512011-03-29 20:52:23 +000048protected:
49 /**
50 * Used to determine what type of buffers to create. We could make the
51 * createBuffer a virtual except that we want to use it in the cons for
52 * pre-allocated buffers.
53 */
bsalomon@google.com1c13c962011-02-14 16:51:21 +000054 enum BufferType {
55 kVertex_BufferType,
56 kIndex_BufferType,
57 };
58
59 /**
60 * Constructor
61 *
62 * @param gpu The GrGpu used to create the buffers.
63 * @param bufferType The type of buffers to create.
bsalomon@google.com1c13c962011-02-14 16:51:21 +000064 * @param bufferSize The minimum size of created buffers.
65 * This value will be clamped to some
66 * reasonable minimum.
robertphillipseea2ff72015-05-14 05:24:53 -070067 * @param preallocBufferCnt The pool will allocate this number of
68 * buffers at bufferSize and keep them until it
69 * is destroyed.
bsalomon@google.com1c13c962011-02-14 16:51:21 +000070 */
71 GrBufferAllocPool(GrGpu* gpu,
72 BufferType bufferType,
robertphillipseea2ff72015-05-14 05:24:53 -070073 size_t bufferSize = 0,
74 int preallocBufferCnt = 0);
bsalomon@google.com1c13c962011-02-14 16:51:21 +000075
robertphillipseea2ff72015-05-14 05:24:53 -070076 virtual ~GrBufferAllocPool();
bsalomon@google.com1c13c962011-02-14 16:51:21 +000077
bsalomon@google.com1c13c962011-02-14 16:51:21 +000078 /**
bsalomon@google.com1c13c962011-02-14 16:51:21 +000079 * Returns a block of memory to hold data. A buffer designated to hold the
80 * data is given to the caller. The buffer may or may not be locked. The
81 * returned ptr remains valid until any of the following:
82 * *makeSpace is called again.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000083 * *unmap is called.
bsalomon@google.com1c13c962011-02-14 16:51:21 +000084 * *reset is called.
85 * *this object is destroyed.
86 *
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +000087 * Once unmap on the pool is called the data is guaranteed to be in the
bsalomon@google.com1c13c962011-02-14 16:51:21 +000088 * buffer at the offset indicated by offset. Until that time it may be
89 * in temporary storage and/or the buffer may be locked.
90 *
91 * @param size the amount of data to make space for
92 * @param alignment alignment constraint from start of buffer
93 * @param buffer returns the buffer that will hold the data.
94 * @param offset returns the offset into buffer of the data.
95 * @return pointer to where the client should write the data.
96 */
97 void* makeSpace(size_t size,
98 size_t alignment,
99 const GrGeometryBuffer** buffer,
100 size_t* offset);
101
robertphillipseea2ff72015-05-14 05:24:53 -0700102 GrGeometryBuffer* createBuffer(size_t size);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000103
104private:
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000105 struct BufferBlock {
106 size_t fBytesFree;
107 GrGeometryBuffer* fBuffer;
108 };
109
110 bool createBlock(size_t requestSize);
111 void destroyBlock();
bsalomon3512eda2014-06-26 12:56:22 -0700112 void flushCpuData(const BufferBlock& block, size_t flushSize);
commit-bot@chromium.org515dcd32013-08-28 14:17:03 +0000113#ifdef SK_DEBUG
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000114 void validate(bool unusedBlockAllowed = false) const;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000115#endif
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000116
bsalomon@google.com25fb21f2011-06-21 18:17:25 +0000117 size_t fBytesInUse;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000118
119 GrGpu* fGpu;
robertphillipseea2ff72015-05-14 05:24:53 -0700120 SkTDArray<GrGeometryBuffer*> fPreallocBuffers;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000121 size_t fMinBlockSize;
122 BufferType fBufferType;
123
bsalomon@google.com49313f62011-09-14 13:54:05 +0000124 SkTArray<BufferBlock> fBlocks;
robertphillipseea2ff72015-05-14 05:24:53 -0700125 int fPreallocBuffersInUse;
126 // We attempt to cycle through the preallocated buffers rather than
127 // always starting from the first.
128 int fPreallocBufferStartIdx;
bsalomon@google.com3582bf92011-06-30 21:32:31 +0000129 SkAutoMalloc fCpuData;
130 void* fBufferPtr;
joshualitt7224c862015-05-29 06:46:47 -0700131 size_t fGeometryBufferMapThreshold;
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000132};
133
134class GrVertexBuffer;
135
136/**
137 * A GrBufferAllocPool of vertex buffers
138 */
139class GrVertexBufferAllocPool : public GrBufferAllocPool {
140public:
141 /**
142 * Constructor
143 *
144 * @param gpu The GrGpu used to create the vertex buffers.
robertphillipseea2ff72015-05-14 05:24:53 -0700145 * @param bufferSize The minimum size of created VBs. This value
146 * will be clamped to some reasonable minimum.
147 * @param preallocBufferCnt The pool will allocate this number of VBs at
148 * bufferSize and keep them until it is
149 * destroyed.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000150 */
robertphillipseea2ff72015-05-14 05:24:53 -0700151 GrVertexBufferAllocPool(GrGpu* gpu, size_t bufferSize = 0, int preallocBufferCnt = 0);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000152
153 /**
154 * Returns a block of memory to hold vertices. A buffer designated to hold
155 * the vertices given to the caller. The buffer may or may not be locked.
156 * The returned ptr remains valid until any of the following:
157 * *makeSpace is called again.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000158 * *unmap is called.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000159 * *reset is called.
160 * *this object is destroyed.
161 *
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000162 * Once unmap on the pool is called the vertices are guaranteed to be in
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000163 * the buffer at the offset indicated by startVertex. Until that time they
164 * may be in temporary storage and/or the buffer may be locked.
165 *
jvanverth@google.coma6338982013-01-31 21:34:25 +0000166 * @param vertexSize specifies size of a vertex to allocate space for
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000167 * @param vertexCount number of vertices to allocate space for
168 * @param buffer returns the vertex buffer that will hold the
169 * vertices.
170 * @param startVertex returns the offset into buffer of the first vertex.
171 * In units of the size of a vertex from layout param.
172 * @return pointer to first vertex.
173 */
jvanverth@google.coma6338982013-01-31 21:34:25 +0000174 void* makeSpace(size_t vertexSize,
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000175 int vertexCount,
176 const GrVertexBuffer** buffer,
177 int* startVertex);
178
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000179private:
180 typedef GrBufferAllocPool INHERITED;
181};
182
183class GrIndexBuffer;
184
185/**
186 * A GrBufferAllocPool of index buffers
187 */
188class GrIndexBufferAllocPool : public GrBufferAllocPool {
189public:
190 /**
191 * Constructor
192 *
193 * @param gpu The GrGpu used to create the index buffers.
robertphillipseea2ff72015-05-14 05:24:53 -0700194 * @param bufferSize The minimum size of created IBs. This value
195 * will be clamped to some reasonable minimum.
196 * @param preallocBufferCnt The pool will allocate this number of VBs at
197 * bufferSize and keep them until it is
198 * destroyed.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000199 */
robertphillipseea2ff72015-05-14 05:24:53 -0700200 GrIndexBufferAllocPool(GrGpu* gpu,
201 size_t bufferSize = 0,
202 int preallocBufferCnt = 0);
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000203
204 /**
205 * Returns a block of memory to hold indices. A buffer designated to hold
206 * the indices is given to the caller. The buffer may or may not be locked.
207 * The returned ptr remains valid until any of the following:
208 * *makeSpace is called again.
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000209 * *unmap is called.
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000210 * *reset is called.
211 * *this object is destroyed.
212 *
commit-bot@chromium.org8341eb72014-05-07 20:51:05 +0000213 * Once unmap on the pool is called the indices are guaranteed to be in the
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000214 * buffer at the offset indicated by startIndex. Until that time they may be
215 * in temporary storage and/or the buffer may be locked.
216 *
217 * @param indexCount number of indices to allocate space for
218 * @param buffer returns the index buffer that will hold the indices.
219 * @param startIndex returns the offset into buffer of the first index.
220 * @return pointer to first index.
221 */
222 void* makeSpace(int indexCount,
223 const GrIndexBuffer** buffer,
224 int* startIndex);
225
bsalomon@google.com1c13c962011-02-14 16:51:21 +0000226private:
227 typedef GrBufferAllocPool INHERITED;
228};
229
230#endif