xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrStagingBufferManager.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 #include "src/gpu/ganesh/GrStagingBufferManager.h"
8 
9 #include "include/gpu/ganesh/GrContextOptions.h"
10 #include "include/gpu/ganesh/GrDirectContext.h"
11 #include "include/private/base/SkAssert.h"
12 #include "include/private/gpu/ganesh/GrTypesPriv.h"
13 #include "src/gpu/ganesh/GrDirectContextPriv.h"
14 #include "src/gpu/ganesh/GrGpu.h"
15 #include "src/gpu/ganesh/GrResourceProvider.h"
16 
17 #include <algorithm>
18 
allocateStagingBufferSlice(size_t size,size_t requiredAlignment)19 GrStagingBufferManager::Slice GrStagingBufferManager::allocateStagingBufferSlice(
20         size_t size, size_t requiredAlignment) {
21     StagingBuffer* buffer = nullptr;
22     size_t offset = 0;
23     for (size_t i = 0; i < fBuffers.size(); ++i) {
24         size_t totalBufferSize = fBuffers[i].fBuffer->size();
25         size_t currentOffset = fBuffers[i].fOffset;
26         offset = ((currentOffset + requiredAlignment - 1)/requiredAlignment)*requiredAlignment;
27         if (totalBufferSize - offset >= size) {
28             buffer = &fBuffers[i];
29             break;
30         }
31     }
32 
33     if (!buffer) {
34         GrResourceProvider* resourceProvider = fGpu->getContext()->priv().resourceProvider();
35         size_t minSize = fGpu->getContext()->priv().options().fMinimumStagingBufferSize;
36         size_t bufferSize = std::max(size, minSize);
37         sk_sp<GrGpuBuffer> newBuffer = resourceProvider->createBuffer(
38                 bufferSize,
39                 GrGpuBufferType::kXferCpuToGpu,
40                 kDynamic_GrAccessPattern,
41                 GrResourceProvider::ZeroInit::kNo);
42         if (!newBuffer) {
43             return {}; // invalid slice
44         }
45         void* mapPtr = newBuffer->map();
46         if (!mapPtr) {
47             return {}; // invalid slice
48         }
49         fBuffers.emplace_back(std::move(newBuffer), mapPtr);
50         buffer = &fBuffers.back();
51         offset = 0;
52     }
53 
54     SkASSERT(buffer);
55     SkASSERT(buffer->remaining() >= size);
56 
57     buffer->fOffset = offset + size;
58     char* offsetMapPtr = static_cast<char*>(buffer->fMapPtr) + offset;
59     return {buffer->fBuffer.get(), offset, offsetMapPtr};
60 }
61 
detachBuffers()62 void GrStagingBufferManager::detachBuffers() {
63     for (size_t i = 0; i < fBuffers.size(); ++i) {
64         fBuffers[i].fBuffer->unmap();
65         fGpu->takeOwnershipOfBuffer(std::move(fBuffers[i].fBuffer));
66     }
67     fBuffers.clear();
68 }
69