Flutter Impeller
vertices_geometry.cc
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 
6 
7 #include <cstdint>
8 #include <utility>
9 
13 
14 namespace impeller {
15 
16 // Fan mode isn't natively supported. Unroll into triangle mode by
17 // manipulating the index array.
18 //
19 // In Triangle fan, the first vertex is shared across all triangles, and then
20 // each sliding window of two vertices plus that first vertex defines a
21 // triangle.
22 static std::vector<uint16_t> fromFanIndices(
23  const std::vector<Point>& vertices,
24  const std::vector<uint16_t>& indices) {
25  std::vector<uint16_t> unrolled_indices;
26 
27  // Un-fan index buffer if provided.
28  if (indices.size() > 0u) {
29  if (indices.size() < 3u) {
30  return {};
31  }
32 
33  auto center_point = indices[0];
34  for (auto i = 1u; i < indices.size() - 1; i++) {
35  unrolled_indices.push_back(center_point);
36  unrolled_indices.push_back(indices[i]);
37  unrolled_indices.push_back(indices[i + 1]);
38  }
39  } else {
40  if (vertices.size() < 3u) {
41  return {};
42  }
43 
44  // If indices were not provided, create an index buffer that unfans
45  // triangles instead of re-writing points, colors, et cetera.
46  for (auto i = 1u; i < vertices.size() - 1; i++) {
47  unrolled_indices.push_back(0);
48  unrolled_indices.push_back(i);
49  unrolled_indices.push_back(i + 1);
50  }
51  }
52  return unrolled_indices;
53 }
54 
55 /////// Vertices Geometry ///////
56 
57 VerticesGeometry::VerticesGeometry(std::vector<Point> vertices,
58  std::vector<uint16_t> indices,
59  std::vector<Point> texture_coordinates,
60  std::vector<Color> colors,
61  Rect bounds,
62  VertexMode vertex_mode)
63  : vertices_(std::move(vertices)),
64  colors_(std::move(colors)),
65  texture_coordinates_(std::move(texture_coordinates)),
66  indices_(std::move(indices)),
67  bounds_(bounds),
68  vertex_mode_(vertex_mode) {
69  NormalizeIndices();
70 }
71 
72 PrimitiveType VerticesGeometry::GetPrimitiveType() const {
73  switch (vertex_mode_) {
75  // Unrolled into triangle mode.
81  }
82 }
83 
84 void VerticesGeometry::NormalizeIndices() {
85  // Convert triangle fan if present.
86  if (vertex_mode_ == VerticesGeometry::VertexMode::kTriangleFan) {
87  indices_ = fromFanIndices(vertices_, indices_);
88  return;
89  }
90 }
91 
93  return colors_.size() > 0;
94 }
95 
97  return texture_coordinates_.size() > 0;
98 }
99 
101  if (!HasTextureCoordinates()) {
102  return std::nullopt;
103  }
104  auto vertex_count = vertices_.size();
105  if (vertex_count == 0) {
106  return std::nullopt;
107  }
108 
109  return Rect::MakePointBounds(texture_coordinates_.begin(),
110  texture_coordinates_.end());
111 }
112 
114  const ContentContext& renderer,
115  const Entity& entity,
116  RenderPass& pass) const {
117  auto index_count = indices_.size();
118  auto vertex_count = vertices_.size();
119 
120  size_t total_vtx_bytes = vertex_count * sizeof(float) * 2;
121  size_t total_idx_bytes = index_count * sizeof(uint16_t);
122 
123  auto vertex_buffer = renderer.GetTransientsBuffer().Emplace(
124  reinterpret_cast<const uint8_t*>(vertices_.data()), total_vtx_bytes,
125  alignof(float));
126 
127  BufferView index_buffer = {};
128  if (index_count) {
129  index_buffer = renderer.GetTransientsBuffer().Emplace(
130  indices_.data(), total_idx_bytes, alignof(uint16_t));
131  }
132 
133  return GeometryResult{
134  .type = GetPrimitiveType(),
135  .vertex_buffer =
136  {
137  .vertex_buffer = vertex_buffer,
138  .index_buffer = index_buffer,
139  .vertex_count = index_count > 0 ? index_count : vertex_count,
140  .index_type =
141  index_count > 0 ? IndexType::k16bit : IndexType::kNone,
142  },
143  .transform = entity.GetShaderTransform(pass),
144  };
145 }
146 
148  Rect texture_coverage,
149  Matrix effect_transform,
150  const ContentContext& renderer,
151  const Entity& entity,
152  RenderPass& pass) const {
154 
155  auto vertex_count = vertices_.size();
156  auto uv_transform =
157  texture_coverage.GetNormalizingTransform() * effect_transform;
158  auto has_texture_coordinates = HasTextureCoordinates();
159  auto has_colors = HasVertexColors();
160 
161  size_t total_vtx_bytes = vertices_.size() * sizeof(VS::PerVertexData);
162  auto vertex_buffer = renderer.GetTransientsBuffer().Emplace(
163  total_vtx_bytes, alignof(VS::PerVertexData), [&](uint8_t* data) {
164  VS::PerVertexData* vtx_contents =
165  reinterpret_cast<VS::PerVertexData*>(data);
166  for (auto i = 0u; i < vertices_.size(); i++) {
167  auto vertex = vertices_[i];
168  auto texture_coord =
169  has_texture_coordinates ? texture_coordinates_[i] : vertices_[i];
170  auto uv = uv_transform * texture_coord;
171  VS::PerVertexData vertex_data = {
172  .vertices = vertex,
173  .texture_coords = uv,
174  .color = has_colors ? colors_[i] : Color::BlackTransparent(),
175  };
176  std::memcpy(vtx_contents++, &vertex_data, sizeof(VS::PerVertexData));
177  }
178  });
179 
180  BufferView index_buffer = {};
181  auto index_count = indices_.size();
182  size_t total_idx_bytes = index_count * sizeof(uint16_t);
183  if (index_count > 0) {
184  index_buffer = renderer.GetTransientsBuffer().Emplace(
185  indices_.data(), total_idx_bytes, alignof(uint16_t));
186  }
187 
188  return GeometryResult{
189  .type = GetPrimitiveType(),
190  .vertex_buffer =
191  {
192  .vertex_buffer = vertex_buffer,
193  .index_buffer = index_buffer,
194  .vertex_count = index_count > 0 ? index_count : vertex_count,
195  .index_type =
196  index_count > 0 ? IndexType::k16bit : IndexType::kNone,
197  },
198  .transform = entity.GetShaderTransform(pass),
199  };
200 }
201 
202 std::optional<Rect> VerticesGeometry::GetCoverage(
203  const Matrix& transform) const {
204  return bounds_.TransformBounds(transform);
205 }
206 
207 } // namespace impeller
impeller::Entity::GetShaderTransform
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition: entity.cc:50
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:95
impeller::IndexType::k16bit
@ k16bit
impeller::VerticesGeometry::VerticesGeometry
VerticesGeometry(std::vector< Point > vertices, std::vector< uint16_t > indices, std::vector< Point > texture_coordinates, std::vector< Color > colors, Rect bounds, VerticesGeometry::VertexMode vertex_mode)
Definition: vertices_geometry.cc:57
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
impeller::TRect::TransformBounds
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:463
impeller::VerticesGeometry::GetPositionUVColorBuffer
GeometryResult GetPositionUVColorBuffer(Rect texture_coverage, Matrix effect_transform, const ContentContext &renderer, const Entity &entity, RenderPass &pass) const
Definition: vertices_geometry.cc:147
impeller::TRect::GetNormalizingTransform
constexpr Matrix GetNormalizingTransform() const
Constructs a Matrix that will map all points in the coordinate space of the rectangle into a new norm...
Definition: rect.h:482
impeller::TRect< Scalar >::MakePointBounds
constexpr static std::optional< TRect > MakePointBounds(const U &value)
Definition: rect.h:151
impeller::VS
SolidFillVertexShader VS
Definition: stroke_path_geometry.cc:16
impeller::PrimitiveType::kTriangle
@ kTriangle
impeller::Entity
Definition: entity.h:20
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::PrimitiveType
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:352
impeller::VerticesGeometry::VertexMode
VertexMode
Definition: vertices_geometry.h:15
impeller::GeometryResult::type
PrimitiveType type
Definition: geometry.h:35
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:231
impeller::VerticesGeometry::HasVertexColors
bool HasVertexColors() const
Definition: vertices_geometry.cc:92
impeller::VerticesGeometry::VertexMode::kTriangleStrip
@ kTriangleStrip
impeller::RenderPipelineHandle::VertexShader
VertexShader_ VertexShader
Definition: pipeline.h:106
impeller::GeometryResult
Definition: geometry.h:19
impeller::IndexType::kNone
@ kNone
Does not use the index buffer.
vertices_geometry.h
impeller::VerticesGeometry::GetCoverage
std::optional< Rect > GetCoverage(const Matrix &transform) const override
Definition: vertices_geometry.cc:202
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:33
content_context.h
impeller::BufferView
Definition: buffer_view.h:15
std
Definition: comparable.h:95
buffer_view.h
impeller::Color::BlackTransparent
static constexpr Color BlackTransparent()
Definition: color.h:272
color.h
impeller::VerticesGeometry::GetPositionBuffer
GeometryResult GetPositionBuffer(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
Definition: vertices_geometry.cc:113
impeller::VerticesGeometry::VertexMode::kTriangles
@ kTriangles
impeller::VerticesGeometry::HasTextureCoordinates
bool HasTextureCoordinates() const
Definition: vertices_geometry.cc:96
impeller
Definition: aiks_blend_unittests.cc:18
impeller::VerticesGeometry::VertexMode::kTriangleFan
@ kTriangleFan
impeller::ContentContext
Definition: content_context.h:366
impeller::TRect< Scalar >
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::VerticesGeometry::GetTextureCoordinateCoverge
std::optional< Rect > GetTextureCoordinateCoverge() const
Definition: vertices_geometry.cc:100
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:752
impeller::fromFanIndices
static std::vector< uint16_t > fromFanIndices(const std::vector< Point > &vertices, const std::vector< uint16_t > &indices)
Definition: vertices_geometry.cc:22