• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * 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.
6  */
7 
8 #ifndef GrBufferAllocPool_DEFINED
9 #define GrBufferAllocPool_DEFINED
10 
11 #include "SkTArray.h"
12 #include "SkTDArray.h"
13 #include "SkTypes.h"
14 #include "GrTypesPriv.h"
15 
16 class GrBuffer;
17 class GrGpu;
18 
19 /**
20  * A pool of geometry buffers tied to a GrGpu.
21  *
22  * The pool allows a client to make space for geometry and then put back excess
23  * space if it over allocated. When a client is ready to draw from the pool
24  * it calls unmap on the pool ensure buffers are ready for drawing. The pool
25  * can be reset after drawing is completed to recycle space.
26  *
27  * At creation time a minimum per-buffer size can be specified. Additionally,
28  * a number of buffers to preallocate can be specified. These will
29  * be allocated at the min size and kept around until the pool is destroyed.
30  */
31 class GrBufferAllocPool : SkNoncopyable {
32 public:
33     /**
34      * Ensures all buffers are unmapped and have all data written to them.
35      * Call before drawing using buffers from the pool.
36      */
37     void unmap();
38 
39     /**
40      *  Invalidates all the data in the pool, unrefs non-preallocated buffers.
41      */
42     void reset();
43 
44     /**
45      * Frees data from makeSpaces in LIFO order.
46      */
47     void putBack(size_t bytes);
48 
49 protected:
50     /**
51      * Constructor
52      *
53      * @param gpu                   The GrGpu used to create the buffers.
54      * @param bufferType            The type of buffers to create.
55      * @param bufferSize            The minimum size of created buffers.
56      *                              This value will be clamped to some
57      *                              reasonable minimum.
58      */
59      GrBufferAllocPool(GrGpu* gpu,
60                        GrBufferType bufferType,
61                        size_t   bufferSize = 0);
62 
63      virtual ~GrBufferAllocPool();
64 
65     /**
66      * Returns a block of memory to hold data. A buffer designated to hold the
67      * data is given to the caller. The buffer may or may not be locked. The
68      * returned ptr remains valid until any of the following:
69      *      *makeSpace is called again.
70      *      *unmap is called.
71      *      *reset is called.
72      *      *this object is destroyed.
73      *
74      * Once unmap on the pool is called the data is guaranteed to be in the
75      * buffer at the offset indicated by offset. Until that time it may be
76      * in temporary storage and/or the buffer may be locked.
77      *
78      * @param size         the amount of data to make space for
79      * @param alignment    alignment constraint from start of buffer
80      * @param buffer       returns the buffer that will hold the data.
81      * @param offset       returns the offset into buffer of the data.
82      * @return pointer to where the client should write the data.
83      */
84     void* makeSpace(size_t size,
85                     size_t alignment,
86                     const GrBuffer** buffer,
87                     size_t* offset);
88 
89     /**
90      * 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.
94      *      *unmap is called.
95      *      *reset is called.
96      *      *this object is destroyed.
97      *
98      * Once unmap on the pool is called the data is guaranteed to be in the
99      * 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      * The caller requests a minimum number of bytes, but the block may be (much)
103      * larger. Assuming that a new block must be allocated, it will be fallbackSize bytes.
104      * The actual block size is returned in actualSize.
105      *
106      * @param minSize        the minimum amount of data to make space for
107      * @param fallbackSize   the amount of data to make space for if a new block is needed
108      * @param alignment      alignment constraint from start of buffer
109      * @param buffer         returns the buffer that will hold the data.
110      * @param offset         returns the offset into buffer of the data.
111      * @param actualSize     returns the capacity of the block
112      * @return pointer to where the client should write the data.
113      */
114     void* makeSpaceAtLeast(size_t minSize,
115                            size_t fallbackSize,
116                            size_t alignment,
117                            const GrBuffer** buffer,
118                            size_t* offset,
119                            size_t* actualSize);
120 
121     GrBuffer* getBuffer(size_t size);
122 
123 private:
124     struct BufferBlock {
125         size_t      fBytesFree;
126         GrBuffer*   fBuffer;
127     };
128 
129     bool createBlock(size_t requestSize);
130     void destroyBlock();
131     void deleteBlocks();
132     void flushCpuData(const BufferBlock& block, size_t flushSize);
133     void* resetCpuData(size_t newSize);
134 #ifdef SK_DEBUG
135     void validate(bool unusedBlockAllowed = false) const;
136 #endif
137     size_t                          fBytesInUse;
138 
139     GrGpu*                          fGpu;
140     size_t                          fMinBlockSize;
141     GrBufferType                    fBufferType;
142 
143     SkTArray<BufferBlock>           fBlocks;
144     void*                           fCpuData;
145     void*                           fBufferPtr;
146     size_t                          fBufferMapThreshold;
147 };
148 
149 /**
150  * A GrBufferAllocPool of vertex buffers
151  */
152 class GrVertexBufferAllocPool : public GrBufferAllocPool {
153 public:
154     /**
155      * Constructor
156      *
157      * @param gpu                   The GrGpu used to create the vertex buffers.
158      */
159     GrVertexBufferAllocPool(GrGpu* gpu);
160 
161     /**
162      * Returns a block of memory to hold vertices. A buffer designated to hold
163      * the vertices given to the caller. The buffer may or may not be locked.
164      * The returned ptr remains valid until any of the following:
165      *      *makeSpace is called again.
166      *      *unmap is called.
167      *      *reset is called.
168      *      *this object is destroyed.
169      *
170      * Once unmap on the pool is called the vertices are guaranteed to be in
171      * the buffer at the offset indicated by startVertex. Until that time they
172      * may be in temporary storage and/or the buffer may be locked.
173      *
174      * @param vertexSize   specifies size of a vertex to allocate space for
175      * @param vertexCount  number of vertices to allocate space for
176      * @param buffer       returns the vertex buffer that will hold the
177      *                     vertices.
178      * @param startVertex  returns the offset into buffer of the first vertex.
179      *                     In units of the size of a vertex from layout param.
180      * @return pointer to first vertex.
181      */
182     void* makeSpace(size_t vertexSize,
183                     int vertexCount,
184                     const GrBuffer** buffer,
185                     int* startVertex);
186 
187     /**
188      * Returns a block of memory to hold vertices. A buffer designated to hold
189      * the vertices given to the caller. The buffer may or may not be locked.
190      * The returned ptr remains valid until any of the following:
191      *      *makeSpace is called again.
192      *      *unmap is called.
193      *      *reset is called.
194      *      *this object is destroyed.
195      *
196      * Once unmap on the pool is called the vertices are guaranteed to be in
197      * the buffer at the offset indicated by startVertex. Until that time they
198      * may be in temporary storage and/or the buffer may be locked.
199      *
200      * The caller requests a minimum number of vertices, but the block may be (much)
201      * larger. Assuming that a new block must be allocated, it will be sized to hold
202      * fallbackVertexCount vertices. The actual block size (in vertices) is returned in
203      * actualVertexCount.
204      *
205      * @param vertexSize           specifies size of a vertex to allocate space for
206      * @param minVertexCount       minimum number of vertices to allocate space for
207      * @param fallbackVertexCount  number of vertices to allocate space for if a new block is needed
208      * @param buffer               returns the vertex buffer that will hold the vertices.
209      * @param startVertex          returns the offset into buffer of the first vertex.
210      *                             In units of the size of a vertex from layout param.
211      * @param actualVertexCount    returns the capacity of the block (in vertices)
212      * @return pointer to first vertex.
213      */
214     void* makeSpaceAtLeast(size_t vertexSize,
215                            int minVertexCount,
216                            int fallbackVertexCount,
217                            const GrBuffer** buffer,
218                            int* startVertex,
219                            int* actualVertexCount);
220 
221 private:
222     typedef GrBufferAllocPool INHERITED;
223 };
224 
225 /**
226  * A GrBufferAllocPool of index buffers
227  */
228 class GrIndexBufferAllocPool : public GrBufferAllocPool {
229 public:
230     /**
231      * Constructor
232      *
233      * @param gpu                   The GrGpu used to create the index buffers.
234      */
235     GrIndexBufferAllocPool(GrGpu* gpu);
236 
237     /**
238      * Returns a block of memory to hold indices. A buffer designated to hold
239      * the indices is given to the caller. The buffer may or may not be locked.
240      * The returned ptr remains valid until any of the following:
241      *      *makeSpace is called again.
242      *      *unmap is called.
243      *      *reset is called.
244      *      *this object is destroyed.
245      *
246      * Once unmap on the pool is called the indices are guaranteed to be in the
247      * buffer at the offset indicated by startIndex. Until that time they may be
248      * in temporary storage and/or the buffer may be locked.
249      *
250      * @param indexCount   number of indices to allocate space for
251      * @param buffer       returns the index buffer that will hold the indices.
252      * @param startIndex   returns the offset into buffer of the first index.
253      * @return pointer to first index.
254      */
255     void* makeSpace(int indexCount,
256                     const GrBuffer** buffer,
257                     int* startIndex);
258 
259     /**
260      * Returns a block of memory to hold indices. A buffer designated to hold
261      * the indices is given to the caller. The buffer may or may not be locked.
262      * The returned ptr remains valid until any of the following:
263      *      *makeSpace is called again.
264      *      *unmap is called.
265      *      *reset is called.
266      *      *this object is destroyed.
267      *
268      * Once unmap on the pool is called the indices are guaranteed to be in the
269      * buffer at the offset indicated by startIndex. Until that time they may be
270      * in temporary storage and/or the buffer may be locked.
271      *
272      * The caller requests a minimum number of indices, but the block may be (much)
273      * larger. Assuming that a new block must be allocated, it will be sized to hold
274      * fallbackIndexCount indices. The actual block size (in indices) is returned in
275      * actualIndexCount.
276      *
277      * @param minIndexCount        minimum number of indices to allocate space for
278      * @param fallbackIndexCount   number of indices to allocate space for if a new block is needed
279      * @param buffer               returns the index buffer that will hold the indices.
280      * @param startIndex           returns the offset into buffer of the first index.
281      * @param actualIndexCount     returns the capacity of the block (in indices)
282      * @return pointer to first index.
283      */
284     void* makeSpaceAtLeast(int minIndexCount,
285                            int fallbackIndexCount,
286                            const GrBuffer** buffer,
287                            int* startIndex,
288                            int* actualIndexCount);
289 
290 private:
291     typedef GrBufferAllocPool INHERITED;
292 };
293 
294 #endif
295