| 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/buffer_view.h"
8 #include "impeller/core/formats.h"
9 #include "impeller/core/vertex_buffer.h"
10 #include "impeller/entity/geometry/geometry.h"
11 #include "impeller/renderer/command_buffer.h"
12
13 namespace impeller {
14
15 PointFieldGeometry::PointFieldGeometry(const Point* points,
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
24 PointFieldGeometry::~PointFieldGeometry() = default;
25
26 GeometryResult 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();
34 Scalar max_basis = transform.GetMaxBasisLengthXY();
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& host_buffer = renderer.GetTransientsBuffer();
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 = 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 = 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{
121 .type = PrimitiveType::kTriangleStrip,
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|
134 std::optional<Rect> PointFieldGeometry::GetCoverage(
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
buffer_view
BufferView buffer_view
Definition: blit_command_gles.cc:152
buffer_view.h
impeller::ContentContext
Definition: content_context.h:138
impeller::ContentContext::GetTransientsBuffer
HostBuffer & GetTransientsBuffer() const
Retrieve the currnent host buffer for transient storage.
Definition: content_context.h:296
impeller::ContentContext::GetTessellator
Tessellator & GetTessellator() const
Definition: content_context.cc:909
impeller::Entity
Definition: entity.h:20
impeller::Entity::GetShaderTransform
Matrix GetShaderTransform(const RenderPass &pass) const
Get the vertex shader transform used for drawing this Entity.
Definition: entity.cc:48
impeller::Entity::GetTransform
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition: entity.cc:44
impeller::PointFieldGeometry::GetCoverage
std::optional< Rect > GetCoverage(const Matrix &transform) const override
Definition: point_field_geometry.cc:134
impeller::PointFieldGeometry::~PointFieldGeometry
~PointFieldGeometry() override
impeller::PointFieldGeometry::PointFieldGeometry
PointFieldGeometry(const Point *points, size_t point_count, Scalar radius, bool round)
Definition: point_field_geometry.cc:15
impeller::RenderPass
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition: render_pass.h:30
impeller::Tessellator::FilledCircle
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...
Definition: tessellator.cc:339
command_buffer.h
formats.h
transform
Matrix transform
Definition: gaussian_blur_filter_contents.cc:214
geometry.h
impeller
Definition: allocation.cc:12
impeller::IndexType::kNone
@ kNone
Does not use the index buffer.
impeller::PrimitiveType::kTriangleStrip
@ kTriangleStrip
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::Point
TPoint< Scalar > Point
Definition: point.h:327
impeller::EllipticalVertexGenerator
Tessellator::EllipticalVertexGenerator EllipticalVertexGenerator
Definition: tessellator.cc:326
point_field_geometry.h
offset
SeparatedVector2 offset
Definition: stroke_path_geometry.cc:322
impeller::GeometryResult
Definition: geometry.h:21
impeller::Matrix
A 4x4 matrix using column-major storage.
Definition: matrix.h:37
impeller::TPoint< Scalar >
impeller::TPoint::y
Type y
Definition: point.h:31
impeller::TPoint::x
Type x
Definition: point.h:30
impeller::TRect< Scalar >
impeller::TRect::TransformBounds
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition: rect.h:476
impeller::TRect< Scalar >::MakeLTRB
constexpr static TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition: rect.h:129
data
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:67
vertex_buffer.h