• 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 
15 class GrGeometryBuffer;
16 class 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
23  * it calls unmap on the pool ensure buffers are ready for drawing. The pool
24  * 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  */
30 class GrBufferAllocPool : SkNoncopyable {
31 public:
32     /**
33      * Ensures all buffers are unmapped and have all data written to them.
34      * Call before drawing using buffers from the pool.
35      */
36     void unmap();
37 
38     /**
39      *  Invalidates all the data in the pool, unrefs non-preallocated buffers.
40      */
41     void reset();
42 
43     /**
44      * Frees data from makeSpaces in LIFO order.
45      */
46     void putBack(size_t bytes);
47 
48 protected:
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      */
54     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.
64      * @param bufferSize            The minimum size of created buffers.
65      *                              This value will be clamped to some
66      *                              reasonable minimum.
67      * @param preallocBufferCnt     The pool will allocate this number of
68      *                              buffers at bufferSize and keep them until it
69      *                              is destroyed.
70      */
71      GrBufferAllocPool(GrGpu* gpu,
72                        BufferType bufferType,
73                        size_t   bufferSize = 0,
74                        int preallocBufferCnt = 0);
75 
76     virtual ~GrBufferAllocPool();
77 
78     /**
79      * 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.
83      *      *unmap is called.
84      *      *reset is called.
85      *      *this object is destroyed.
86      *
87      * Once unmap on the pool is called the data is guaranteed to be in the
88      * 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 
102     GrGeometryBuffer* createBuffer(size_t size);
103 
104 private:
105     struct BufferBlock {
106         size_t              fBytesFree;
107         GrGeometryBuffer*   fBuffer;
108     };
109 
110     bool createBlock(size_t requestSize);
111     void destroyBlock();
112     void flushCpuData(const BufferBlock& block, size_t flushSize);
113 #ifdef SK_DEBUG
114     void validate(bool unusedBlockAllowed = false) const;
115 #endif
116 
117     size_t                          fBytesInUse;
118 
119     GrGpu*                          fGpu;
120     SkTDArray<GrGeometryBuffer*>    fPreallocBuffers;
121     size_t                          fMinBlockSize;
122     BufferType                      fBufferType;
123 
124     SkTArray<BufferBlock>           fBlocks;
125     int                             fPreallocBuffersInUse;
126     // We attempt to cycle through the preallocated buffers rather than
127     // always starting from the first.
128     int                             fPreallocBufferStartIdx;
129     SkAutoMalloc                    fCpuData;
130     void*                           fBufferPtr;
131 };
132 
133 class GrVertexBuffer;
134 
135 /**
136  * A GrBufferAllocPool of vertex buffers
137  */
138 class GrVertexBufferAllocPool : public GrBufferAllocPool {
139 public:
140     /**
141      * Constructor
142      *
143      * @param gpu                   The GrGpu used to create the vertex buffers.
144      * @param bufferSize            The minimum size of created VBs. This value
145      *                              will be clamped to some reasonable minimum.
146      * @param preallocBufferCnt     The pool will allocate this number of VBs at
147      *                              bufferSize and keep them until it is
148      *                              destroyed.
149      */
150     GrVertexBufferAllocPool(GrGpu* gpu, size_t bufferSize = 0, int preallocBufferCnt = 0);
151 
152     /**
153      * Returns a block of memory to hold vertices. A buffer designated to hold
154      * the vertices given to the caller. The buffer may or may not be locked.
155      * The returned ptr remains valid until any of the following:
156      *      *makeSpace is called again.
157      *      *unmap is called.
158      *      *reset is called.
159      *      *this object is destroyed.
160      *
161      * Once unmap on the pool is called the vertices are guaranteed to be in
162      * the buffer at the offset indicated by startVertex. Until that time they
163      * may be in temporary storage and/or the buffer may be locked.
164      *
165      * @param vertexSize   specifies size of a vertex to allocate space for
166      * @param vertexCount  number of vertices to allocate space for
167      * @param buffer       returns the vertex buffer that will hold the
168      *                     vertices.
169      * @param startVertex  returns the offset into buffer of the first vertex.
170      *                     In units of the size of a vertex from layout param.
171      * @return pointer to first vertex.
172      */
173     void* makeSpace(size_t vertexSize,
174                     int vertexCount,
175                     const GrVertexBuffer** buffer,
176                     int* startVertex);
177 
178 private:
179     typedef GrBufferAllocPool INHERITED;
180 };
181 
182 class GrIndexBuffer;
183 
184 /**
185  * A GrBufferAllocPool of index buffers
186  */
187 class GrIndexBufferAllocPool : public GrBufferAllocPool {
188 public:
189     /**
190      * Constructor
191      *
192      * @param gpu                   The GrGpu used to create the index buffers.
193      * @param bufferSize            The minimum size of created IBs. This value
194      *                              will be clamped to some reasonable minimum.
195      * @param preallocBufferCnt     The pool will allocate this number of VBs at
196      *                              bufferSize and keep them until it is
197      *                              destroyed.
198      */
199     GrIndexBufferAllocPool(GrGpu* gpu,
200                            size_t bufferSize = 0,
201                            int preallocBufferCnt = 0);
202 
203     /**
204      * Returns a block of memory to hold indices. A buffer designated to hold
205      * the indices is given to the caller. The buffer may or may not be locked.
206      * The returned ptr remains valid until any of the following:
207      *      *makeSpace is called again.
208      *      *unmap is called.
209      *      *reset is called.
210      *      *this object is destroyed.
211      *
212      * Once unmap on the pool is called the indices are guaranteed to be in the
213      * buffer at the offset indicated by startIndex. Until that time they may be
214      * in temporary storage and/or the buffer may be locked.
215      *
216      * @param indexCount   number of indices to allocate space for
217      * @param buffer       returns the index buffer that will hold the indices.
218      * @param startIndex   returns the offset into buffer of the first index.
219      * @return pointer to first index.
220      */
221     void* makeSpace(int indexCount,
222                     const GrIndexBuffer** buffer,
223                     int* startIndex);
224 
225 private:
226     typedef GrBufferAllocPool INHERITED;
227 };
228 
229 #endif
230