Flutter Engine
The Flutter Engine
Classes | Public Member Functions | Static Public Attributes | Protected Member Functions | List of all members
GrBufferAllocPool Class Reference

#include <GrBufferAllocPool.h>

Inheritance diagram for GrBufferAllocPool:
SkNoncopyable GrDrawIndirectBufferAllocPool GrIndexBufferAllocPool GrVertexBufferAllocPool

Classes

class  CpuBufferCache
 

Public Member Functions

void unmap ()
 
void reset ()
 
void putBack (size_t bytes)
 

Static Public Attributes

static constexpr size_t kDefaultBufferSize = 1 << 15
 

Protected Member Functions

 GrBufferAllocPool (GrGpu *gpu, GrGpuBufferType bufferType, sk_sp< CpuBufferCache > cpuBufferCache)
 
virtual ~GrBufferAllocPool ()
 
void * makeSpace (size_t size, size_t alignment, sk_sp< const GrBuffer > *buffer, size_t *offset)
 
void * makeSpaceAtLeast (size_t minSize, size_t fallbackSize, size_t alignment, sk_sp< const GrBuffer > *buffer, size_t *offset, size_t *actualSize)
 
sk_sp< GrBuffergetBuffer (size_t size)
 

Detailed Description

A pool of geometry buffers tied to a GrGpu.

The pool allows a client to make space for geometry and then put back excess space if it over allocated. When a client is ready to draw from the pool it calls unmap on the pool ensure buffers are ready for drawing. The pool can be reset after drawing is completed to recycle space.

At creation time a minimum per-buffer size can be specified. Additionally, a number of buffers to preallocate can be specified. These will be allocated at the min size and kept around until the pool is destroyed.

Definition at line 35 of file GrBufferAllocPool.h.

Constructor & Destructor Documentation

◆ GrBufferAllocPool()

GrBufferAllocPool::GrBufferAllocPool ( GrGpu gpu,
GrGpuBufferType  bufferType,
sk_sp< CpuBufferCache cpuBufferCache 
)
protected

Constructor

Parameters
gpuThe GrGpu used to create the buffers.
bufferTypeThe type of buffers to create.
cpuBufferCacheIf non-null a cache for client side array buffers or staging buffers used before data is uploaded to GPU buffer objects.

Definition at line 88 of file GrBufferAllocPool.cpp.

90 : fBlocks(8)
91 , fCpuBufferCache(std::move(cpuBufferCache))
92 , fGpu(gpu)
93 , fBufferType(bufferType) {}

◆ ~GrBufferAllocPool()

GrBufferAllocPool::~GrBufferAllocPool ( )
protectedvirtual

Definition at line 108 of file GrBufferAllocPool.cpp.

108 {
109 VALIDATE();
110 this->deleteBlocks();
111}
static void VALIDATE(bool=false)

Member Function Documentation

◆ getBuffer()

sk_sp< GrBuffer > GrBufferAllocPool::getBuffer ( size_t  size)
protected

Definition at line 413 of file GrBufferAllocPool.cpp.

413 {
414 const GrCaps& caps = *fGpu->caps();
415 auto resourceProvider = fGpu->getContext()->priv().resourceProvider();
418 // Create a CPU buffer.
419 bool mustInitialize = caps.mustClearUploadedBufferData();
420 return fCpuBufferCache ? fCpuBufferCache->makeBuffer(size, mustInitialize)
422 }
423 return resourceProvider->createBuffer(size,
424 fBufferType,
427}
@ kDynamic_GrAccessPattern
Definition: GrTypesPriv.h:426
Definition: GrCaps.h:57
bool preferClientSideDynamicBuffers() const
Definition: GrCaps.h:114
bool useClientSideIndirectBuffers() const
Definition: GrCaps.h:85
bool mustClearUploadedBufferData() const
Definition: GrCaps.h:380
static sk_sp< GrCpuBuffer > Make(size_t size)
Definition: GrCpuBuffer.h:17
GrResourceProvider * resourceProvider()
GrDirectContextPriv priv()
const GrCaps * caps() const
Definition: GrGpu.h:73
GrDirectContext * getContext()
Definition: GrGpu.h:67
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

◆ makeSpace()

void * GrBufferAllocPool::makeSpace ( size_t  size,
size_t  alignment,
sk_sp< const GrBuffer > *  buffer,
size_t *  offset 
)
protected

Returns a block of memory to hold data. A buffer designated to hold the data is given to the caller. The buffer may or may not be locked. The returned ptr remains valid until any of the following: *makeSpace is called again. *unmap is called. *reset is called. *this object is destroyed.

Once unmap on the pool is called the data is guaranteed to be in the buffer at the offset indicated by offset. Until that time it may be in temporary storage and/or the buffer may be locked.

Parameters
sizethe amount of data to make space for
alignmentalignment constraint from start of buffer
bufferreturns the buffer that will hold the data.
offsetreturns the offset into buffer of the data.
Returns
pointer to where the client should write the data.

Definition at line 189 of file GrBufferAllocPool.cpp.

192 {
193 VALIDATE();
194
197
198 if (fBufferPtr) {
199 BufferBlock& back = fBlocks.back();
200 size_t usedBytes = back.fBuffer->size() - back.fBytesFree;
201 size_t pad = align_up_pad(usedBytes, alignment);
202 SkSafeMath safeMath;
203 size_t alignedSize = safeMath.add(pad, size);
204 if (!safeMath.ok()) {
205 return nullptr;
206 }
207 if (alignedSize <= back.fBytesFree) {
208 memset((void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes), 0, pad);
209 usedBytes += pad;
210 *offset = usedBytes;
211 *buffer = back.fBuffer;
212 back.fBytesFree -= alignedSize;
213 fBytesInUse += alignedSize;
214 VALIDATE();
215 return (void*)(reinterpret_cast<intptr_t>(fBufferPtr) + usedBytes);
216 }
217 }
218
219 // We could honor the space request using by a partial update of the current
220 // VB (if there is room). But we don't currently use draw calls to GL that
221 // allow the driver to know that previously issued draws won't read from
222 // the part of the buffer we update. Also, when this was written the GL
223 // buffer implementation was cheating on the actual buffer size by shrinking
224 // the buffer in updateData() if the amount of data passed was less than
225 // the full buffer size. This is old code and both concerns may be obsolete.
226
227 if (!this->createBlock(size)) {
228 return nullptr;
229 }
230 SkASSERT(fBufferPtr);
231
232 *offset = 0;
233 BufferBlock& back = fBlocks.back();
234 *buffer = back.fBuffer;
235 back.fBytesFree -= size;
236 fBytesInUse += size;
237 VALIDATE();
238 return fBufferPtr;
239}
static size_t align_up_pad(size_t x, size_t alignment)
#define SkASSERT(cond)
Definition: SkAssert.h:116
size_t add(size_t x, size_t y)
Definition: SkSafeMath.h:33
bool ok() const
Definition: SkSafeMath.h:26
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition: switches.h:126
SeparatedVector2 offset

◆ makeSpaceAtLeast()

void * GrBufferAllocPool::makeSpaceAtLeast ( size_t  minSize,
size_t  fallbackSize,
size_t  alignment,
sk_sp< const GrBuffer > *  buffer,
size_t *  offset,
size_t *  actualSize 
)
protected

Returns a block of memory to hold data. A buffer designated to hold the data is given to the caller. The buffer may or may not be locked. The returned ptr remains valid until any of the following: *makeSpace is called again. *unmap is called. *reset is called. *this object is destroyed.

Once unmap on the pool is called the data is guaranteed to be in the buffer at the offset indicated by offset. Until that time it may be in temporary storage and/or the buffer may be locked.

The caller requests a minimum number of bytes, but the block may be (much) larger. Assuming that a new block must be allocated, it will be fallbackSize bytes. The actual block size is returned in actualSize.

Parameters
minSizethe minimum amount of data to make space for
fallbackSizethe amount of data to make space for if a new block is needed
alignmentalignment constraint from start of buffer
bufferreturns the buffer that will hold the data.
offsetreturns the offset into buffer of the data.
actualSizereturns the capacity of the block
Returns
pointer to where the client should write the data.

Definition at line 241 of file GrBufferAllocPool.cpp.

246 {
247 VALIDATE();
248
251 SkASSERT(actualSize);
252
253 size_t usedBytes = (fBlocks.empty()) ? 0 : fBlocks.back().fBuffer->size() -
254 fBlocks.back().fBytesFree;
255 size_t pad = align_up_pad(usedBytes, alignment);
256 if (!fBufferPtr || fBlocks.empty() || (minSize + pad) > fBlocks.back().fBytesFree) {
257 // We either don't have a block yet or the current block doesn't have enough free space.
258 // Create a new one.
259 if (!this->createBlock(fallbackSize)) {
260 return nullptr;
261 }
262 usedBytes = 0;
263 pad = 0;
264 }
265 SkASSERT(fBufferPtr);
266
267 // Consume padding first, to make subsequent alignment math easier
268 memset(static_cast<char*>(fBufferPtr) + usedBytes, 0, pad);
269 usedBytes += pad;
270 fBlocks.back().fBytesFree -= pad;
271 fBytesInUse += pad;
272
273 // Give caller all remaining space in this block (but aligned correctly)
274 size_t size = align_down(fBlocks.back().fBytesFree, alignment);
275 *offset = usedBytes;
276 *buffer = fBlocks.back().fBuffer;
277 *actualSize = size;
278 fBlocks.back().fBytesFree -= size;
279 fBytesInUse += size;
280 VALIDATE();
281 return static_cast<char*>(fBufferPtr) + usedBytes;
282}
static size_t align_down(size_t x, uint32_t alignment)
bool empty() const
Definition: SkTArray.h:199

◆ putBack()

void GrBufferAllocPool::putBack ( size_t  bytes)

Frees data from makeSpaces in LIFO order.

Definition at line 284 of file GrBufferAllocPool.cpp.

284 {
285 VALIDATE();
286 if (!bytes) {
287 return;
288 }
289 SkASSERT(!fBlocks.empty());
290 BufferBlock& block = fBlocks.back();
291 // Caller shouldn't try to put back more than they've taken and all those bytes should fit into
292 // one block. All the uses of this call are sequential with a single makeSpaceAtLeast call. So
293 // we should not have a case where someone is putting back bytes that are greater than the
294 // current block.
295 // It is possible the caller returns all their allocated bytes thus the <= and not just <.
296 SkASSERT(bytes <= (block.fBuffer->size() - block.fBytesFree));
297 block.fBytesFree += bytes;
298 fBytesInUse -= bytes;
299
300 // We don't allow blocks without any used bytes. So if we end up in that case after putting
301 // back the bytes then destroy the block. This scenario shouldn't occur often, but even if we
302 // end up allocating a new block immediately after destroying this one, the GPU and CPU buffers
303 // will usually be cached so the new block shouldn't be too expensive to make.
304 // TODO: This was true in older versions and uses of this class but is it still needed to
305 // have this restriction?
306 if (block.fBytesFree == block.fBuffer->size()) {
307 GrBuffer* buffer = block.fBuffer.get();
308 if (!buffer->isCpuBuffer() && static_cast<GrGpuBuffer*>(buffer)->isMapped()) {
309 UNMAP_BUFFER(block);
310 }
311 this->destroyBlock();
312 }
313
314 VALIDATE();
315}
#define UNMAP_BUFFER(block)
bool isMapped() const
Definition: GrGpuBuffer.cpp:47

◆ reset()

void GrBufferAllocPool::reset ( )

Invalidates all the data in the pool, unrefs non-preallocated buffers.

Definition at line 113 of file GrBufferAllocPool.cpp.

113 {
114 VALIDATE();
115 fBytesInUse = 0;
116 this->deleteBlocks();
117 this->resetCpuData(0);
118 VALIDATE();
119}

◆ unmap()

void GrBufferAllocPool::unmap ( )

Ensures all buffers are unmapped and have all data written to them. Call before drawing using buffers from the pool.

Definition at line 121 of file GrBufferAllocPool.cpp.

121 {
122 VALIDATE();
123
124 if (fBufferPtr) {
125 BufferBlock& block = fBlocks.back();
126 GrBuffer* buffer = block.fBuffer.get();
127 if (!buffer->isCpuBuffer()) {
128 if (static_cast<GrGpuBuffer*>(buffer)->isMapped()) {
129 UNMAP_BUFFER(block);
130 } else {
131 size_t flushSize = block.fBuffer->size() - block.fBytesFree;
132 this->flushCpuData(fBlocks.back(), flushSize);
133 }
134 }
135 fBufferPtr = nullptr;
136 }
137 VALIDATE();
138}

Member Data Documentation

◆ kDefaultBufferSize

constexpr size_t GrBufferAllocPool::kDefaultBufferSize = 1 << 15
inlinestaticconstexpr

Definition at line 37 of file GrBufferAllocPool.h.


The documentation for this class was generated from the following files: