1 /*
2 * Copyright 2019 Google Inc.
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/ganesh/GrGpuBuffer.h"
9
10 #include "include/private/base/SkAlign.h"
11 #include "include/private/base/SkAssert.h"
12 #include "include/private/base/SkTo.h"
13 #include "src/gpu/ResourceKey.h"
14 #include "src/gpu/ganesh/GrCaps.h"
15 #include "src/gpu/ganesh/GrGpu.h"
16
17 #include <cstdint>
18
GrGpuBuffer(GrGpu * gpu,size_t sizeInBytes,GrGpuBufferType type,GrAccessPattern pattern,std::string_view label)19 GrGpuBuffer::GrGpuBuffer(GrGpu* gpu, size_t sizeInBytes, GrGpuBufferType type,
20 GrAccessPattern pattern,
21 std::string_view label)
22 : GrGpuResource(gpu, label)
23 , fMapPtr(nullptr)
24 , fSizeInBytes(sizeInBytes)
25 , fAccessPattern(pattern)
26 , fIntendedType(type) {}
27
map()28 void* GrGpuBuffer::map() {
29 if (this->wasDestroyed()) {
30 return nullptr;
31 }
32 if (!fMapPtr) {
33 this->onMap(this->mapType());
34 }
35 return fMapPtr;
36 }
37
unmap()38 void GrGpuBuffer::unmap() {
39 if (this->wasDestroyed()) {
40 return;
41 }
42 SkASSERT(fMapPtr);
43 this->onUnmap(this->mapType());
44 fMapPtr = nullptr;
45 }
46
isMapped() const47 bool GrGpuBuffer::isMapped() const { return SkToBool(fMapPtr); }
48
clearToZero()49 bool GrGpuBuffer::clearToZero() {
50 SkASSERT(!this->isMapped());
51
52 if (this->wasDestroyed()) {
53 return false;
54 }
55
56 if (this->intendedType() == GrGpuBufferType::kXferGpuToCpu) {
57 return false;
58 }
59
60 return this->onClearToZero();
61 }
62
updateData(const void * src,size_t offset,size_t size,bool preserve)63 bool GrGpuBuffer::updateData(const void* src, size_t offset, size_t size, bool preserve) {
64 SkASSERT(!this->isMapped());
65 SkASSERT(size > 0 && offset + size <= fSizeInBytes);
66 SkASSERT(src);
67
68 if (this->wasDestroyed()) {
69 return false;
70 }
71
72 if (preserve) {
73 size_t a = this->getGpu()->caps()->bufferUpdateDataPreserveAlignment();
74 if (SkAlignTo(offset, a) != offset || SkAlignTo(size, a) != size) {
75 return false;
76 }
77 }
78
79 if (this->intendedType() == GrGpuBufferType::kXferGpuToCpu) {
80 return false;
81 }
82
83 return this->onUpdateData(src, offset, size, preserve);
84 }
85
ComputeScratchKeyForDynamicBuffer(size_t size,GrGpuBufferType intendedType,skgpu::ScratchKey * key)86 void GrGpuBuffer::ComputeScratchKeyForDynamicBuffer(size_t size,
87 GrGpuBufferType intendedType,
88 skgpu::ScratchKey* key) {
89 static const skgpu::ScratchKey::ResourceType kType = skgpu::ScratchKey::GenerateResourceType();
90 skgpu::ScratchKey::Builder builder(key, kType, 1 + (sizeof(size_t) + 3) / 4);
91 builder[0] = SkToU32(intendedType);
92 builder[1] = (uint32_t)size;
93 if (sizeof(size_t) > 4) {
94 builder[2] = (uint32_t)((uint64_t)size >> 32);
95 }
96 }
97
computeScratchKey(skgpu::ScratchKey * key) const98 void GrGpuBuffer::computeScratchKey(skgpu::ScratchKey* key) const {
99 if (kDynamic_GrAccessPattern == fAccessPattern) {
100 ComputeScratchKeyForDynamicBuffer(fSizeInBytes, fIntendedType, key);
101 }
102 }
103