xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrGpuBuffer.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 #ifndef GrGpuBuffer_DEFINED
9 #define GrGpuBuffer_DEFINED
10 
11 #include "include/private/gpu/ganesh/GrTypesPriv.h"
12 #include "src/gpu/ganesh/GrBuffer.h"
13 #include "src/gpu/ganesh/GrGpuResource.h"
14 
15 #include <cstddef>
16 #include <string_view>
17 
18 class GrGpu;
19 
20 namespace skgpu {
21 class ScratchKey;
22 }
23 
24 class GrGpuBuffer : public GrGpuResource, public GrBuffer {
25 public:
26     /**
27      * Computes a scratch key for a GPU-side buffer with a "dynamic" access pattern. (Buffers with
28      * "static" and "stream" patterns are disqualified by nature from being cached and reused.)
29      */
30     static void ComputeScratchKeyForDynamicBuffer(size_t size, GrGpuBufferType, skgpu::ScratchKey*);
31 
accessPattern()32     GrAccessPattern accessPattern() const { return fAccessPattern; }
33 
size()34     size_t size() const final { return fSizeInBytes; }
35 
ref()36     void ref() const final { GrGpuResource::ref(); }
37 
unref()38     void unref() const final { GrGpuResource::unref(); }
39 
40     /**
41      * Maps the buffer to be read or written by the CPU.
42      *
43      * It is an error to draw from the buffer while it is mapped or transfer to/from the buffer. It
44      * may fail if the backend doesn't support mapping the buffer. Once a buffer is mapped,
45      * subsequent calls to map() trivially succeed. No matter how many times map() is called,
46      * umap() will unmap the buffer on the first call if it is mapped.
47      *
48      * If the buffer is of type GrGpuBufferType::kXferGpuToCpu then it is mapped for reading only.
49      * Otherwise it is mapped writing only. Writing to a buffer that is mapped for reading or vice
50      * versa produces undefined results. If the buffer is mapped for writing then the buffer's
51      * previous contents are invalidated.
52      *
53      * @return a pointer to the data or nullptr if the map fails.
54      */
55     void* map();
56 
57     /**
58      * Unmaps the buffer if it is mapped.
59      *
60      * The pointer returned by the previous map call will no longer be valid.
61      */
62     void unmap();
63 
64     /**
65      * Queries whether the buffer has been mapped.
66      *
67      * @return true if the buffer is mapped, false otherwise.
68      */
69     bool isMapped() const;
70 
isCpuBuffer()71     bool isCpuBuffer() const final { return false; }
72 
73     /**
74      * Overwrites the buffer with zero bytes. Always fails for GrGpuBufferType::kXferGpuToCpu
75      * buffers. The buffer must not currently be mapped.
76      */
77     bool clearToZero();
78 
79     /**
80      * Updates the buffer data.
81      *
82      * The size of the buffer will be preserved. The src data will be
83      * placed at offset. If preserve is false then any remaining content
84      * before/after the range [offset, offset+size) becomes undefined.
85      * Preserving updates will fail if the size and offset are not aligned
86      * to GrCaps::bufferUpdateDataPreserveAlignment().
87      *
88      * The buffer must not be mapped.
89      *
90      * Fails for GrGpuBufferType::kXferGpuToCpu.
91      *
92      * Note that buffer updates do not go through GrContext and therefore are
93      * not serialized with other operations.
94      *
95      * @return returns true if the update succeeds, false otherwise.
96      */
97     bool updateData(const void* src, size_t offset, size_t size, bool preserve);
98 
intendedType()99     GrGpuBufferType intendedType() const { return fIntendedType; }
100 
101 protected:
102     GrGpuBuffer(GrGpu*,
103                 size_t sizeInBytes,
104                 GrGpuBufferType,
105                 GrAccessPattern,
106                 std::string_view label);
107 
108     enum class MapType {
109         /** Maps for reading. The effect of writes is undefined. */
110         kRead,
111         /**
112          * Maps for writing. The existing contents are discarded and the initial contents of the
113          * buffer. Reads (even after overwriting initial contents) should be avoided for performance
114          * reasons as the memory may not be cached.
115          */
116         kWriteDiscard,
117     };
118 
119     void* fMapPtr;
120 
121 private:
122     /** Currently MapType is determined entirely by the buffer type, as documented in map(). */
mapType()123     MapType mapType() const {
124         return this->intendedType() == GrGpuBufferType::kXferGpuToCpu ? MapType::kRead
125                                                                       : MapType::kWriteDiscard;
126     }
127 
128     virtual void onMap(MapType) = 0;
129     virtual void onUnmap(MapType) = 0;
130     virtual bool onClearToZero() = 0;
131     virtual bool onUpdateData(const void* src, size_t offset, size_t size, bool preserve) = 0;
132 
onGpuMemorySize()133     size_t onGpuMemorySize() const override { return fSizeInBytes; }
onSetLabel()134     void onSetLabel() override{}
getResourceType()135     const char* getResourceType() const override { return "Buffer Object"; }
136     void computeScratchKey(skgpu::ScratchKey* key) const override;
137 
138     size_t            fSizeInBytes;
139     GrAccessPattern   fAccessPattern;
140     GrGpuBufferType   fIntendedType;
141 };
142 
143 #endif
144