Home | History | Annotate | Download | only in gpu
      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