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