Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GrRingBuffer.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google LLC
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
9
13
14// Get offset into buffer that has enough space for size
15// Returns fTotalSize if no space
16size_t GrRingBuffer::getAllocationOffset(size_t size) {
17 // capture current state locally (because fTail could be overwritten by the completion handler)
18 size_t head, tail;
19 head = fHead;
20 tail = fTail;
21
22 // The head and tail indices increment without bound, wrapping with overflow,
23 // so we need to mod them down to the actual bounds of the allocation to determine
24 // which blocks are available.
25 size_t modHead = head & (fTotalSize - 1);
26 size_t modTail = tail & (fTotalSize - 1);
27
28 bool full = (head != tail && modHead == modTail);
29
30 if (full) {
31 return fTotalSize;
32 }
33
34 // case 1: free space lies at the beginning and/or the end of the buffer
35 if (modHead >= modTail) {
36 // check for room at the end
37 if (fTotalSize - modHead < size) {
38 // no room at the end, check the beginning
39 if (modTail < size) {
40 // no room at the beginning
41 return fTotalSize;
42 }
43 // we are going to allocate from the beginning, adjust head to '0' position
44 head += fTotalSize - modHead;
45 modHead = 0;
46 }
47 // case 2: free space lies in the middle of the buffer, check for room there
48 } else if (modTail - modHead < size) {
49 // no room in the middle
50 return fTotalSize;
51 }
52
53 fHead = SkAlignTo(head + size, fAlignment);
54 return modHead;
55}
56
58 fNewAllocation = true;
59 if (fCurrentBuffer) {
60 size_t offset = this->getAllocationOffset(size);
61 if (offset < fTotalSize) {
62 return { fCurrentBuffer.get(), offset };
63 }
64
65 // Try to grow allocation (old allocation will age out).
66 fTotalSize *= 2;
67 // Add current buffer to be tracked for next submit.
68 fPreviousBuffers.push_back(std::move(fCurrentBuffer));
69 }
70
71 GrResourceProvider* resourceProvider = fGpu->getContext()->priv().resourceProvider();
72 fCurrentBuffer = resourceProvider->createBuffer(fTotalSize,
73 fType,
76
77 SkASSERT(fCurrentBuffer);
78 fHead = 0;
79 fTail = 0;
80 fGenID++;
81 size_t offset = this->getAllocationOffset(size);
82 SkASSERT(offset < fTotalSize);
83 return { fCurrentBuffer.get(), offset };
84}
85
86// used when current command buffer/command list is submitted
88 for (unsigned int i = 0; i < fPreviousBuffers.size(); ++i) {
89 fPreviousBuffers[i]->unmap();
90 gpu->takeOwnershipOfBuffer(std::move(fPreviousBuffers[i]));
91 }
92 fPreviousBuffers.clear();
93
94 if (fNewAllocation) {
95#ifdef SK_BUILD_FOR_MAC
96 // Since we're using a Managed buffer on MacOS we need to unmap to write back to GPU
97 // TODO: once we set up persistently mapped UPLOAD buffers on D3D, we can remove the
98 // platform restriction.
99 fCurrentBuffer->unmap();
100#endif
101 SubmitData* submitData = new SubmitData();
102 submitData->fOwner = this;
103 submitData->fLastHead = fHead;
104 submitData->fGenID = fGenID;
105 gpu->addFinishedProc(FinishSubmit, submitData);
106 fNewAllocation = false;
107 }
108}
109
110// used when current command buffer/command list is completed
111void GrRingBuffer::FinishSubmit(void* finishedContext) {
112 GrRingBuffer::SubmitData* submitData = (GrRingBuffer::SubmitData*)finishedContext;
113 if (submitData && submitData->fOwner && submitData->fGenID == submitData->fOwner->fGenID) {
114 submitData->fOwner->fTail = submitData->fLastHead;
115 submitData->fOwner = nullptr;
116 }
117 delete submitData;
118}
@ kDynamic_GrAccessPattern
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
Definition SkAlign.h:33
#define SkASSERT(cond)
Definition SkAssert.h:116
GrResourceProvider * resourceProvider()
GrDirectContextPriv priv()
Definition GrGpu.h:62
GrDirectContext * getContext()
Definition GrGpu.h:67
virtual void addFinishedProc(GrGpuFinishedProc finishedProc, GrGpuFinishedContext finishedContext)=0
virtual void takeOwnershipOfBuffer(sk_sp< GrGpuBuffer >)
Definition GrGpu.h:432
sk_sp< GrGpuBuffer > createBuffer(size_t size, GrGpuBufferType, GrAccessPattern, ZeroInit)
void startSubmit(GrGpu *)
Slice suballocate(size_t size)
size_t size() const
T * get() const
Definition SkRefCnt.h:303
Definition full.py:1
Point offset