Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrBufferAllocPool.h
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 unlock 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 unlocked and have all data written to them.
34      * Call before drawing using buffers from the pool.
35      */
36     void unlock();
37
38     /**
39      *  Invalidates all the data in the pool, unrefs non-preallocated buffers.
40      */
41     void reset();
42
43     /**
44      * Gets the number of preallocated buffers that are yet to be used.
45      */
46     int preallocatedBuffersRemaining() const;
47
48     /**
49      * gets the number of preallocated buffers
50      */
51     int preallocatedBufferCount() const;
52
53     /**
54      * Frees data from makeSpaces in LIFO order.
55      */
56     void putBack(size_t bytes);
57
58     /**
59      * Gets the GrGpu that this pool is associated with.
60      */
61     GrGpu* getGpu() { return fGpu; }
62
63 protected:
64     /**
65      * Used to determine what type of buffers to create. We could make the
66      * createBuffer a virtual except that we want to use it in the cons for
67      * pre-allocated buffers.
68      */
69     enum BufferType {
70         kVertex_BufferType,
71         kIndex_BufferType,
72     };
73
74     /**
75      * Constructor
76      *
77      * @param gpu                   The GrGpu used to create the buffers.
78      * @param bufferType            The type of buffers to create.
79      * @param frequentResetHint     A hint that indicates that the pool
80      *                              should expect frequent unlock() calls
81      *                              (as opposed to many makeSpace / acquires
82      *                              between resets).
83      * @param bufferSize            The minimum size of created buffers.
84      *                              This value will be clamped to some
85      *                              reasonable minimum.
86      * @param preallocBufferCnt     The pool will allocate this number of
87      *                              buffers at bufferSize and keep them until it
88      *                              is destroyed.
89      */
90      GrBufferAllocPool(GrGpu* gpu,
91                        BufferType bufferType,
92                        bool frequentResetHint,
93                        size_t   bufferSize = 0,
94                        int preallocBufferCnt = 0);
95
96     virtual ~GrBufferAllocPool();
97
98     /**
99      * Gets the size of the preallocated buffers.
100      *
101      * @return the size of preallocated buffers.
102      */
103     size_t preallocatedBufferSize() const {
104         return fPreallocBuffers.count() ? fMinBlockSize : 0;
105     }
106
107     /**
108      * Returns a block of memory to hold data. A buffer designated to hold the
109      * data is given to the caller. The buffer may or may not be locked. The
110      * returned ptr remains valid until any of the following:
111      *      *makeSpace is called again.
112      *      *unlock is called.
113      *      *reset is called.
114      *      *this object is destroyed.
115      *
116      * Once unlock on the pool is called the data is guaranteed to be in the
117      * buffer at the offset indicated by offset. Until that time it may be
118      * in temporary storage and/or the buffer may be locked.
119      *
120      * @param size         the amount of data to make space for
121      * @param alignment    alignment constraint from start of buffer
122      * @param buffer       returns the buffer that will hold the data.
123      * @param offset       returns the offset into buffer of the data.
124      * @return pointer to where the client should write the data.
125      */
126     void* makeSpace(size_t size,
127                     size_t alignment,
128                     const GrGeometryBuffer** buffer,
129                     size_t* offset);
130
131     /**
132      * Gets the number of items of a size that can be added to the current
133      * buffer without spilling to another buffer. If the pool has been reset, or
134      * the previous makeSpace completely exhausted a buffer then the returned
135      * size will be the size of the next available preallocated buffer, or zero
136      * if no preallocated buffer remains available. It is assumed that items
137      * should be itemSize-aligned from the start of a buffer.
138      *
139      * @return the number of items that would fit in the current buffer.
140      */
141     int currentBufferItems(size_t itemSize) const;
142
143     GrGeometryBuffer* createBuffer(size_t size);
144
145 private:
146
147     // The GrGpu must be able to clear the ref of pools it creates as members
148     friend class GrGpu;
149     void releaseGpuRef();
150
151     struct BufferBlock {
152         size_t              fBytesFree;
153         GrGeometryBuffer*   fBuffer;
154     };
155
156     bool createBlock(size_t requestSize);
157     void destroyBlock();
158     void flushCpuData(GrGeometryBuffer* buffer, size_t flushSize);
159 #ifdef SK_DEBUG
160     void validate(bool unusedBlockAllowed = false) const;
161 #endif
162
163     size_t                          fBytesInUse;
164
165     GrGpu*                          fGpu;
166     bool                            fGpuIsReffed;
167     bool                            fFrequentResetHint;
168     SkTDArray<GrGeometryBuffer*>    fPreallocBuffers;
169     size_t                          fMinBlockSize;
170     BufferType                      fBufferType;
171
172     SkTArray<BufferBlock>           fBlocks;
173     int                             fPreallocBuffersInUse;
174     // We attempt to cycle through the preallocated buffers rather than
175     // always starting from the first.
176     int                             fPreallocBufferStartIdx;
177     SkAutoMalloc                    fCpuData;
178     void*                           fBufferPtr;
179 };
180
181 class GrVertexBuffer;
182
183 /**
184  * A GrBufferAllocPool of vertex buffers
185  */
186 class GrVertexBufferAllocPool : public GrBufferAllocPool {
187 public:
188     /**
189      * Constructor
190      *
191      * @param gpu                   The GrGpu used to create the vertex buffers.
192      * @param frequentResetHint     A hint that indicates that the pool
193      *                              should expect frequent unlock() calls
194      *                              (as opposed to many makeSpace / acquires
195      *                              between resets).
196      * @param bufferSize            The minimum size of created VBs This value
197      *                              will be clamped to some reasonable minimum.
198      * @param preallocBufferCnt     The pool will allocate this number of VBs at
199      *                              bufferSize and keep them until it is
200      *                              destroyed.
201      */
202     GrVertexBufferAllocPool(GrGpu* gpu,
203                             bool frequentResetHint,
204                             size_t bufferSize = 0,
205                             int preallocBufferCnt = 0);
206
207     /**
208      * Returns a block of memory to hold vertices. A buffer designated to hold
209      * the vertices given to the caller. The buffer may or may not be locked.
210      * The returned ptr remains valid until any of the following:
211      *      *makeSpace is called again.
212      *      *unlock is called.
213      *      *reset is called.
214      *      *this object is destroyed.
215      *
216      * Once unlock on the pool is called the vertices are guaranteed to be in
217      * the buffer at the offset indicated by startVertex. Until that time they
218      * may be in temporary storage and/or the buffer may be locked.
219      *
220      * @param vertexSize   specifies size of a vertex to allocate space for
221      * @param vertexCount  number of vertices to allocate space for
222      * @param buffer       returns the vertex buffer that will hold the
223      *                     vertices.
224      * @param startVertex  returns the offset into buffer of the first vertex.
225      *                     In units of the size of a vertex from layout param.
226      * @return pointer to first vertex.
227      */
228     void* makeSpace(size_t vertexSize,
229                     int vertexCount,
230                     const GrVertexBuffer** buffer,
231                     int* startVertex);
232
233     /**
234      * Shortcut to make space and then write verts into the made space.
235      */
236     bool appendVertices(size_t vertexSize,
237                         int vertexCount,
238                         const void* vertices,
239                         const GrVertexBuffer** buffer,
240                         int* startVertex);
241
242     /**
243      * Gets the number of vertices that can be added to the current VB without
244      * spilling to another VB. If the pool has been reset, or the previous
245      * makeSpace completely exhausted a VB then the returned number of vertices
246      * would fit in the next available preallocated buffer. If any makeSpace
247      * would force a new VB to be created the return value will be zero.
248      *
249      * @param   the size of a vertex to compute space for.
250      * @return the number of vertices that would fit in the current buffer.
251      */
252     int currentBufferVertices(size_t vertexSize) const;
253
254     /**
255      * Gets the number of vertices that can fit in a  preallocated vertex buffer.
256      * Zero if no preallocated buffers.
257      *
258      * @param   the size of a vertex to compute space for.
259      *
260      * @return number of vertices that fit in one of the preallocated vertex
261      *         buffers.
262      */
263     int preallocatedBufferVertices(size_t vertexSize) const;
264
265 private:
266     typedef GrBufferAllocPool INHERITED;
267 };
268
269 class GrIndexBuffer;
270
271 /**
272  * A GrBufferAllocPool of index buffers
273  */
274 class GrIndexBufferAllocPool : public GrBufferAllocPool {
275 public:
276     /**
277      * Constructor
278      *
279      * @param gpu                   The GrGpu used to create the index buffers.
280      * @param frequentResetHint     A hint that indicates that the pool
281      *                              should expect frequent unlock() calls
282      *                              (as opposed to many makeSpace / acquires
283      *                              between resets).
284      * @param bufferSize            The minimum size of created IBs This value
285      *                              will be clamped to some reasonable minimum.
286      * @param preallocBufferCnt     The pool will allocate this number of VBs at
287      *                              bufferSize and keep them until it is
288      *                              destroyed.
289      */
290     GrIndexBufferAllocPool(GrGpu* gpu,
291                            bool frequentResetHint,
292                            size_t bufferSize = 0,
293                            int preallocBufferCnt = 0);
294
295     /**
296      * Returns a block of memory to hold indices. A buffer designated to hold
297      * the indices is given to the caller. The buffer may or may not be locked.
298      * The returned ptr remains valid until any of the following:
299      *      *makeSpace is called again.
300      *      *unlock is called.
301      *      *reset is called.
302      *      *this object is destroyed.
303      *
304      * Once unlock on the pool is called the indices are guaranteed to be in the
305      * buffer at the offset indicated by startIndex. Until that time they may be
306      * in temporary storage and/or the buffer may be locked.
307      *
308      * @param indexCount   number of indices to allocate space for
309      * @param buffer       returns the index buffer that will hold the indices.
310      * @param startIndex   returns the offset into buffer of the first index.
311      * @return pointer to first index.
312      */
313     void* makeSpace(int indexCount,
314                     const GrIndexBuffer** buffer,
315                     int* startIndex);
316
317     /**
318      * Shortcut to make space and then write indices into the made space.
319      */
320     bool appendIndices(int indexCount,
321                        const void* indices,
322                        const GrIndexBuffer** buffer,
323                        int* startIndex);
324
325     /**
326      * Gets the number of indices that can be added to the current IB without
327      * spilling to another IB. If the pool has been reset, or the previous
328      * makeSpace completely exhausted a IB then the returned number of indices
329      * would fit in the next available preallocated buffer. If any makeSpace
330      * would force a new IB to be created the return value will be zero.
331      */
332     int currentBufferIndices() const;
333
334     /**
335      * Gets the number of indices that can fit in a preallocated index buffer.
336      * Zero if no preallocated buffers.
337      *
338      * @return number of indices that fit in one of the preallocated index
339      *         buffers.
340      */
341     int preallocatedBufferIndices() const;
342
343 private:
344     typedef GrBufferAllocPool INHERITED;
345 };
346
347 #endif