| Flutter Impeller |

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
5 #include "impeller/entity/geometry/point_field_geometry.h"
6
7 #include "impeller/core/formats.h"
8 #include "impeller/entity/geometry/geometry.h"
9 #include "impeller/renderer/command_buffer.h"
10
11 namespace impeller {
12
13 PointFieldGeometry::PointFieldGeometry(std::vector<Point> points,
14 Scalar radius,
15 bool round)
16 : points_(std::move(points)), radius_(radius), round_(round) {}
17
18 PointFieldGeometry::~PointFieldGeometry() = default;
19
20 GeometryResult PointFieldGeometry::GetPositionBuffer(
21 const ContentContext& renderer,
22 const Entity& entity,
23 RenderPass& pass) const {
24 if (radius_ < 0.0) {
25 return {};
26 }
27 const Matrix& transform = entity.GetTransform();
28
29 Scalar max_basis = transform.GetMaxBasisLengthXY();
30 if (max_basis == 0) {
31 return {};
32 }
33 Scalar min_size = 0.5f / max_basis;
34 Scalar radius = std::max(radius_, min_size);
35
36 HostBuffer& host_buffer = renderer.GetTransientsBuffer();
37 VertexBufferBuilder<SolidFillVertexShader::PerVertexData> vtx_builder;
38 if (round_) {
39 // Get triangulation relative to {0, 0} so we can translate it to each
40 // point in turn.
41 auto generator =
42 renderer.GetTessellator()->FilledCircle(transform, {}, radius);
43 FML_DCHECK(generator.GetTriangleType() == PrimitiveType::kTriangleStrip);
44 std::vector<Point> circle_vertices;
45 circle_vertices.reserve(generator.GetVertexCount());
46 generator.GenerateVertices([&circle_vertices](const Point& p) { //
47 circle_vertices.push_back(p);
48 });
49 FML_DCHECK(circle_vertices.size() == generator.GetVertexCount());
50
51 vtx_builder.Reserve((circle_vertices.size() + 2) * points_.size() - 2);
52 for (auto& center : points_) {
53 if (vtx_builder.HasVertices()) {
54 vtx_builder.AppendVertex(vtx_builder.Last());
55 vtx_builder.AppendVertex({center + circle_vertices[0]});
56 }
57
58 for (auto& vertex : circle_vertices) {
59 vtx_builder.AppendVertex({center + vertex});
60 }
61 }
62 } else {
63 vtx_builder.Reserve(6 * points_.size() - 2);
64 for (auto& point : points_) {
65 auto first = Point(point.x - radius, point.y - radius);
66
67 if (vtx_builder.HasVertices()) {
68 vtx_builder.AppendVertex(vtx_builder.Last());
69 vtx_builder.AppendVertex({first});
70 }
71
72 // Z pattern from UL -> UR -> LL -> LR
73 vtx_builder.AppendVertex({first});
74 vtx_builder.AppendVertex({{point.x + radius, point.y - radius}});
75 vtx_builder.AppendVertex({{point.x - radius, point.y + radius}});
76 vtx_builder.AppendVertex({{point.x + radius, point.y + radius}});
77 }
78 }
79
80 return GeometryResult{
81 .type = PrimitiveType::kTriangleStrip,
82 .vertex_buffer = vtx_builder.CreateVertexBuffer(host_buffer),
83 .transform = entity.GetShaderTransform(pass),
84 };
85 }
86
87 // |Geometry|
88 std::optional<Rect> PointFieldGeometry::GetCoverage(
89 const Matrix& transform) const {
90 if (points_.size() > 0) {
91 // Doesn't use MakePointBounds as this isn't resilient to points that
92 // all lie along the same axis.
93 auto first = points_.begin();
94 auto last = points_.end();
95 auto left = first->x;
96 auto top = first->y;
97 auto right = first->x;
98 auto bottom = first->y;
99 for (auto it = first + 1; it < last; ++it) {
100 left = std::min(left, it->x);
101 top = std::min(top, it->y);
102 right = std::max(right, it->x);
103 bottom = std::max(bottom, it->y);
104 }
105 auto coverage = Rect::MakeLTRB(left - radius_, top - radius_,
106 right + radius_, bottom + radius_);
107 return coverage.TransformBounds(transform);
108 }
109 return std::nullopt;
110 }
111
112 } // namespace impeller
impeller::Entity::GetShaderTransform
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition: entity.cc:51
impeller::Scalar
float Scalar
Definition: scalar.h:18
geometry.h
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:47
point_field_geometry.h
impeller::PointFieldGeometry::PointFieldGeometry
PointFieldGeometry(std::vector< Point > points, Scalar radius, bool round)
Definition: point_field_geometry.cc:13
formats.h
impeller::Entity
Definition: entity.h:20
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:213
impeller::GeometryResult
Definition: geometry.h:26
impeller::ContentContext::GetTessellator
std::shared_ptr< Tessellator > GetTessellator() const
Definition: content_context.cc:546
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:33
command_buffer.h
impeller::PointFieldGeometry::~PointFieldGeometry
~PointFieldGeometry() override
std
Definition: comparable.h:95
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
impeller
Definition: allocation.cc:12
impeller::ContentContext
Definition: content_context.h:366
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:753