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 
8 #ifndef GrStagingBufferManager_DEFINED
9 #define GrStagingBufferManager_DEFINED
10 
11 #include "include/core/SkRefCnt.h"
12 #include "src/gpu/GrGpuBuffer.h"
13 #include <vector>
14 
15 class GrGpu;
16 
17 class GrStagingBufferManager {
18 public:
GrStagingBufferManager(GrGpu * gpu)19     GrStagingBufferManager(GrGpu* gpu) : fGpu(gpu) {}
20 
21     struct Slice {
SliceSlice22         Slice() {}
SliceSlice23         Slice(GrGpuBuffer* buffer, size_t offset, void* offsetMapPtr)
24                 : fBuffer(buffer), fOffset(offset), fOffsetMapPtr(offsetMapPtr) {}
25         GrGpuBuffer* fBuffer = nullptr;
26         size_t fOffset = 0;
27         void* fOffsetMapPtr = nullptr;
28     };
29 
30     Slice allocateStagingBufferSlice(size_t size, size_t requiredAlignment = 1);
31 
32     // This call is used to move all the buffers off of the manager and to backend gpu by calling
33     // the virtual GrGpu::takeOwnershipOfBuffer on each buffer. This is called during
34     // submitToGpu. It is up to the backend to take refs to the buffers in their implemented
35     // takeOwnershipOfBuffer implementation if they need to. After this call returns the
36     // manager will have released all refs to its buffers.
37     void detachBuffers();
38 
hasBuffers()39     bool hasBuffers() { return !fBuffers.empty(); }
40 
reset()41     void reset() {
42         for (size_t i = 0; i < fBuffers.size(); ++i) {
43             fBuffers[i].fBuffer->unmap();
44         }
45         fBuffers.clear();
46     }
47 
48 private:
49     static constexpr size_t kMinStagingBufferSize = 64 * 1024;
50 
51     struct StagingBuffer {
StagingBufferStagingBuffer52         StagingBuffer(sk_sp<GrGpuBuffer> buffer, void* mapPtr)
53                 : fBuffer(std::move(buffer))
54                 , fMapPtr(mapPtr) {}
55 
56         sk_sp<GrGpuBuffer> fBuffer;
57         void* fMapPtr;
58         size_t fOffset = 0;
59 
remainingStagingBuffer60         size_t remaining() { return fBuffer->size() - fOffset; }
61     };
62 
63     std::vector<StagingBuffer> fBuffers;
64     GrGpu* fGpu;
65 };
66 
67 #endif
68 
69