• 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      */
68      GrBufferAllocPool(GrGpu* gpu,
69                        BufferType bufferType,
70                        size_t   bufferSize = 0);
71 
72      virtual ~GrBufferAllocPool();
73 
74     /**
75      * Returns a block of memory to hold data. A buffer designated to hold the
76      * data is given to the caller. The buffer may or may not be locked. The
77      * returned ptr remains valid until any of the following:
78      *      *makeSpace is called again.
79      *      *unmap is called.
80      *      *reset is called.
81      *      *this object is destroyed.
82      *
83      * Once unmap on the pool is called the data is guaranteed to be in the
84      * buffer at the offset indicated by offset. Until that time it may be
85      * in temporary storage and/or the buffer may be locked.
86      *
87      * @param size         the amount of data to make space for
88      * @param alignment    alignment constraint from start of buffer
89      * @param buffer       returns the buffer that will hold the data.
90      * @param offset       returns the offset into buffer of the data.
91      * @return pointer to where the client should write the data.
92      */
93     void* makeSpace(size_t size,
94                     size_t alignment,
95                     const GrGeometryBuffer** buffer,
96                     size_t* offset);
97 
98     GrGeometryBuffer* getBuffer(size_t size);
99 
100 private:
101     struct BufferBlock {
102         size_t              fBytesFree;
103         GrGeometryBuffer*   fBuffer;
104     };
105 
106     bool createBlock(size_t requestSize);
107     void destroyBlock();
108     void deleteBlocks();
109     void flushCpuData(const BufferBlock& block, size_t flushSize);
110     void* resetCpuData(size_t newSize);
111 #ifdef SK_DEBUG
112     void validate(bool unusedBlockAllowed = false) const;
113 #endif
114     size_t                          fBytesInUse;
115 
116     GrGpu*                          fGpu;
117     size_t                          fMinBlockSize;
118     BufferType                      fBufferType;
119 
120     SkTArray<BufferBlock>           fBlocks;
121     void*                           fCpuData;
122     void*                           fBufferPtr;
123     size_t                          fGeometryBufferMapThreshold;
124 };
125 
126 class GrVertexBuffer;
127 
128 /**
129  * A GrBufferAllocPool of vertex buffers
130  */
131 class GrVertexBufferAllocPool : public GrBufferAllocPool {
132 public:
133     /**
134      * Constructor
135      *
136      * @param gpu                   The GrGpu used to create the vertex buffers.
137      */
138     GrVertexBufferAllocPool(GrGpu* gpu);
139 
140     /**
141      * Returns a block of memory to hold vertices. A buffer designated to hold
142      * the vertices given to the caller. The buffer may or may not be locked.
143      * The returned ptr remains valid until any of the following:
144      *      *makeSpace is called again.
145      *      *unmap is called.
146      *      *reset is called.
147      *      *this object is destroyed.
148      *
149      * Once unmap on the pool is called the vertices are guaranteed to be in
150      * the buffer at the offset indicated by startVertex. Until that time they
151      * may be in temporary storage and/or the buffer may be locked.
152      *
153      * @param vertexSize   specifies size of a vertex to allocate space for
154      * @param vertexCount  number of vertices to allocate space for
155      * @param buffer       returns the vertex buffer that will hold the
156      *                     vertices.
157      * @param startVertex  returns the offset into buffer of the first vertex.
158      *                     In units of the size of a vertex from layout param.
159      * @return pointer to first vertex.
160      */
161     void* makeSpace(size_t vertexSize,
162                     int vertexCount,
163                     const GrVertexBuffer** buffer,
164                     int* startVertex);
165 
166 private:
167     typedef GrBufferAllocPool INHERITED;
168 };
169 
170 class GrIndexBuffer;
171 
172 /**
173  * A GrBufferAllocPool of index buffers
174  */
175 class GrIndexBufferAllocPool : public GrBufferAllocPool {
176 public:
177     /**
178      * Constructor
179      *
180      * @param gpu                   The GrGpu used to create the index buffers.
181      */
182     GrIndexBufferAllocPool(GrGpu* gpu);
183 
184     /**
185      * Returns a block of memory to hold indices. A buffer designated to hold
186      * the indices is given to the caller. The buffer may or may not be locked.
187      * The returned ptr remains valid until any of the following:
188      *      *makeSpace is called again.
189      *      *unmap is called.
190      *      *reset is called.
191      *      *this object is destroyed.
192      *
193      * Once unmap on the pool is called the indices are guaranteed to be in the
194      * buffer at the offset indicated by startIndex. Until that time they may be
195      * in temporary storage and/or the buffer may be locked.
196      *
197      * @param indexCount   number of indices to allocate space for
198      * @param buffer       returns the index buffer that will hold the indices.
199      * @param startIndex   returns the offset into buffer of the first index.
200      * @return pointer to first index.
201      */
202     void* makeSpace(int indexCount,
203                     const GrIndexBuffer** buffer,
204                     int* startIndex);
205 
206 private:
207     typedef GrBufferAllocPool INHERITED;
208 };
209 
210 #endif
211