GrBufferAllocPool.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  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. #ifndef GrBufferAllocPool_DEFINED
  8. #define GrBufferAllocPool_DEFINED
  9. #include "include/core/SkTypes.h"
  10. #include "include/private/GrTypesPriv.h"
  11. #include "include/private/SkNoncopyable.h"
  12. #include "include/private/SkTArray.h"
  13. #include "include/private/SkTDArray.h"
  14. #include "src/gpu/GrCpuBuffer.h"
  15. #include "src/gpu/GrNonAtomicRef.h"
  16. class GrGpu;
  17. /**
  18. * A pool of geometry buffers tied to a GrGpu.
  19. *
  20. * The pool allows a client to make space for geometry and then put back excess
  21. * space if it over allocated. When a client is ready to draw from the pool
  22. * it calls unmap on the pool ensure buffers are ready for drawing. The pool
  23. * can be reset after drawing is completed to recycle space.
  24. *
  25. * At creation time a minimum per-buffer size can be specified. Additionally,
  26. * a number of buffers to preallocate can be specified. These will
  27. * be allocated at the min size and kept around until the pool is destroyed.
  28. */
  29. class GrBufferAllocPool : SkNoncopyable {
  30. public:
  31. static constexpr size_t kDefaultBufferSize = 1 << 15;
  32. /**
  33. * A cache object that can be shared by multiple GrBufferAllocPool instances. It caches
  34. * cpu buffer allocations to avoid reallocating them.
  35. */
  36. class CpuBufferCache : public GrNonAtomicRef<CpuBufferCache> {
  37. public:
  38. static sk_sp<CpuBufferCache> Make(int maxBuffersToCache);
  39. sk_sp<GrCpuBuffer> makeBuffer(size_t size, bool mustBeInitialized);
  40. void releaseAll();
  41. private:
  42. CpuBufferCache(int maxBuffersToCache);
  43. struct Buffer {
  44. sk_sp<GrCpuBuffer> fBuffer;
  45. bool fCleared = false;
  46. };
  47. std::unique_ptr<Buffer[]> fBuffers;
  48. int fMaxBuffersToCache = 0;
  49. };
  50. /**
  51. * Ensures all buffers are unmapped and have all data written to them.
  52. * Call before drawing using buffers from the pool.
  53. */
  54. void unmap();
  55. /**
  56. * Invalidates all the data in the pool, unrefs non-preallocated buffers.
  57. */
  58. void reset();
  59. /**
  60. * Frees data from makeSpaces in LIFO order.
  61. */
  62. void putBack(size_t bytes);
  63. protected:
  64. /**
  65. * Constructor
  66. *
  67. * @param gpu The GrGpu used to create the buffers.
  68. * @param bufferType The type of buffers to create.
  69. * @param cpuBufferCache If non-null a cache for client side array buffers
  70. * or staging buffers used before data is uploaded to
  71. * GPU buffer objects.
  72. */
  73. GrBufferAllocPool(GrGpu* gpu, GrGpuBufferType bufferType, sk_sp<CpuBufferCache> cpuBufferCache);
  74. virtual ~GrBufferAllocPool();
  75. /**
  76. * Returns a block of memory to hold data. A buffer designated to hold the
  77. * data is given to the caller. The buffer may or may not be locked. The
  78. * returned ptr remains valid until any of the following:
  79. * *makeSpace is called again.
  80. * *unmap is called.
  81. * *reset is called.
  82. * *this object is destroyed.
  83. *
  84. * Once unmap on the pool is called the data is guaranteed to be in the
  85. * buffer at the offset indicated by offset. Until that time it may be
  86. * in temporary storage and/or the buffer may be locked.
  87. *
  88. * @param size the amount of data to make space for
  89. * @param alignment alignment constraint from start of buffer
  90. * @param buffer returns the buffer that will hold the data.
  91. * @param offset returns the offset into buffer of the data.
  92. * @return pointer to where the client should write the data.
  93. */
  94. void* makeSpace(size_t size, size_t alignment, sk_sp<const GrBuffer>* buffer, size_t* offset);
  95. /**
  96. * Returns a block of memory to hold data. A buffer designated to hold the
  97. * data is given to the caller. The buffer may or may not be locked. The
  98. * returned ptr remains valid until any of the following:
  99. * *makeSpace is called again.
  100. * *unmap is called.
  101. * *reset is called.
  102. * *this object is destroyed.
  103. *
  104. * Once unmap on the pool is called the data is guaranteed to be in the
  105. * buffer at the offset indicated by offset. Until that time it may be
  106. * in temporary storage and/or the buffer may be locked.
  107. *
  108. * The caller requests a minimum number of bytes, but the block may be (much)
  109. * larger. Assuming that a new block must be allocated, it will be fallbackSize bytes.
  110. * The actual block size is returned in actualSize.
  111. *
  112. * @param minSize the minimum amount of data to make space for
  113. * @param fallbackSize the amount of data to make space for if a new block is needed
  114. * @param alignment alignment constraint from start of buffer
  115. * @param buffer returns the buffer that will hold the data.
  116. * @param offset returns the offset into buffer of the data.
  117. * @param actualSize returns the capacity of the block
  118. * @return pointer to where the client should write the data.
  119. */
  120. void* makeSpaceAtLeast(size_t minSize,
  121. size_t fallbackSize,
  122. size_t alignment,
  123. sk_sp<const GrBuffer>* buffer,
  124. size_t* offset,
  125. size_t* actualSize);
  126. sk_sp<GrBuffer> getBuffer(size_t size);
  127. private:
  128. struct BufferBlock {
  129. size_t fBytesFree;
  130. sk_sp<GrBuffer> fBuffer;
  131. };
  132. bool createBlock(size_t requestSize);
  133. void destroyBlock();
  134. void deleteBlocks();
  135. void flushCpuData(const BufferBlock& block, size_t flushSize);
  136. void resetCpuData(size_t newSize);
  137. #ifdef SK_DEBUG
  138. void validate(bool unusedBlockAllowed = false) const;
  139. #endif
  140. size_t fBytesInUse = 0;
  141. SkTArray<BufferBlock> fBlocks;
  142. sk_sp<CpuBufferCache> fCpuBufferCache;
  143. sk_sp<GrCpuBuffer> fCpuStagingBuffer;
  144. GrGpu* fGpu;
  145. GrGpuBufferType fBufferType;
  146. void* fBufferPtr = nullptr;
  147. };
  148. /**
  149. * A GrBufferAllocPool of vertex buffers
  150. */
  151. class GrVertexBufferAllocPool : public GrBufferAllocPool {
  152. public:
  153. /**
  154. * Constructor
  155. *
  156. * @param gpu The GrGpu used to create the vertex buffers.
  157. * @param cpuBufferCache If non-null a cache for client side array buffers
  158. * or staging buffers used before data is uploaded to
  159. * GPU buffer objects.
  160. */
  161. GrVertexBufferAllocPool(GrGpu* gpu, sk_sp<CpuBufferCache> cpuBufferCache);
  162. /**
  163. * Returns a block of memory to hold vertices. A buffer designated to hold
  164. * the vertices given to the caller. The buffer may or may not be locked.
  165. * The returned ptr remains valid until any of the following:
  166. * *makeSpace is called again.
  167. * *unmap is called.
  168. * *reset is called.
  169. * *this object is destroyed.
  170. *
  171. * Once unmap on the pool is called the vertices are guaranteed to be in
  172. * the buffer at the offset indicated by startVertex. Until that time they
  173. * may be in temporary storage and/or the buffer may be locked.
  174. *
  175. * @param vertexSize specifies size of a vertex to allocate space for
  176. * @param vertexCount number of vertices to allocate space for
  177. * @param buffer returns the vertex buffer that will hold the
  178. * vertices.
  179. * @param startVertex returns the offset into buffer of the first vertex.
  180. * In units of the size of a vertex from layout param.
  181. * @return pointer to first vertex.
  182. */
  183. void* makeSpace(size_t vertexSize,
  184. int vertexCount,
  185. sk_sp<const GrBuffer>* buffer,
  186. int* startVertex);
  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. sk_sp<const GrBuffer>* buffer,
  218. int* startVertex,
  219. int* actualVertexCount);
  220. private:
  221. typedef GrBufferAllocPool INHERITED;
  222. };
  223. /**
  224. * A GrBufferAllocPool of index buffers
  225. */
  226. class GrIndexBufferAllocPool : public GrBufferAllocPool {
  227. public:
  228. /**
  229. * Constructor
  230. *
  231. * @param gpu The GrGpu used to create the index buffers.
  232. * @param cpuBufferCache If non-null a cache for client side array buffers
  233. * or staging buffers used before data is uploaded to
  234. * GPU buffer objects.
  235. */
  236. GrIndexBufferAllocPool(GrGpu* gpu, sk_sp<CpuBufferCache> cpuBufferCache);
  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, sk_sp<const GrBuffer>* buffer, int* startIndex);
  256. /**
  257. * Returns a block of memory to hold indices. A buffer designated to hold
  258. * the indices is given to the caller. The buffer may or may not be locked.
  259. * The returned ptr remains valid until any of the following:
  260. * *makeSpace is called again.
  261. * *unmap is called.
  262. * *reset is called.
  263. * *this object is destroyed.
  264. *
  265. * Once unmap on the pool is called the indices are guaranteed to be in the
  266. * buffer at the offset indicated by startIndex. Until that time they may be
  267. * in temporary storage and/or the buffer may be locked.
  268. *
  269. * The caller requests a minimum number of indices, but the block may be (much)
  270. * larger. Assuming that a new block must be allocated, it will be sized to hold
  271. * fallbackIndexCount indices. The actual block size (in indices) is returned in
  272. * actualIndexCount.
  273. *
  274. * @param minIndexCount minimum number of indices to allocate space for
  275. * @param fallbackIndexCount number of indices to allocate space for if a new block is needed
  276. * @param buffer returns the index buffer that will hold the indices.
  277. * @param startIndex returns the offset into buffer of the first index.
  278. * @param actualIndexCount returns the capacity of the block (in indices)
  279. * @return pointer to first index.
  280. */
  281. void* makeSpaceAtLeast(int minIndexCount,
  282. int fallbackIndexCount,
  283. sk_sp<const GrBuffer>* buffer,
  284. int* startIndex,
  285. int* actualIndexCount);
  286. private:
  287. typedef GrBufferAllocPool INHERITED;
  288. };
  289. #endif