xref: /aosp_15_r20/external/skia/src/gpu/graphite/render/DynamicInstancesPatchAllocator.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2022 Google LLC
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 skgpu_graphite_render_DynamicInstancesPatchAllocator_DEFINED
9 #define skgpu_graphite_render_DynamicInstancesPatchAllocator_DEFINED
10 
11 #include "src/gpu/BufferWriter.h"
12 #include "src/gpu/graphite/DrawWriter.h"
13 #include "src/gpu/tessellate/LinearTolerances.h"
14 
15 namespace skgpu::graphite {
16 
17 // An adapter around DrawWriter::DynamicInstances that fits the API requirements of
18 // skgpu::tess::PatchWriter's PatchAllocator template parameter.
19 //
20 // FixedCountVariant should be one of FixedCountCurves, FixedCountWedges, or FixedCountStrokes
21 // (technically any class with a static VertexCount(const LinearTolerances&) function).
22 template <typename FixedCountVariant>
23 class DynamicInstancesPatchAllocator {
24 public:
25     // 'stride' is provided by PatchWriter.
26     // 'writer' is the DrawWriter that the RenderStep can append instance data to,
27     // 'fixedVertexBuffer' and 'fixedIndexBuffer' are the bindings for the instance template that
28     // is passed to DrawWriter::DynamicInstances.
DynamicInstancesPatchAllocator(size_t stride,DrawWriter & writer,BindBufferInfo fixedVertexBuffer,BindBufferInfo fixedIndexBuffer,unsigned int reserveCount)29     DynamicInstancesPatchAllocator(size_t stride,
30                                    DrawWriter& writer,
31                                    BindBufferInfo fixedVertexBuffer,
32                                    BindBufferInfo fixedIndexBuffer,
33                                    unsigned int reserveCount)
34             : fInstances(writer, fixedVertexBuffer, fixedIndexBuffer) {
35         SkASSERT(stride == writer.instanceStride());
36         // TODO: Is it worth re-reserving large chunks after this preallocation is used up? Or will
37         // appending 1 at a time be fine since it's coming from a large vertex buffer alloc anyway?
38         fInstances.reserve(reserveCount);
39     }
40 
append(const tess::LinearTolerances & tolerances)41     VertexWriter append(const tess::LinearTolerances& tolerances) {
42         return fInstances.append(tolerances, 1);
43     }
44 
45 private:
46     struct LinearToleranceProxy {
47         operator unsigned int() const { return FixedCountVariant::VertexCount(fTolerances); }
48         void operator <<(const tess::LinearTolerances& t) { fTolerances.accumulate(t); }
49 
50         tess::LinearTolerances fTolerances;
51     };
52 
53     DrawWriter::DynamicInstances<LinearToleranceProxy> fInstances;
54 };
55 
56 }  // namespace skgpu::graphite
57 
58 #endif // skgpu_graphite_render_DynamicInstancesPatchAllocator_DEFINED
59