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/GrContextPriv.h"
12#include "src/gpu/GrGpu.h"
13#include "src/gpu/GrResourceProvider.h"
14
15GrStagingBufferManager::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 = GrAlignTo(currentOffset, 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
54void 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