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