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
15class GrGpu;
16
17class GrStagingBufferManager {
18public:
19 GrStagingBufferManager(GrGpu* gpu) : fGpu(gpu) {}
20
21 struct Slice {
22 Slice() {}
23 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
39 bool hasBuffers() { return !fBuffers.empty(); }
40
41 void reset() {
42 for (size_t i = 0; i < fBuffers.size(); ++i) {
43 fBuffers[i].fBuffer->unmap();
44 }
45 fBuffers.clear();
46 }
47
48private:
49 static constexpr size_t kMinStagingBufferSize = 64 * 1024;
50
51 struct StagingBuffer {
52 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
60 size_t remaining() { return fBuffer->size() - fOffset; }
61 };
62
63 std::vector<StagingBuffer> fBuffers;
64 GrGpu* fGpu;
65};
66
67#endif
68
69