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