Flutter Engine
 
Loading...
Searching...
No Matches
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
12
13namespace impeller {
14
15namespace {
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.
23static 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
68PrimitiveType DlVerticesGeometry::GetPrimitiveType() const {
69 switch (vertices_->mode()) {
71 // Unrolled into triangle mode.
72 if (performed_normalization_) {
74 }
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.GetTransientsDataBuffer().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.GetTransientsIndexesBuffer().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 {
153 using VS = PorterDuffBlendPipeline::VertexShader;
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.GetTransientsDataBuffer().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.GetTransientsIndexesBuffer().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
213bool 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 & GetTransientsDataBuffer() const
Retrieve the current host buffer for transient storage of other non-index data.
const Capabilities & GetDeviceCapabilities() const
HostBuffer & GetTransientsIndexesBuffer() const
Retrieve the current host buffer for transient storage of indexes used for indexed draws.
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
@ kTriangles
The vertices are taken 3 at a time to form a triangle.
Color ToColor(const flutter::DlColor &color)
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition formats.h:352
@ kNone
Does not use the index buffer.
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:472
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:491
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129
std::shared_ptr< const fml::Mapping > data