| 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
5 #include "impeller/entity/geometry/vertices_geometry.h"
6
7 #include <cstdint>
8 #include <utility>
9
10 #include "impeller/core/buffer_view.h"
11 #include "impeller/entity/contents/content_context.h"
12 #include "impeller/geometry/color.h"
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_) {
74 case VerticesGeometry::VertexMode::kTriangleFan:
75 // Unrolled into triangle mode.
76 return PrimitiveType::kTriangle;
77 case VerticesGeometry::VertexMode::kTriangleStrip:
78 return PrimitiveType::kTriangleStrip;
79 case VerticesGeometry::VertexMode::kTriangles:
80 return PrimitiveType::kTriangle;
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
92 bool VerticesGeometry::HasVertexColors() const {
93 return colors_.size() > 0;
94 }
95
96 bool VerticesGeometry::HasTextureCoordinates() const {
97 return texture_coordinates_.size() > 0;
98 }
99
100 std::optional<Rect> VerticesGeometry::GetTextureCoordinateCoverge() const {
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
113 GeometryResult VerticesGeometry::GetPositionBuffer(
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
147 GeometryResult VerticesGeometry::GetPositionUVColorBuffer(
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 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