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