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