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