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