xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrEagerVertexAllocator.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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