blob: aaec828adcd2e4fad48829cb984324e6306fcb95 [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
11#include "src/gpu/ops/GrMeshDrawOp.h"
12
13// This interface is used to allocate and map GPU vertex data before the exact number of required
14// vertices is known. Usage pattern:
15//
16// 1. Call lock(eagerCount) with an upper bound on the number of required vertices.
17// 2. Compute and write vertex data to the returned pointer (if not null).
18// 3. Call unlock(actualCount) and provide the actual number of vertices written during step #2.
19//
20// On step #3, the implementation will attempt to shrink the underlying GPU memory slot to fit the
21// actual vertex count.
22class GrEagerVertexAllocator {
23public:
24 template<typename T> T* lock(int eagerCount) {
25 return static_cast<T*>(this->lock(sizeof(T), eagerCount));
26 }
27 virtual void* lock(size_t stride, int eagerCount) = 0;
28
29 virtual void unlock(int actualCount) = 0;
30
31 virtual ~GrEagerVertexAllocator() {}
32};
33
34// GrEagerVertexAllocator implementation that uses GrMeshDrawOp::Target::makeVertexSpace and
35// GrMeshDrawOp::Target::putBackVertices.
36class GrEagerDynamicVertexAllocator : public GrEagerVertexAllocator {
37public:
38 GrEagerDynamicVertexAllocator(GrMeshDrawOp::Target* target,
Robert Phillips3ac83b2f2020-10-26 13:50:57 -040039 sk_sp<const GrBuffer>* vertexBuffer,
40 int* baseVertex)
Chris Daltond081dce2020-01-23 12:09:04 -070041 : fTarget(target)
42 , fVertexBuffer(vertexBuffer)
43 , fBaseVertex(baseVertex) {
44 }
45
46#ifdef SK_DEBUG
47 ~GrEagerDynamicVertexAllocator() override {
48 SkASSERT(!fLockCount);
49 }
50#endif
51
Chris Dalton42915c22020-04-22 16:24:43 -060052 // Un-shadow GrEagerVertexAllocator::lock<T>.
53 using GrEagerVertexAllocator::lock;
54
55 // Mark "final" as a hint for the compiler to not use the vtable.
56 void* lock(size_t stride, int eagerCount) final {
Chris Daltond081dce2020-01-23 12:09:04 -070057 SkASSERT(!fLockCount);
58 SkASSERT(eagerCount);
59 if (void* data = fTarget->makeVertexSpace(stride, eagerCount, fVertexBuffer, fBaseVertex)) {
60 fLockStride = stride;
61 fLockCount = eagerCount;
62 return data;
63 }
64 fVertexBuffer->reset();
65 *fBaseVertex = 0;
66 return nullptr;
67 }
68
Chris Dalton42915c22020-04-22 16:24:43 -060069 // Mark "final" as a hint for the compiler to not use the vtable.
70 void unlock(int actualCount) final {
Chris Daltond081dce2020-01-23 12:09:04 -070071 SkASSERT(fLockCount);
72 SkASSERT(actualCount <= fLockCount);
73 fTarget->putBackVertices(fLockCount - actualCount, fLockStride);
74 if (!actualCount) {
75 fVertexBuffer->reset();
76 *fBaseVertex = 0;
77 }
78 fLockCount = 0;
79 }
80
81private:
82 GrMeshDrawOp::Target* const fTarget;
83 sk_sp<const GrBuffer>* const fVertexBuffer;
84 int* const fBaseVertex;
85
86 size_t fLockStride;
87 int fLockCount = 0;
88};
89
90#endif