2 * Copyright 2021 Google LLC.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrVertexChunkArray_DEFINED
9 #define GrVertexChunkArray_DEFINED
11 #include "include/core/SkRefCnt.h"
12 #include "include/private/SkNoncopyable.h"
13 #include "include/private/SkTArray.h"
14 #include "src/gpu/BufferWriter.h"
15 #include "src/gpu/ganesh/GrBuffer.h"
17 class GrMeshDrawTarget;
19 // Represents a chunk of vertex data. Use with GrVertexChunkArray and GrVertexChunkBuilder. We write
20 // the data out in chunks when we don't start out knowing exactly how many vertices (or instances)
21 // we will end up writing.
22 struct GrVertexChunk {
23 sk_sp<const GrBuffer> fBuffer;
25 int fBase; // baseVertex or baseInstance, depending on the use case.
28 // Represents an array of GrVertexChunks.
30 // We only preallocate 1 chunk because if the array needs to grow, then we're also allocating a
31 // brand new GPU buffer anyway.
32 using GrVertexChunkArray = SkSTArray<1, GrVertexChunk>;
34 // Builds a GrVertexChunkArray. The provided Target must not be used externally throughout the
35 // entire lifetime of this object.
36 class GrVertexChunkBuilder : SkNoncopyable {
38 GrVertexChunkBuilder(GrMeshDrawTarget* target, GrVertexChunkArray* chunks,
39 size_t stride, int minVerticesPerChunk)
43 , fMinVerticesPerChunk(minVerticesPerChunk) {
44 SkASSERT(fMinVerticesPerChunk > 0);
47 ~GrVertexChunkBuilder();
49 size_t stride() const { return fStride; }
51 // Appends 'count' contiguous vertices. These vertices are not guaranteed to be contiguous with
52 // previous or future calls to appendVertices.
53 SK_ALWAYS_INLINE skgpu::VertexWriter appendVertices(int count) {
55 if (fCurrChunkVertexCount + count > fCurrChunkVertexCapacity && !this->allocChunk(count)) {
56 SkDEBUGCODE(fLastAppendAmount = 0;)
59 SkASSERT(fCurrChunkVertexCount + count <= fCurrChunkVertexCapacity);
60 fCurrChunkVertexCount += count;
61 SkDEBUGCODE(fLastAppendAmount = count;)
62 return std::exchange(fCurrChunkVertexWriter,
63 fCurrChunkVertexWriter.makeOffset(fStride * count));
66 // Pops the most recent 'count' contiguous vertices. Since there is no guarantee of contiguity
67 // between appends, 'count' may be no larger than the most recent call to appendVertices().
68 void popVertices(int count) {
69 SkASSERT(count <= fLastAppendAmount);
70 SkASSERT(fLastAppendAmount <= fCurrChunkVertexCount);
72 fCurrChunkVertexCount -= count;
73 fCurrChunkVertexWriter = fCurrChunkVertexWriter.makeOffset(fStride * -count);
74 SkDEBUGCODE(fLastAppendAmount -= count;)
78 bool allocChunk(int minCount);
80 GrMeshDrawTarget* const fTarget;
81 GrVertexChunkArray* const fChunks;
83 int fMinVerticesPerChunk;
85 skgpu::VertexWriter fCurrChunkVertexWriter;
86 int fCurrChunkVertexCount = 0;
87 int fCurrChunkVertexCapacity = 0;
89 SkDEBUGCODE(int fLastAppendAmount = 0;)