Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
UploadBufferManager.cpp
Go to the documentation of this file.
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
9
17
18namespace skgpu::graphite {
19
20static constexpr size_t kReusedBufferSize = 64 << 10; // 64 KB
21
23 const Caps* caps)
24 : fResourceProvider(resourceProvider)
25 , fMinAlignment(caps->requiredTransferBufferAlignment()) {}
26
28
29std::tuple<TextureUploadWriter, BindBufferInfo> UploadBufferManager::getTextureUploadWriter(
30 size_t requiredBytes, size_t requiredAlignment) {
31 auto[bufferMapPtr, bindInfo] = this->makeBindInfo(requiredBytes,
32 requiredAlignment,
33 "TextureUploadBuffer");
34 if (!bufferMapPtr) {
36 }
37
38 return {TextureUploadWriter(bufferMapPtr, requiredBytes), bindInfo};
39}
40
41std::tuple<void*/*mappedPtr*/, BindBufferInfo> UploadBufferManager::makeBindInfo(
42 size_t requiredBytes, size_t requiredAlignment, std::string_view label) {
43 if (!requiredBytes) {
44 return {nullptr, BindBufferInfo()};
45 }
46
47 requiredAlignment = std::max(requiredAlignment, fMinAlignment);
48 requiredBytes = SkAlignTo(requiredBytes, requiredAlignment);
49 if (requiredBytes > kReusedBufferSize) {
50 // Create a dedicated buffer for this request.
51 sk_sp<Buffer> buffer = fResourceProvider->findOrCreateBuffer(requiredBytes,
54 std::move(label));
55 void* bufferMapPtr = buffer ? buffer->map() : nullptr;
56 if (!bufferMapPtr) {
57 // Unlike [Draw|Static]BufferManager, the UploadManager does not track if any buffer
58 // mapping has failed. This is because it's common for uploads to be scoped to a
59 // specific image creation. In that case, the image can be returned as null to signal a
60 // very isolated failure instead of taking down the entire Recording. For the other
61 // managers, failures to map buffers creates unrecoverable scenarios.
62 return {nullptr, BindBufferInfo()};
63 }
64
65 BindBufferInfo bindInfo;
66 bindInfo.fBuffer = buffer.get();
67 bindInfo.fOffset = 0;
68
69 fUsedBuffers.push_back(std::move(buffer));
70 return {bufferMapPtr, bindInfo};
71 }
72
73 // Try to reuse an already-allocated buffer.
74 fReusedBufferOffset = SkAlignTo(fReusedBufferOffset, requiredAlignment);
75 if (fReusedBuffer && requiredBytes > fReusedBuffer->size() - fReusedBufferOffset) {
76 fUsedBuffers.push_back(std::move(fReusedBuffer));
77 }
78
79 if (!fReusedBuffer) {
80 fReusedBuffer = fResourceProvider->findOrCreateBuffer(kReusedBufferSize,
83 std::move(label));
84 fReusedBufferOffset = 0;
85 if (!fReusedBuffer || !fReusedBuffer->map()) {
86 fReusedBuffer = nullptr;
87 return {nullptr, BindBufferInfo()};
88 }
89 }
90
91 BindBufferInfo bindInfo;
92 bindInfo.fBuffer = fReusedBuffer.get();
93 bindInfo.fOffset = fReusedBufferOffset;
94
95 void* bufferMapPtr = fReusedBuffer->map();
96 SkASSERT(bufferMapPtr); // Should have been validated when it was created
97 bufferMapPtr = SkTAddOffset<void>(bufferMapPtr, fReusedBufferOffset);
98
99 fReusedBufferOffset += requiredBytes;
100
101 return {bufferMapPtr, bindInfo};
102}
103
105 for (sk_sp<Buffer>& buffer : fUsedBuffers) {
106 buffer->unmap();
107 recording->priv().addResourceRef(std::move(buffer));
108 }
109 fUsedBuffers.clear();
110
111 if (fReusedBuffer) {
112 fReusedBuffer->unmap();
113 recording->priv().addResourceRef(std::move(fReusedBuffer));
114 }
115}
116
118 for (sk_sp<Buffer>& buffer : fUsedBuffers) {
119 buffer->unmap();
120 commandBuffer->trackResource(std::move(buffer));
121 }
122 fUsedBuffers.clear();
123
124 if (fReusedBuffer) {
125 fReusedBuffer->unmap();
126 commandBuffer->trackResource(std::move(fReusedBuffer));
127 }
128}
129
130} // namespace skgpu::graphite
static constexpr size_t SkAlignTo(size_t x, size_t alignment)
Definition SkAlign.h:33
#define SkASSERT(cond)
Definition SkAssert.h:116
void trackResource(sk_sp< Resource > resource)
void addResourceRef(sk_sp< Resource > resource)
sk_sp< Buffer > findOrCreateBuffer(size_t size, BufferType type, AccessPattern, std::string_view label)
std::tuple< TextureUploadWriter, BindBufferInfo > getTextureUploadWriter(size_t requiredBytes, size_t requiredAlignment)
UploadBufferManager(ResourceProvider *, const Caps *)
static const uint8_t buffer[]
static constexpr size_t kReusedBufferSize