Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
14namespace 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.
22static 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
57VerticesGeometry::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
72PrimitiveType VerticesGeometry::GetPrimitiveType() const {
73 switch (vertex_mode_) {
75 // Unrolled into triangle mode.
81 }
82}
83
84void VerticesGeometry::NormalizeIndices() {
85 // Convert triangle fan if present.
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
203 const Matrix& transform) const {
204 return bounds_.TransformBounds(transform);
205}
206
207} // namespace impeller
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition entity.cc:50
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition render_pass.h:33
std::optional< Rect > GetCoverage(const Matrix &transform) const override
std::optional< Rect > GetTextureCoordinateCoverge() const
GeometryResult GetPositionUVColorBuffer(Rect texture_coverage, Matrix effect_transform, const ContentContext &renderer, const Entity &entity, RenderPass &pass) const
GeometryResult GetPositionBuffer(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
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)
@ kNone
Does not use the index buffer.
PrimitiveType
Decides how backend draws pixels based on input vertices.
Definition formats.h:353
static std::vector< uint16_t > fromFanIndices(const std::vector< Point > &vertices, const std::vector< uint16_t > &indices)
SolidFillVertexShader VS
Definition ref_ptr.h:256
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition p3.cpp:47
static constexpr Color BlackTransparent()
Definition color.h:262
PrimitiveType type
Definition geometry.h:35
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:440
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:459
static constexpr std::optional< TRect > MakePointBounds(const U &value)
Definition rect.h:151