• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // mtl_buffer_pool.h:
7 //    Defines class interface for BufferPool, managing a pool of mtl::Buffer
8 //
9 
10 #ifndef LIBANGLE_RENDERER_METAL_MTL_BUFFER_POOL_H_
11 #define LIBANGLE_RENDERER_METAL_MTL_BUFFER_POOL_H_
12 
13 #include "libANGLE/renderer/metal/mtl_resources.h"
14 
15 namespace rx
16 {
17 
18 class ContextMtl;
19 
20 namespace mtl
21 {
22 
23 // A buffer pool is conceptually an infinitely long buffer. Each time you write to the buffer,
24 // you will always write to a previously unused portion. After a series of writes, you must flush
25 // the buffer data to the device. Buffer lifetime currently assumes that each new allocation will
26 // last as long or longer than each prior allocation.
27 //
28 // Buffer pool is used to implement a variety of data streaming operations in Metal, such
29 // as for immediate vertex array and element array data, and other dynamic data.
30 //
31 // Internally buffer pool keeps a collection of mtl::Buffer. When we write past the end of a
32 // currently active mtl::Buffer we keep it until it is no longer in use. We then mark it available
33 // for future allocations in a free list.
34 class BufferPool
35 {
36   public:
37     // alwaysAllocNewBuffer=true will always allocate new buffer or reuse free buffer on allocate(),
38     // regardless of whether current buffer still has unused portion or not.
39     BufferPool(bool alwaysAllocNewBuffer = false);
40     ~BufferPool();
41 
42     // Init is called after the buffer creation so that the alignment can be specified later.
43     void initialize(ContextMtl *contextMtl,
44                     size_t initialSize,
45                     size_t alignment,
46                     size_t maxBuffers = 0);
47 
48     // This call will allocate a new region at the end of the buffer. It internally may trigger
49     // a new buffer to be created (which is returned in the optional parameter
50     // `newBufferAllocatedOut`).  The new region will be in the returned buffer at given offset. If
51     // a memory pointer is given, the buffer will be automatically map()ed.
52     angle::Result allocate(ContextMtl *contextMtl,
53                            size_t sizeInBytes,
54                            uint8_t **ptrOut            = nullptr,
55                            BufferRef *bufferOut        = nullptr,
56                            size_t *offsetOut           = nullptr,
57                            bool *newBufferAllocatedOut = nullptr);
58 
59     // After a sequence of writes, call commit to ensure the data is visible to the device.
60     angle::Result commit(ContextMtl *contextMtl);
61 
62     // This releases all the buffers that have been allocated since this was last called.
63     void releaseInFlightBuffers(ContextMtl *contextMtl);
64 
65     // This frees resources immediately.
66     void destroy(ContextMtl *contextMtl);
67 
getCurrentBuffer()68     const BufferRef &getCurrentBuffer() { return mBuffer; }
69 
getAlignment()70     size_t getAlignment() { return mAlignment; }
71     void updateAlignment(ContextMtl *contextMtl, size_t alignment);
72 
73     // Set whether allocate() will always allocate new buffer or attempting to append to previous
74     // buffer or not. Default is false.
setAlwaysAllocateNewBuffer(bool e)75     void setAlwaysAllocateNewBuffer(bool e) { mAlwaysAllocateNewBuffer = e; }
76 
77   private:
78     void reset();
79     angle::Result allocateNewBuffer(ContextMtl *contextMtl);
80     void destroyBufferList(ContextMtl *contextMtl, std::vector<BufferRef> *buffers);
81 
82     size_t mInitialSize;
83     BufferRef mBuffer;
84     uint32_t mNextAllocationOffset;
85     size_t mSize;
86     size_t mAlignment;
87 
88     std::vector<BufferRef> mInFlightBuffers;
89     std::vector<BufferRef> mBufferFreeList;
90 
91     size_t mBuffersAllocated;
92     size_t mMaxBuffers;
93     bool mAlwaysAllocateNewBuffer;
94 };
95 
96 }  // namespace mtl
97 }  // namespace rx
98 
99 #endif /* LIBANGLE_RENDERER_METAL_MTL_BUFFER_POOL_H_ */
100