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 <initializer_list>
9 #include <memory>
10 #include <type_traits>
11 #include <vector>
12 
13 #include "impeller/base/strings.h"
16 #include "impeller/core/formats.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& host_buffer) {
26  return VertexBuffer{
27  .vertex_buffer = 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>
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) {
47  }
48  if constexpr (sizeof(IndexType) == 2) {
50  }
51  if (sizeof(IndexType) == 4) {
53  }
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 
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 
96  VertexBuffer buffer;
97  buffer.vertex_buffer = CreateVertexBufferView(host_buffer);
98  buffer.index_buffer = CreateIndexBufferView(host_buffer);
99  buffer.vertex_count = GetIndexCount();
100  buffer.index_type = GetIndexType();
101  return buffer;
102  };
103 
104  VertexBuffer CreateVertexBuffer(Allocator& device_allocator) const {
105  VertexBuffer buffer;
106  // This can be merged into a single allocation.
107  buffer.vertex_buffer = CreateVertexBufferView(device_allocator);
108  buffer.index_buffer = CreateIndexBufferView(device_allocator);
109  buffer.vertex_count = GetIndexCount();
110  buffer.index_type = GetIndexType();
111  return buffer;
112  };
113 
114  void IterateVertices(const std::function<void(VertexType&)>& iterator) {
115  for (auto& vertex : vertices_) {
116  iterator(vertex);
117  }
118  }
119 
120  private:
121  std::vector<VertexType> vertices_;
122  std::vector<IndexType> indices_;
123  std::string label_;
124 
125  BufferView CreateVertexBufferView(HostBuffer& buffer) const {
126  return buffer.Emplace(vertices_.data(),
127  vertices_.size() * sizeof(VertexType),
128  alignof(VertexType));
129  }
130 
131  BufferView CreateVertexBufferView(Allocator& allocator) const {
132  auto buffer = allocator.CreateBufferWithCopy(
133  reinterpret_cast<const uint8_t*>(vertices_.data()),
134  vertices_.size() * sizeof(VertexType));
135  if (!buffer) {
136  return {};
137  }
138  if (!label_.empty()) {
139  buffer->SetLabel(SPrintF("%s Vertices", label_.c_str()));
140  }
141  return DeviceBuffer::AsBufferView(std::move(buffer));
142  }
143 
144  std::vector<IndexType> CreateIndexBuffer() const { return indices_; }
145 
146  BufferView CreateIndexBufferView(HostBuffer& buffer) const {
147  const auto index_buffer = CreateIndexBuffer();
148  if (index_buffer.size() == 0) {
149  return {};
150  }
151  return buffer.Emplace(index_buffer.data(),
152  index_buffer.size() * sizeof(IndexType),
153  alignof(IndexType));
154  }
155 
156  BufferView CreateIndexBufferView(Allocator& allocator) const {
157  const auto index_buffer = CreateIndexBuffer();
158  if (index_buffer.size() == 0) {
159  return {};
160  }
161  auto buffer = allocator.CreateBufferWithCopy(
162  reinterpret_cast<const uint8_t*>(index_buffer.data()),
163  index_buffer.size() * sizeof(IndexType));
164  if (!buffer) {
165  return {};
166  }
167  if (!label_.empty()) {
168  buffer->SetLabel(SPrintF("%s Indices", label_.c_str()));
169  }
170  return DeviceBuffer::AsBufferView(std::move(buffer));
171  }
172 };
173 
174 } // namespace impeller
175 
176 #endif // FLUTTER_IMPELLER_RENDERER_VERTEX_BUFFER_BUILDER_H_
An object that allocates device memory.
Definition: allocator.h:24
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
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
VertexBuffer CreateVertexBuffer(HostBuffer &host_buffer) const
const VertexType & Last() const
void IterateVertices(const std::function< void(VertexType &)> &iterator)
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
VertexBuffer CreateVertexBuffer(Allocator &device_allocator) const
VertexBufferBuilder & AppendVertex(VertexType_ vertex)
void SetLabel(const std::string &label)
constexpr impeller::IndexType GetIndexType() const
VertexBufferBuilder & AppendIndex(IndexType_ index)
@ kNone
Does not use the index buffer.
std::string SPrintF(const char *format,...)
Definition: strings.cc:12
VertexBuffer CreateVertexBuffer(std::array< VertexType, size > input, HostBuffer &host_buffer)
Create an index-less vertex buffer from a fixed size array.
BufferView index_buffer
The index buffer binding used by the vertex shader stage.
Definition: vertex_buffer.h:20