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 "GrBuffer.h" 12 #include "GrGpuResource.h" 13 14 class GrGpu; 15 16 class GrGpuBuffer : public GrGpuResource, public GrBuffer { 17 public: 18 /** 19 * Computes a scratch key for a GPU-side buffer with a "dynamic" access pattern. (Buffers with 20 * "static" and "stream" patterns are disqualified by nature from being cached and reused.) 21 */ 22 static void ComputeScratchKeyForDynamicVBO(size_t size, GrGpuBufferType, GrScratchKey*); 23 accessPattern()24 GrAccessPattern accessPattern() const { return fAccessPattern; } 25 size()26 size_t size() const final { return fSizeInBytes; } 27 ref()28 void ref() const final { GrGpuResource::ref(); } 29 unref()30 void unref() const final { GrGpuResource::unref(); } 31 32 /** 33 * Maps the buffer to be written by the CPU. 34 * 35 * The previous content of the buffer is invalidated. It is an error 36 * to draw from the buffer while it is mapped. It may fail if the backend 37 * doesn't support mapping the buffer. If the buffer is CPU backed then 38 * it will always succeed and is a free operation. Once a buffer is mapped, 39 * subsequent calls to map() are ignored. 40 * 41 * Note that buffer mapping does not go through GrContext and therefore is 42 * not serialized with other operations. 43 * 44 * @return a pointer to the data or nullptr if the map fails. 45 */ map()46 void* map() { 47 if (!fMapPtr) { 48 this->onMap(); 49 } 50 return fMapPtr; 51 } 52 53 /** 54 * Unmaps the buffer. 55 * 56 * The pointer returned by the previous map call will no longer be valid. 57 */ unmap()58 void unmap() { 59 SkASSERT(fMapPtr); 60 this->onUnmap(); 61 fMapPtr = nullptr; 62 } 63 64 /** 65 Queries whether the buffer has been mapped. 66 67 @return true if the buffer is mapped, false otherwise. 68 */ isMapped()69 bool isMapped() const { return SkToBool(fMapPtr); } 70 isCpuBuffer()71 bool isCpuBuffer() const final { return false; } 72 73 /** 74 * Updates the buffer data. 75 * 76 * The size of the buffer will be preserved. The src data will be 77 * placed at the beginning of the buffer and any remaining contents will 78 * be undefined. srcSizeInBytes must be <= to the buffer size. 79 * 80 * The buffer must not be mapped. 81 * 82 * Note that buffer updates do not go through GrContext and therefore are 83 * not serialized with other operations. 84 * 85 * @return returns true if the update succeeds, false otherwise. 86 */ updateData(const void * src,size_t srcSizeInBytes)87 bool updateData(const void* src, size_t srcSizeInBytes) { 88 SkASSERT(!this->isMapped()); 89 SkASSERT(srcSizeInBytes <= fSizeInBytes); 90 return this->onUpdateData(src, srcSizeInBytes); 91 } 92 93 protected: 94 GrGpuBuffer(GrGpu*, size_t sizeInBytes, GrGpuBufferType, GrAccessPattern); intendedType()95 GrGpuBufferType intendedType() const { return fIntendedType; } 96 97 void* fMapPtr; 98 99 private: 100 virtual void onMap() = 0; 101 virtual void onUnmap() = 0; 102 virtual bool onUpdateData(const void* src, size_t srcSizeInBytes) = 0; 103 onGpuMemorySize()104 size_t onGpuMemorySize() const override { return fSizeInBytes; } getResourceType()105 const char* getResourceType() const override { return "Buffer Object"; } 106 void computeScratchKey(GrScratchKey* key) const override; 107 108 size_t fSizeInBytes; 109 GrAccessPattern fAccessPattern; 110 GrGpuBufferType fIntendedType; 111 }; 112 113 #endif 114