Flutter Impeller
dl_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 "display_list/dl_vertices.h"
12 
13 namespace impeller {
14 
15 namespace {
16 
17 // Fan mode isn't natively supported on Metal backends. Unroll into triangle
18 // mode by manipulating the index array.
19 //
20 // In Triangle fan, the first vertex is shared across all triangles, and then
21 // each sliding window of two vertices plus that first vertex defines a
22 // triangle.
23 static std::vector<uint16_t> fromFanIndices(size_t vertex_count,
24  size_t index_count,
25  const uint16_t* indices) {
26  std::vector<uint16_t> unrolled_indices;
27 
28  // Un-fan index buffer if provided.
29  if (index_count > 0u) {
30  if (index_count < 3u) {
31  return {};
32  }
33 
34  auto center_point = indices[0];
35  for (auto i = 1u; i < index_count - 1; i++) {
36  unrolled_indices.push_back(center_point);
37  unrolled_indices.push_back(indices[i]);
38  unrolled_indices.push_back(indices[i + 1]);
39  }
40  } else {
41  if (vertex_count < 3u) {
42  return {};
43  }
44 
45  // If indices were not provided, create an index buffer that unfans
46  // triangles instead of re-writing points, colors, et cetera.
47  for (auto i = 1u; i < vertex_count - 1; i++) {
48  unrolled_indices.push_back(0);
49  unrolled_indices.push_back(i);
50  unrolled_indices.push_back(i + 1);
51  }
52  }
53  return unrolled_indices;
54 }
55 
56 } // namespace
57 
58 /////// Vertices Geometry ///////
59 
61  const std::shared_ptr<const flutter::DlVertices>& vertices,
62  const ContentContext& renderer)
63  : vertices_(vertices) {
64  performed_normalization_ = MaybePerformIndexNormalization(renderer);
65  bounds_ = vertices_->GetBounds();
66 }
67 
68 PrimitiveType DlVerticesGeometry::GetPrimitiveType() const {
69  switch (vertices_->mode()) {
70  case flutter::DlVertexMode::kTriangleFan:
71  // Unrolled into triangle mode.
72  if (performed_normalization_) {
74  }
76  case flutter::DlVertexMode::kTriangleStrip:
78  case flutter::DlVertexMode::kTriangles:
80  }
81 }
82 
84  return vertices_->colors() != nullptr;
85 }
86 
88  return vertices_->texture_coordinate_data() != nullptr;
89 }
90 
92  if (!HasTextureCoordinates()) {
93  return std::nullopt;
94  }
95  auto vertex_count = vertices_->vertex_count();
96  if (vertex_count == 0) {
97  return std::nullopt;
98  }
99 
100  auto first = vertices_->texture_coordinate_data();
101  auto left = first->x;
102  auto top = first->y;
103  auto right = first->x;
104  auto bottom = first->y;
105  int i = 1;
106  for (auto it = first + 1; i < vertex_count; ++it, i++) {
107  left = std::min(left, it->x);
108  top = std::min(top, it->y);
109  right = std::max(right, it->x);
110  bottom = std::max(bottom, it->y);
111  }
112  return Rect::MakeLTRB(left, top, right, bottom);
113 }
114 
116  const ContentContext& renderer,
117  const Entity& entity,
118  RenderPass& pass) const {
119  int vertex_count = vertices_->vertex_count();
120  BufferView vertex_buffer = renderer.GetTransientsBuffer().Emplace(
121  vertices_->vertex_data(), vertex_count * sizeof(Point), alignof(Point));
122 
123  BufferView index_buffer = {};
124  auto index_count =
125  performed_normalization_ ? indices_.size() : vertices_->index_count();
126  const uint16_t* indices_data =
127  performed_normalization_ ? indices_.data() : vertices_->indices();
128  if (index_count) {
129  index_buffer = renderer.GetTransientsBuffer().Emplace(
130  indices_data, index_count * sizeof(uint16_t), 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  int vertex_count = vertices_->vertex_count();
156  Matrix uv_transform =
157  texture_coverage.GetNormalizingTransform() * effect_transform;
158  bool has_texture_coordinates = HasTextureCoordinates();
159  bool has_colors = HasVertexColors();
160 
161  const Point* coordinates = has_texture_coordinates
162  ? vertices_->texture_coordinate_data()
163  : vertices_->vertex_data();
164  BufferView vertex_buffer = renderer.GetTransientsBuffer().Emplace(
165  vertex_count * sizeof(VS::PerVertexData), alignof(VS::PerVertexData),
166  [&](uint8_t* data) {
167  VS::PerVertexData* vtx_contents =
168  reinterpret_cast<VS::PerVertexData*>(data);
169  const Point* vertex_points = vertices_->vertex_data();
170  for (auto i = 0; i < vertex_count; i++) {
171  Point texture_coord = coordinates[i];
172  Point uv = uv_transform * texture_coord;
173  Color color = has_colors
174  ? skia_conversions::ToColor(vertices_->colors()[i])
175  .Premultiply()
177  VS::PerVertexData vertex_data = {.vertices = vertex_points[i],
178  .texture_coords = uv,
179  .color = color};
180  vtx_contents[i] = vertex_data;
181  }
182  });
183 
184  BufferView index_buffer = {};
185  auto index_count =
186  performed_normalization_ ? indices_.size() : vertices_->index_count();
187  const uint16_t* indices_data =
188  performed_normalization_ ? indices_.data() : vertices_->indices();
189  if (index_count) {
190  index_buffer = renderer.GetTransientsBuffer().Emplace(
191  indices_data, index_count * sizeof(uint16_t), alignof(uint16_t));
192  }
193 
194  return GeometryResult{
195  .type = GetPrimitiveType(),
196  .vertex_buffer =
197  {
198  .vertex_buffer = vertex_buffer,
199  .index_buffer = index_buffer,
200  .vertex_count = index_count > 0 ? index_count : vertex_count,
201  .index_type =
202  index_count > 0 ? IndexType::k16bit : IndexType::kNone,
203  },
204  .transform = entity.GetShaderTransform(pass),
205  };
206 }
207 
209  const Matrix& transform) const {
210  return bounds_.TransformBounds(transform);
211 }
212 
213 bool DlVerticesGeometry::MaybePerformIndexNormalization(
214  const ContentContext& renderer) {
215  if (vertices_->mode() == flutter::DlVertexMode::kTriangleFan &&
217  indices_ = fromFanIndices(vertices_->vertex_count(),
218  vertices_->index_count(), vertices_->indices());
219  return true;
220  }
221  return false;
222 }
223 
225  return false;
226 }
227 
228 } // namespace impeller
virtual bool SupportsTriangleFan() const =0
Whether the primitive type TriangleFan is supported by the backend.
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
const Capabilities & GetDeviceCapabilities() const
bool HasTextureCoordinates() const override
std::optional< Rect > GetCoverage(const Matrix &transform) const override
bool CanApplyMaskFilter() const override
DlVerticesGeometry(const std::shared_ptr< const flutter::DlVertices > &vertices, const ContentContext &renderer)
std::optional< Rect > GetTextureCoordinateCoverage() const override
GeometryResult GetPositionUVColorBuffer(Rect texture_coverage, Matrix effect_transform, const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
GeometryResult GetPositionBuffer(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
bool HasVertexColors() const override
Matrix GetShaderTransform(const RenderPass &pass) const
Definition: entity.cc:48
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
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:30
Color ToColor(const flutter::DlColor &color)
@ kNone
Does not use the index buffer.
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition: formats.h:352
LinePipeline::VertexShader VS
static constexpr Color BlackTransparent()
Definition: color.h:270
constexpr Color Premultiply() const
Definition: color.h:212
PrimitiveType type
Definition: geometry.h:37
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:476
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:495
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:68