| Flutter Impeller |

vertex_buffer_builder.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef FLUTTER_IMPELLER_RENDERER_VERTEX_BUFFER_BUILDER_H_
6 #define FLUTTER_IMPELLER_RENDERER_VERTEX_BUFFER_BUILDER_H_
7
8 #include <format>
9 #include <initializer_list>
10 #include <memory>
11 #include <type_traits>
12 #include <vector>
13
14 #include "impeller/core/allocator.h"
15 #include "impeller/core/device_buffer.h"
16 #include "impeller/core/formats.h"
17 #include "impeller/core/host_buffer.h"
18 #include "impeller/core/vertex_buffer.h"
19
20 namespace impeller {
21
22 /// @brief Create an index-less vertex buffer from a fixed size array.
23 template <class VertexType, size_t size>
24 VertexBuffer CreateVertexBuffer(std::array<VertexType, size> input,
25 HostBuffer& data_host_buffer) {
26 return VertexBuffer{
27 .vertex_buffer = data_host_buffer.Emplace(
28 input.data(), sizeof(VertexType) * size, alignof(VertexType)),
29 .vertex_count = size,
30 .index_type = IndexType::kNone,
31 };
32 }
33
34 template <class VertexType_, class IndexType_ = uint16_t>
35 class VertexBufferBuilder {
36 public:
37 using VertexType = VertexType_;
38 using IndexType = IndexType_;
39
40 VertexBufferBuilder() = default;
41
42 ~VertexBufferBuilder() = default;
43
44 constexpr impeller::IndexType GetIndexType() const {
45 if (indices_.size() == 0) {
46 return impeller::IndexType::kNone;
47 }
48 if constexpr (sizeof(IndexType) == 2) {
49 return impeller::IndexType::k16bit;
50 }
51 if (sizeof(IndexType) == 4) {
52 return impeller::IndexType::k32bit;
53 }
54 return impeller::IndexType::kUnknown;
55 }
56
57 void SetLabel(const std::string& label) { label_ = label; }
58
59 void Reserve(size_t count) { return vertices_.reserve(count); }
60
61 void ReserveIndices(size_t count) { return indices_.reserve(count); }
62
63 bool HasVertices() const { return !vertices_.empty(); }
64
65 size_t GetVertexCount() const { return vertices_.size(); }
66
67 size_t GetIndexCount() const {
68 return indices_.size() > 0 ? indices_.size() : vertices_.size();
69 }
70
71 const VertexType& Last() const {
72 FML_DCHECK(!vertices_.empty());
73 return vertices_.back();
74 }
75
76 VertexBufferBuilder& AppendVertex(VertexType_ vertex) {
77 vertices_.emplace_back(std::move(vertex));
78 return *this;
79 }
80
81 VertexBufferBuilder& AddVertices(
82 std::initializer_list<VertexType_> vertices) {
83 vertices_.reserve(vertices.size());
84 for (auto& vertex : vertices) {
85 vertices_.emplace_back(std::move(vertex));
86 }
87 return *this;
88 }
89
90 VertexBufferBuilder& AppendIndex(IndexType_ index) {
91 indices_.emplace_back(index);
92 return *this;
93 }
94
95 VertexBuffer CreateVertexBuffer(HostBuffer& data_host_buffer,
96 HostBuffer& indexes_host_buffer) const {
97 VertexBuffer buffer;
98 buffer.vertex_buffer = CreateVertexBufferView(data_host_buffer);
99 buffer.index_buffer = CreateIndexBufferView(indexes_host_buffer);
100 buffer.vertex_count = GetIndexCount();
101 buffer.index_type = GetIndexType();
102 return buffer;
103 };
104
105 VertexBuffer CreateVertexBuffer(Allocator& device_allocator) const {
106 VertexBuffer buffer;
107 // This can be merged into a single allocation.
108 buffer.vertex_buffer = CreateVertexBufferView(device_allocator);
109 buffer.index_buffer = CreateIndexBufferView(device_allocator);
110 buffer.vertex_count = GetIndexCount();
111 buffer.index_type = GetIndexType();
112 return buffer;
113 };
114
115 void IterateVertices(const std::function<void(VertexType&)>& iterator) {
116 for (auto& vertex : vertices_) {
117 iterator(vertex);
118 }
119 }
120
121 private:
122 std::vector<VertexType> vertices_;
123 std::vector<IndexType> indices_;
124 std::string label_;
125
126 BufferView CreateVertexBufferView(HostBuffer& data_host_buffer) const {
127 return data_host_buffer.Emplace(vertices_.data(),
128 vertices_.size() * sizeof(VertexType),
129 alignof(VertexType));
130 }
131
132 BufferView CreateVertexBufferView(Allocator& allocator) const {
133 auto buffer = allocator.CreateBufferWithCopy(
134 reinterpret_cast<const uint8_t*>(vertices_.data()),
135 vertices_.size() * sizeof(VertexType));
136 if (!buffer) {
137 return {};
138 }
139 if (!label_.empty()) {
140 buffer->SetLabel(std::format("{} Vertices", label_));
141 }
142 return DeviceBuffer::AsBufferView(std::move(buffer));
143 }
144
145 std::vector<IndexType> CreateIndexBuffer() const { return indices_; }
146
147 BufferView CreateIndexBufferView(HostBuffer& indexes_host_buffer) const {
148 const auto index_buffer = CreateIndexBuffer();
149 if (index_buffer.size() == 0) {
150 return {};
151 }
152 return indexes_host_buffer.Emplace(index_buffer.data(),
153 index_buffer.size() * sizeof(IndexType),
154 alignof(IndexType));
155 }
156
157 BufferView CreateIndexBufferView(Allocator& allocator) const {
158 const auto index_buffer = CreateIndexBuffer();
159 if (index_buffer.size() == 0) {
160 return {};
161 }
162 auto buffer = allocator.CreateBufferWithCopy(
163 reinterpret_cast<const uint8_t*>(index_buffer.data()),
164 index_buffer.size() * sizeof(IndexType));
165 if (!buffer) {
166 return {};
167 }
168 if (!label_.empty()) {
169 buffer->SetLabel(std::format("{} Indices", label_));
170 }
171 return DeviceBuffer::AsBufferView(std::move(buffer));
172 }
173 };
174
175 } // namespace impeller
176
177 #endif // FLUTTER_IMPELLER_RENDERER_VERTEX_BUFFER_BUILDER_H_
allocator.h
impeller::Allocator
An object that allocates device memory.
Definition: allocator.h:24
impeller::DeviceBuffer::AsBufferView
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
Definition: device_buffer.cc:18
impeller::HostBuffer
Definition: host_buffer.h:26
impeller::HostBuffer::Emplace
BufferView Emplace(const BufferType &buffer, size_t alignment=0)
Emplace non-uniform data (like contiguous vertices) onto the host buffer.
Definition: host_buffer.h:92
impeller::VertexBufferBuilder
Definition: vertex_buffer_builder.h:35
impeller::VertexBufferBuilder::GetVertexCount
size_t GetVertexCount() const
Definition: vertex_buffer_builder.h:65
impeller::VertexBufferBuilder::Last
const VertexType & Last() const
Definition: vertex_buffer_builder.h:71
impeller::VertexBufferBuilder::IndexType
IndexType_ IndexType
Definition: vertex_buffer_builder.h:38
impeller::VertexBufferBuilder::~VertexBufferBuilder
~VertexBufferBuilder()=default
impeller::VertexBufferBuilder::VertexBufferBuilder
VertexBufferBuilder()=default
impeller::VertexBufferBuilder::GetIndexCount
size_t GetIndexCount() const
Definition: vertex_buffer_builder.h:67
impeller::VertexBufferBuilder::CreateVertexBuffer
VertexBuffer CreateVertexBuffer(HostBuffer &data_host_buffer, HostBuffer &indexes_host_buffer) const
Definition: vertex_buffer_builder.h:95
impeller::VertexBufferBuilder::ReserveIndices
void ReserveIndices(size_t count)
Definition: vertex_buffer_builder.h:61
impeller::VertexBufferBuilder::VertexType
VertexType_ VertexType
Definition: vertex_buffer_builder.h:37
impeller::VertexBufferBuilder::IterateVertices
void IterateVertices(const std::function< void(VertexType &)> &iterator)
Definition: vertex_buffer_builder.h:115
impeller::VertexBufferBuilder::AddVertices
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
Definition: vertex_buffer_builder.h:81
impeller::VertexBufferBuilder::Reserve
void Reserve(size_t count)
Definition: vertex_buffer_builder.h:59
impeller::VertexBufferBuilder::CreateVertexBuffer
VertexBuffer CreateVertexBuffer(Allocator &device_allocator) const
Definition: vertex_buffer_builder.h:105
impeller::VertexBufferBuilder::AppendVertex
VertexBufferBuilder & AppendVertex(VertexType_ vertex)
Definition: vertex_buffer_builder.h:76
impeller::VertexBufferBuilder::SetLabel
void SetLabel(const std::string &label)
Definition: vertex_buffer_builder.h:57
impeller::VertexBufferBuilder::GetIndexType
constexpr impeller::IndexType GetIndexType() const
Definition: vertex_buffer_builder.h:44
impeller::VertexBufferBuilder::AppendIndex
VertexBufferBuilder & AppendIndex(IndexType_ index)
Definition: vertex_buffer_builder.h:90
impeller::VertexBufferBuilder::HasVertices
bool HasVertices() const
Definition: vertex_buffer_builder.h:63
formats.h
device_buffer.h
host_buffer.h
impeller
Definition: allocation.cc:12
impeller::IndexType
IndexType
Definition: formats.h:346
impeller::IndexType::k16bit
@ k16bit
impeller::IndexType::kUnknown
@ kUnknown
impeller::IndexType::kNone
@ kNone
Does not use the index buffer.
impeller::IndexType::k32bit
@ k32bit
impeller::CreateVertexBuffer
VertexBuffer CreateVertexBuffer(std::array< VertexType, size > input, HostBuffer &data_host_buffer)
Create an index-less vertex buffer from a fixed size array.
Definition: vertex_buffer_builder.h:24
impeller::BufferView
Definition: buffer_view.h:19
impeller::VertexBuffer
Definition: vertex_buffer.h:15
impeller::VertexBuffer::index_type
IndexType index_type
Definition: vertex_buffer.h:31
impeller::VertexBuffer::vertex_count
size_t vertex_count
Definition: vertex_buffer.h:25
impeller::VertexBuffer::index_buffer
BufferView index_buffer
The index buffer binding used by the vertex shader stage.
Definition: vertex_buffer.h:20
impeller::VertexBuffer::vertex_buffer
BufferView vertex_buffer
Definition: vertex_buffer.h:16
vertex_buffer.h