1 /* 2 * Copyright 2020 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 GrEagerVertexAllocator_DEFINED 9 #define GrEagerVertexAllocator_DEFINED 10 11 #include "src/gpu/BufferWriter.h" 12 #include "src/gpu/GrThreadSafeCache.h" 13 14 class GrMeshDrawTarget; 15 16 // This interface is used to allocate and map GPU vertex data before the exact number of required 17 // vertices is known. Usage pattern: 18 // 19 // 1. Call lock(eagerCount) with an upper bound on the number of required vertices. 20 // 2. Compute and write vertex data to the returned pointer (if not null). 21 // 3. Call unlock(actualCount) and provide the actual number of vertices written during step #2. 22 // 23 // On step #3, the implementation will attempt to shrink the underlying GPU memory slot to fit the 24 // actual vertex count. 25 class GrEagerVertexAllocator { 26 public: 27 virtual void* lock(size_t stride, int eagerCount) = 0; 28 29 virtual void unlock(int actualCount) = 0; 30 ~GrEagerVertexAllocator()31 virtual ~GrEagerVertexAllocator() {} 32 lockWriter(size_t stride,int eagerCount)33 skgpu::VertexWriter lockWriter(size_t stride, int eagerCount) { 34 void* p = this->lock(stride, eagerCount); 35 return p ? skgpu::VertexWriter{p, stride * eagerCount} : skgpu::VertexWriter{}; 36 } 37 }; 38 39 // GrEagerVertexAllocator implementation that uses GrMeshDrawTarget::makeVertexSpace and 40 // GrMeshDrawTarget::putBackVertices. 41 class GrEagerDynamicVertexAllocator : public GrEagerVertexAllocator { 42 public: GrEagerDynamicVertexAllocator(GrMeshDrawTarget * target,sk_sp<const GrBuffer> * vertexBuffer,int * baseVertex)43 GrEagerDynamicVertexAllocator(GrMeshDrawTarget* target, 44 sk_sp<const GrBuffer>* vertexBuffer, 45 int* baseVertex) 46 : fTarget(target) 47 , fVertexBuffer(vertexBuffer) 48 , fBaseVertex(baseVertex) { 49 } 50 51 #ifdef SK_DEBUG ~GrEagerDynamicVertexAllocator()52 ~GrEagerDynamicVertexAllocator() override { 53 SkASSERT(!fLockCount); 54 } 55 #endif 56 57 // Mark "final" as a hint for the compiler to not use the vtable. 58 void* lock(size_t stride, int eagerCount) final; 59 60 // Mark "final" as a hint for the compiler to not use the vtable. 61 void unlock(int actualCount) final; 62 63 private: 64 GrMeshDrawTarget* const fTarget; 65 sk_sp<const GrBuffer>* const fVertexBuffer; 66 int* const fBaseVertex; 67 68 size_t fLockStride; 69 int fLockCount = 0; 70 }; 71 72 class GrCpuVertexAllocator : public GrEagerVertexAllocator { 73 public: 74 GrCpuVertexAllocator() = default; 75 76 #ifdef SK_DEBUG ~GrCpuVertexAllocator()77 ~GrCpuVertexAllocator() override { 78 SkASSERT(!fLockStride && !fVertices && !fVertexData); 79 } 80 #endif 81 82 void* lock(size_t stride, int eagerCount) override; 83 void unlock(int actualCount) override; 84 85 sk_sp<GrThreadSafeCache::VertexData> detachVertexData(); 86 87 private: 88 sk_sp<GrThreadSafeCache::VertexData> fVertexData; 89 90 void* fVertices = nullptr; 91 size_t fLockStride = 0; 92 }; 93 94 #endif 95