blob: 7828b0e1ef13b5ab4dc76936b0cd573c50405fbf [file] [log] [blame]
Chris Daltond081dce2020-01-23 12:09:04 -07001/*
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
Robert Phillips98b066c2021-04-22 10:51:58 -040011#include "src/gpu/GrThreadSafeCache.h"
Robert Phillips71143952021-06-17 14:55:07 -040012
13class GrMeshDrawTarget;
Chris Daltond081dce2020-01-23 12:09:04 -070014
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.
24class GrEagerVertexAllocator {
25public:
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
33 virtual ~GrEagerVertexAllocator() {}
34};
35
Robert Phillips71143952021-06-17 14:55:07 -040036// GrEagerVertexAllocator implementation that uses GrMeshDrawTarget::makeVertexSpace and
37// GrMeshDrawTarget::putBackVertices.
Chris Daltond081dce2020-01-23 12:09:04 -070038class GrEagerDynamicVertexAllocator : public GrEagerVertexAllocator {
39public:
Robert Phillips71143952021-06-17 14:55:07 -040040 GrEagerDynamicVertexAllocator(GrMeshDrawTarget* target,
Robert Phillips3ac83b2f2020-10-26 13:50:57 -040041 sk_sp<const GrBuffer>* vertexBuffer,
42 int* baseVertex)
Chris Daltond081dce2020-01-23 12:09:04 -070043 : fTarget(target)
44 , fVertexBuffer(vertexBuffer)
45 , fBaseVertex(baseVertex) {
46 }
47
48#ifdef SK_DEBUG
49 ~GrEagerDynamicVertexAllocator() override {
50 SkASSERT(!fLockCount);
51 }
52#endif
53
Chris Dalton42915c22020-04-22 16:24:43 -060054 // Un-shadow GrEagerVertexAllocator::lock<T>.
55 using GrEagerVertexAllocator::lock;
56
57 // Mark "final" as a hint for the compiler to not use the vtable.
Robert Phillips71143952021-06-17 14:55:07 -040058 void* lock(size_t stride, int eagerCount) final;
Chris Daltond081dce2020-01-23 12:09:04 -070059
Chris Dalton42915c22020-04-22 16:24:43 -060060 // Mark "final" as a hint for the compiler to not use the vtable.
Robert Phillips71143952021-06-17 14:55:07 -040061 void unlock(int actualCount) final;
Chris Daltond081dce2020-01-23 12:09:04 -070062
63private:
Robert Phillips71143952021-06-17 14:55:07 -040064 GrMeshDrawTarget* const fTarget;
Chris Daltond081dce2020-01-23 12:09:04 -070065 sk_sp<const GrBuffer>* const fVertexBuffer;
66 int* const fBaseVertex;
67
68 size_t fLockStride;
69 int fLockCount = 0;
70};
71
Robert Phillips98b066c2021-04-22 10:51:58 -040072class GrCpuVertexAllocator : public GrEagerVertexAllocator {
73public:
74 GrCpuVertexAllocator() = default;
75
76#ifdef SK_DEBUG
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
87private:
88 sk_sp<GrThreadSafeCache::VertexData> fVertexData;
89
90 void* fVertices = nullptr;
91 size_t fLockStride = 0;
92};
93
Chris Daltond081dce2020-01-23 12:09:04 -070094#endif