Flutter Engine
 
Loading...
Searching...
No Matches
point_field_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
16 size_t point_count,
17 Scalar radius,
18 bool round)
19 : point_count_(point_count),
20 radius_(radius),
21 round_(round),
22 points_(points) {}
23
25
26GeometryResult PointFieldGeometry::GetPositionBuffer(
27 const ContentContext& renderer,
28 const Entity& entity,
29 RenderPass& pass) const {
30 if (radius_ < 0.0 || point_count_ == 0) {
31 return {};
32 }
33 const Matrix& transform = entity.GetTransform();
35 if (max_basis == 0) {
36 return {};
37 }
38
39 Scalar min_size = 0.5f / max_basis;
40 Scalar radius = std::max(radius_, min_size);
41 HostBuffer& data_host_buffer = renderer.GetTransientsDataBuffer();
42 BufferView buffer_view;
43 size_t vertex_count = 0;
44
45 if (round_) {
46 // Get triangulation relative to {0, 0} so we can translate it to each
47 // point in turn.
48 Tessellator::EllipticalVertexGenerator generator =
49 renderer.GetTessellator().FilledCircle(transform, {}, radius);
50 FML_DCHECK(generator.GetTriangleType() == PrimitiveType::kTriangleStrip);
51
52 std::vector<Point> circle_vertices;
53 circle_vertices.reserve(generator.GetVertexCount());
54 generator.GenerateVertices([&circle_vertices](const Point& p) { //
55 circle_vertices.push_back(p);
56 });
57 FML_DCHECK(circle_vertices.size() == generator.GetVertexCount());
58
59 vertex_count = (circle_vertices.size() + 2) * point_count_ - 2;
60 buffer_view = data_host_buffer.Emplace(
61 vertex_count * sizeof(Point), alignof(Point), [&](uint8_t* data) {
62 Point* output = reinterpret_cast<Point*>(data);
63 size_t offset = 0;
64
65 Point center = points_[0];
66 for (auto& vertex : circle_vertices) {
67 output[offset++] = static_cast<Point>(center + vertex);
68 }
69 // For all subequent points, insert a degenerate triangle to break
70 // the strip. This could be optimized out if we switched to using
71 // primitive restart.
72 Point last_point = circle_vertices.back() + center;
73 for (size_t i = 1; i < point_count_; i++) {
74 Point center = points_[i];
75 output[offset++] = last_point;
76 output[offset++] = static_cast<Point>(center + circle_vertices[0]);
77 for (const Point& vertex : circle_vertices) {
78 output[offset++] = static_cast<Point>(center + vertex);
79 }
80 last_point = circle_vertices.back() + center;
81 }
82 });
83 } else {
84 vertex_count = 6 * point_count_ - 2;
85 buffer_view = data_host_buffer.Emplace(
86 vertex_count * sizeof(Point), alignof(Point), [&](uint8_t* data) {
87 Point* output = reinterpret_cast<Point*>(data);
88 size_t offset = 0;
89
90 Point point = points_[0];
91 Point first = Point(point.x - radius, point.y - radius);
92
93 // Z pattern from UL -> UR -> LL -> LR
94 Point last_point = Point(0, 0);
95 output[offset++] = first;
96 output[offset++] = Point(point.x + radius, point.y - radius);
97 output[offset++] = Point(point.x - radius, point.y + radius);
98 output[offset++] = last_point =
99 Point(point.x + radius, point.y + radius);
100
101 // For all subequent points, insert a degenerate triangle to break
102 // the strip. This could be optimized out if we switched to using
103 // primitive restart.
104 for (size_t i = 1; i < point_count_; i++) {
105 Point point = points_[i];
106 Point first = Point(point.x - radius, point.y - radius);
107
108 output[offset++] = last_point;
109 output[offset++] = first;
110
111 output[offset++] = first;
112 output[offset++] = Point(point.x + radius, point.y - radius);
113 output[offset++] = Point(point.x - radius, point.y + radius);
114 output[offset++] = last_point =
115 Point(point.x + radius, point.y + radius);
116 }
117 });
118 }
119
120 return GeometryResult{
122 .vertex_buffer =
123 VertexBuffer{
124 .vertex_buffer = std::move(buffer_view),
125 .index_buffer = {},
126 .vertex_count = vertex_count,
127 .index_type = IndexType::kNone,
128 },
129 .transform = entity.GetShaderTransform(pass),
130 };
131}
132
133// |Geometry|
135 const Matrix& transform) const {
136 if (point_count_ > 0) {
137 // Doesn't use MakePointBounds as this isn't resilient to points that
138 // all lie along the same axis.
139 Scalar left = points_[0].x;
140 Scalar top = points_[0].y;
141 Scalar right = points_[0].x;
142 Scalar bottom = points_[0].y;
143 for (auto i = 1u; i < point_count_; i++) {
144 const Point point = points_[i];
145 left = std::min(left, point.x);
146 top = std::min(top, point.y);
147 right = std::max(right, point.x);
148 bottom = std::max(bottom, point.y);
149 }
150 Rect coverage = Rect::MakeLTRB(left - radius_, top - radius_,
151 right + radius_, bottom + radius_);
152 return coverage.TransformBounds(transform);
153 }
154 return std::nullopt;
155}
156
157} // namespace impeller
BufferView buffer_view
HostBuffer & GetTransientsDataBuffer() const
Retrieve the current host buffer for transient storage of other non-index data.
Tessellator & GetTessellator() const
Matrix GetShaderTransform(const RenderPass &pass) const
Definition entity.cc:48
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition entity.cc:44
std::optional< Rect > GetCoverage(const Matrix &transform) const override
PointFieldGeometry(const Point *points, size_t point_count, Scalar radius, bool round)
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition render_pass.h:30
EllipticalVertexGenerator FilledCircle(const Matrix &view_transform, const Point &center, Scalar radius)
Create a |VertexGenerator| that can produce vertices for a filled circle of the given radius around t...
#define FML_DCHECK(condition)
Definition logging.h:122
float Scalar
Definition scalar.h:19
@ kNone
Does not use the index buffer.
TPoint< Scalar > Point
Definition point.h:327
A 4x4 matrix using column-major storage.
Definition matrix.h:37
Scalar GetMaxBasisLengthXY() const
Return the maximum scale applied specifically to either the X axis or Y axis unit vectors (the bases)...
Definition matrix.h:328
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition rect.h:472
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129
std::vector< Point > points
std::shared_ptr< const fml::Mapping > data