• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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/graphite/UploadBufferManager.h"
9 
10 #include "include/gpu/graphite/Recording.h"
11 #include "include/private/base/SkAlign.h"
12 #include "src/gpu/graphite/Buffer.h"
13 #include "src/gpu/graphite/Caps.h"
14 #include "src/gpu/graphite/RecordingPriv.h"
15 #include "src/gpu/graphite/ResourceProvider.h"
16 
17 namespace skgpu::graphite {
18 
19 static constexpr size_t kReusedBufferSize = 64 << 10;  // 64 KB
20 
UploadBufferManager(ResourceProvider * resourceProvider,const Caps * caps)21 UploadBufferManager::UploadBufferManager(ResourceProvider* resourceProvider,
22                                          const Caps* caps)
23         : fResourceProvider(resourceProvider)
24         , fMinAlignment(caps->requiredTransferBufferAlignment()) {}
25 
~UploadBufferManager()26 UploadBufferManager::~UploadBufferManager() {}
27 
getUploadWriter(size_t requiredBytes,size_t requiredAlignment)28 std::tuple<UploadWriter, BindBufferInfo> UploadBufferManager::getUploadWriter(
29         size_t requiredBytes, size_t requiredAlignment) {
30     if (!requiredBytes) {
31         return {UploadWriter(), BindBufferInfo()};
32     }
33 
34     requiredAlignment = std::max(requiredAlignment, fMinAlignment);
35     requiredBytes = SkAlignTo(requiredBytes, requiredAlignment);
36     if (requiredBytes > kReusedBufferSize) {
37         // Create a dedicated buffer for this request.
38         sk_sp<Buffer> buffer = fResourceProvider->findOrCreateBuffer(
39                 requiredBytes, BufferType::kXferCpuToGpu, PrioritizeGpuReads::kNo);
40 
41         BindBufferInfo bindInfo;
42         bindInfo.fBuffer = buffer.get();
43         bindInfo.fOffset = 0;
44 
45         void* bufferMapPtr = buffer->map();
46         fUsedBuffers.push_back(std::move(buffer));
47         return {UploadWriter(bufferMapPtr, requiredBytes), bindInfo};
48     }
49 
50     // Try to reuse an already-allocated buffer.
51     fReusedBufferOffset = SkAlignTo(fReusedBufferOffset, requiredAlignment);
52     if (fReusedBuffer && requiredBytes > fReusedBuffer->size() - fReusedBufferOffset) {
53         fUsedBuffers.push_back(std::move(fReusedBuffer));
54     }
55 
56     if (!fReusedBuffer) {
57         fReusedBuffer = fResourceProvider->findOrCreateBuffer(
58                 kReusedBufferSize, BufferType::kXferCpuToGpu, PrioritizeGpuReads::kNo);
59         fReusedBufferOffset = 0;
60         if (!fReusedBuffer) {
61             return {UploadWriter(), BindBufferInfo()};
62         }
63     }
64 
65     BindBufferInfo bindInfo;
66     bindInfo.fBuffer = fReusedBuffer.get();
67     bindInfo.fOffset = fReusedBufferOffset;
68 
69     void* bufferMapPtr = fReusedBuffer->map();
70     bufferMapPtr = SkTAddOffset<void>(bufferMapPtr, fReusedBufferOffset);
71 
72     fReusedBufferOffset += requiredBytes;
73     return {UploadWriter(bufferMapPtr, requiredBytes), bindInfo};
74 }
75 
transferToRecording(Recording * recording)76 void UploadBufferManager::transferToRecording(Recording* recording) {
77     for (sk_sp<Buffer>& buffer : fUsedBuffers) {
78         buffer->unmap();
79         recording->priv().addResourceRef(std::move(buffer));
80     }
81     fUsedBuffers.clear();
82 
83     if (fReusedBuffer) {
84         fReusedBuffer->unmap();
85         recording->priv().addResourceRef(std::move(fReusedBuffer));
86     }
87 }
88 
89 }  // namespace skgpu::graphite
90