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/GrThreadSafeCache.h" 12 13 class GrMeshDrawTarget; 14 15 // This interface is used to allocate and map GPU vertex data before the exact number of required 16 // vertices is known. Usage pattern: 17 // 18 // 1. Call lock(eagerCount) with an upper bound on the number of required vertices. 19 // 2. Compute and write vertex data to the returned pointer (if not null). 20 // 3. Call unlock(actualCount) and provide the actual number of vertices written during step #2. 21 // 22 // On step #3, the implementation will attempt to shrink the underlying GPU memory slot to fit the 23 // actual vertex count. 24 class GrEagerVertexAllocator { 25 public: lock(int eagerCount)26 template<typename T> T* lock(int eagerCount) { 27 return static_cast<T*>(this->lock(sizeof(T), eagerCount)); 28 } 29 virtual void* lock(size_t stride, int eagerCount) = 0; 30 31 virtual void unlock(int actualCount) = 0; 32 ~GrEagerVertexAllocator()33 virtual ~GrEagerVertexAllocator() {} 34 }; 35 36 // GrEagerVertexAllocator implementation that uses GrMeshDrawTarget::makeVertexSpace and 37 // GrMeshDrawTarget::putBackVertices. 38 class GrEagerDynamicVertexAllocator : public GrEagerVertexAllocator { 39 public: GrEagerDynamicVertexAllocator(GrMeshDrawTarget * target,sk_sp<const GrBuffer> * vertexBuffer,int * baseVertex)40 GrEagerDynamicVertexAllocator(GrMeshDrawTarget* target, 41 sk_sp<const GrBuffer>* vertexBuffer, 42 int* baseVertex) 43 : fTarget(target) 44 , fVertexBuffer(vertexBuffer) 45 , fBaseVertex(baseVertex) { 46 } 47 48 #ifdef SK_DEBUG ~GrEagerDynamicVertexAllocator()49 ~GrEagerDynamicVertexAllocator() override { 50 SkASSERT(!fLockCount); 51 } 52 #endif 53 54 // Un-shadow GrEagerVertexAllocator::lock<T>. 55 using GrEagerVertexAllocator::lock; 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