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 
     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