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