• 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/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