• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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