1 /* 2 * Copyright 2016 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 GrBuffer_DEFINED 9 #define GrBuffer_DEFINED 10 11 #include "GrGpuResource.h" 12 13 class GrGpu; 14 15 class GrBuffer : public GrGpuResource { 16 public: 17 /** 18 * Creates a client-side buffer. 19 */ 20 static SK_WARN_UNUSED_RESULT GrBuffer* CreateCPUBacked(GrGpu*, size_t sizeInBytes, GrBufferType, 21 const void* data = nullptr); 22 23 /** 24 * Computes a scratch key for a GPU-side buffer with a "dynamic" access pattern. (Buffers with 25 * "static" and "stream" patterns are disqualified by nature from being cached and reused.) 26 */ 27 static void ComputeScratchKeyForDynamicVBO(size_t size, GrBufferType, GrScratchKey*); 28 29 GrAccessPattern accessPattern() const { return fAccessPattern; } 30 size_t sizeInBytes() const { return fSizeInBytes; } 31 32 /** 33 * Returns true if the buffer is a wrapper around a CPU array. If true it 34 * indicates that map will always succeed and will be free. 35 */ 36 bool isCPUBacked() const { return SkToBool(fCPUData); } 37 size_t baseOffset() const { return reinterpret_cast<size_t>(fCPUData); } 38 39 /** 40 * Maps the buffer to be written by the CPU. 41 * 42 * The previous content of the buffer is invalidated. It is an error 43 * to draw from the buffer while it is mapped. It may fail if the backend 44 * doesn't support mapping the buffer. If the buffer is CPU backed then 45 * it will always succeed and is a free operation. Once a buffer is mapped, 46 * subsequent calls to map() are ignored. 47 * 48 * Note that buffer mapping does not go through GrContext and therefore is 49 * not serialized with other operations. 50 * 51 * @return a pointer to the data or nullptr if the map fails. 52 */ 53 void* map() { 54 if (!fMapPtr) { 55 this->onMap(); 56 } 57 return fMapPtr; 58 } 59 60 /** 61 * Unmaps the buffer. 62 * 63 * The pointer returned by the previous map call will no longer be valid. 64 */ 65 void unmap() { 66 SkASSERT(fMapPtr); 67 this->onUnmap(); 68 fMapPtr = nullptr; 69 } 70 71 /** 72 * Returns the same ptr that map() returned at time of map or nullptr if the 73 * is not mapped. 74 * 75 * @return ptr to mapped buffer data or nullptr if buffer is not mapped. 76 */ 77 void* mapPtr() const { return fMapPtr; } 78 79 /** 80 Queries whether the buffer has been mapped. 81 82 @return true if the buffer is mapped, false otherwise. 83 */ 84 bool isMapped() const { return SkToBool(fMapPtr); } 85 86 /** 87 * Updates the buffer data. 88 * 89 * The size of the buffer will be preserved. The src data will be 90 * placed at the beginning of the buffer and any remaining contents will 91 * be undefined. srcSizeInBytes must be <= to the buffer size. 92 * 93 * The buffer must not be mapped. 94 * 95 * Note that buffer updates do not go through GrContext and therefore are 96 * not serialized with other operations. 97 * 98 * @return returns true if the update succeeds, false otherwise. 99 */ 100 bool updateData(const void* src, size_t srcSizeInBytes) { 101 SkASSERT(!this->isMapped()); 102 SkASSERT(srcSizeInBytes <= fSizeInBytes); 103 return this->onUpdateData(src, srcSizeInBytes); 104 } 105 106 ~GrBuffer() override { 107 sk_free(fCPUData); 108 } 109 110 protected: 111 GrBuffer(GrGpu*, size_t sizeInBytes, GrBufferType, GrAccessPattern); 112 113 void* fMapPtr; 114 115 private: 116 /** 117 * Internal constructor to make a CPU-backed buffer. 118 */ 119 GrBuffer(GrGpu*, size_t sizeInBytes, GrBufferType, void* cpuData); 120 121 virtual void onMap() { SkASSERT(this->isCPUBacked()); fMapPtr = fCPUData; } 122 virtual void onUnmap() { SkASSERT(this->isCPUBacked()); } 123 virtual bool onUpdateData(const void* src, size_t srcSizeInBytes); 124 125 size_t onGpuMemorySize() const override { return fSizeInBytes; } // TODO: zero for cpu backed? 126 void computeScratchKey(GrScratchKey* key) const override; 127 128 size_t fSizeInBytes; 129 GrAccessPattern fAccessPattern; 130 void* fCPUData; 131 GrBufferType fIntendedType; 132 133 typedef GrGpuResource INHERITED; 134 }; 135 136 #endif 137