Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit f187197

Browse files
[Impeller] dont unnecessarily copy point data out of display list. (#56492)
Display list now stores impeller::Point objects, so have the PointFieldGeometry reference these points directly. As the dispatching/recording is immediate, there is no need to copy to secondary storage.
1 parent 950e240 commit f187197

File tree

8 files changed

+49
-48
lines changed

8 files changed

+49
-48
lines changed

impeller/display_list/canvas.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,8 @@ void Canvas::ClipGeometry(const Geometry& geometry,
638638
clip_depth);
639639
}
640640

641-
void Canvas::DrawPoints(std::vector<Point> points,
641+
void Canvas::DrawPoints(const Point points[],
642+
uint32_t count,
642643
Scalar radius,
643644
const Paint& paint,
644645
PointStyle point_style) {
@@ -650,7 +651,7 @@ void Canvas::DrawPoints(std::vector<Point> points,
650651
entity.SetTransform(GetCurrentTransform());
651652
entity.SetBlendMode(paint.blend_mode);
652653

653-
PointFieldGeometry geom(std::move(points), radius,
654+
PointFieldGeometry geom(points, count, radius,
654655
/*round=*/point_style == PointStyle::kRound);
655656
AddRenderEntityWithFiltersToCurrentPass(entity, &geom, paint);
656657
}

impeller/display_list/canvas.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ class Canvas {
200200

201201
void DrawCircle(const Point& center, Scalar radius, const Paint& paint);
202202

203-
void DrawPoints(std::vector<Point> points,
203+
void DrawPoints(const Point points[],
204+
uint32_t count,
204205
Scalar radius,
205206
const Paint& paint,
206207
PointStyle point_style);

impeller/display_list/dl_dispatcher.cc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include "impeller/entity/entity.h"
2828
#include "impeller/entity/geometry/ellipse_geometry.h"
2929
#include "impeller/entity/geometry/fill_path_geometry.h"
30-
#include "impeller/entity/geometry/geometry.h"
3130
#include "impeller/entity/geometry/rect_geometry.h"
3231
#include "impeller/entity/geometry/round_rect_geometry.h"
3332
#include "impeller/geometry/color.h"
@@ -663,14 +662,14 @@ void DlDispatcherBase::drawPoints(PointMode mode,
663662
switch (mode) {
664663
case flutter::DlCanvas::PointMode::kPoints: {
665664
// Cap::kButt is also treated as a square.
666-
auto point_style = paint.stroke_cap == Cap::kRound ? PointStyle::kRound
667-
: PointStyle::kSquare;
668-
auto radius = paint.stroke_width;
665+
PointStyle point_style = paint.stroke_cap == Cap::kRound
666+
? PointStyle::kRound
667+
: PointStyle::kSquare;
668+
Scalar radius = paint.stroke_width;
669669
if (radius > 0) {
670670
radius /= 2.0;
671671
}
672-
GetCanvas().DrawPoints(skia_conversions::ToPoints(points, count), radius,
673-
paint, point_style);
672+
GetCanvas().DrawPoints(points, count, radius, paint, point_style);
674673
} break;
675674
case flutter::DlCanvas::PointMode::kLines:
676675
for (uint32_t i = 1; i < count; i += 2) {

impeller/entity/entity_unittests.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "impeller/entity/entity.h"
3636
#include "impeller/entity/entity_playground.h"
3737
#include "impeller/entity/geometry/geometry.h"
38+
#include "impeller/entity/geometry/point_field_geometry.h"
3839
#include "impeller/entity/geometry/stroke_path_geometry.h"
3940
#include "impeller/entity/geometry/superellipse_geometry.h"
4041
#include "impeller/geometry/color.h"
@@ -2095,9 +2096,9 @@ TEST_P(EntityTest, TiledTextureContentsIsOpaque) {
20952096

20962097
TEST_P(EntityTest, PointFieldGeometryCoverage) {
20972098
std::vector<Point> points = {{10, 20}, {100, 200}};
2098-
auto geometry = Geometry::MakePointField(points, 5.0, false);
2099-
ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2100-
ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
2099+
PointFieldGeometry geometry(points.data(), 2, 5.0, false);
2100+
ASSERT_EQ(geometry.GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
2101+
ASSERT_EQ(geometry.GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
21012102
Rect::MakeLTRB(35, 15, 135, 205));
21022103
}
21032104

impeller/entity/geometry/geometry.cc

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
#include "impeller/entity/geometry/ellipse_geometry.h"
1414
#include "impeller/entity/geometry/fill_path_geometry.h"
1515
#include "impeller/entity/geometry/line_geometry.h"
16-
#include "impeller/entity/geometry/point_field_geometry.h"
1716
#include "impeller/entity/geometry/rect_geometry.h"
1817
#include "impeller/entity/geometry/round_rect_geometry.h"
1918
#include "impeller/entity/geometry/stroke_path_geometry.h"
@@ -63,12 +62,6 @@ std::unique_ptr<Geometry> Geometry::MakeFillPath(
6362
return std::make_unique<FillPathGeometry>(path, inner_rect);
6463
}
6564

66-
std::unique_ptr<Geometry> Geometry::MakePointField(std::vector<Point> points,
67-
Scalar radius,
68-
bool round) {
69-
return std::make_unique<PointFieldGeometry>(std::move(points), radius, round);
70-
}
71-
7265
std::unique_ptr<Geometry> Geometry::MakeStrokePath(const Path& path,
7366
Scalar stroke_width,
7467
Scalar miter_limit,

impeller/entity/geometry/geometry.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,6 @@ class Geometry {
8383
static std::unique_ptr<Geometry> MakeRoundRect(const Rect& rect,
8484
const Size& radii);
8585

86-
static std::unique_ptr<Geometry> MakePointField(std::vector<Point> points,
87-
Scalar radius,
88-
bool round);
89-
9086
virtual GeometryResult GetPositionBuffer(const ContentContext& renderer,
9187
const Entity& entity,
9288
RenderPass& pass) const = 0;

impeller/entity/geometry/point_field_geometry.cc

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,22 @@
1212

1313
namespace impeller {
1414

15-
PointFieldGeometry::PointFieldGeometry(std::vector<Point> points,
15+
PointFieldGeometry::PointFieldGeometry(const Point* points,
16+
size_t point_count,
1617
Scalar radius,
1718
bool round)
18-
: points_(std::move(points)), radius_(radius), round_(round) {}
19+
: point_count_(point_count),
20+
radius_(radius),
21+
round_(round),
22+
points_(points) {}
1923

2024
PointFieldGeometry::~PointFieldGeometry() = default;
2125

2226
GeometryResult PointFieldGeometry::GetPositionBuffer(
2327
const ContentContext& renderer,
2428
const Entity& entity,
2529
RenderPass& pass) const {
26-
if (radius_ < 0.0 || points_.empty()) {
30+
if (radius_ < 0.0 || point_count_ == 0) {
2731
return {};
2832
}
2933
const Matrix& transform = entity.GetTransform();
@@ -52,7 +56,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer(
5256
});
5357
FML_DCHECK(circle_vertices.size() == generator.GetVertexCount());
5458

55-
vertex_count = (circle_vertices.size() + 2) * points_.size() - 2;
59+
vertex_count = (circle_vertices.size() + 2) * point_count_ - 2;
5660
buffer_view = host_buffer.Emplace(
5761
vertex_count * sizeof(Point), alignof(Point), [&](uint8_t* data) {
5862
Point* output = reinterpret_cast<Point*>(data);
@@ -66,7 +70,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer(
6670
// the strip. This could be optimized out if we switched to using
6771
// primitive restart.
6872
Point last_point = circle_vertices.back() + center;
69-
for (size_t i = 1; i < points_.size(); i++) {
73+
for (size_t i = 1; i < point_count_; i++) {
7074
Point center = points_[i];
7175
output[offset++] = last_point;
7276
output[offset++] = Point(center + circle_vertices[0]);
@@ -77,7 +81,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer(
7781
}
7882
});
7983
} else {
80-
vertex_count = 6 * points_.size() - 2;
84+
vertex_count = 6 * point_count_ - 2;
8185
buffer_view = host_buffer.Emplace(
8286
vertex_count * sizeof(Point), alignof(Point), [&](uint8_t* data) {
8387
Point* output = reinterpret_cast<Point*>(data);
@@ -97,7 +101,7 @@ GeometryResult PointFieldGeometry::GetPositionBuffer(
97101
// For all subequent points, insert a degenerate triangle to break
98102
// the strip. This could be optimized out if we switched to using
99103
// primitive restart.
100-
for (size_t i = 1; i < points_.size(); i++) {
104+
for (size_t i = 1; i < point_count_; i++) {
101105
Point point = points_[i];
102106
Point first = Point(point.x - radius, point.y - radius);
103107

@@ -129,22 +133,21 @@ GeometryResult PointFieldGeometry::GetPositionBuffer(
129133
// |Geometry|
130134
std::optional<Rect> PointFieldGeometry::GetCoverage(
131135
const Matrix& transform) const {
132-
if (points_.size() > 0) {
136+
if (point_count_ > 0) {
133137
// Doesn't use MakePointBounds as this isn't resilient to points that
134138
// all lie along the same axis.
135-
auto first = points_.begin();
136-
auto last = points_.end();
137-
auto left = first->x;
138-
auto top = first->y;
139-
auto right = first->x;
140-
auto bottom = first->y;
141-
for (auto it = first + 1; it < last; ++it) {
142-
left = std::min(left, it->x);
143-
top = std::min(top, it->y);
144-
right = std::max(right, it->x);
145-
bottom = std::max(bottom, it->y);
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);
146149
}
147-
auto coverage = Rect::MakeLTRB(left - radius_, top - radius_,
150+
Rect coverage = Rect::MakeLTRB(left - radius_, top - radius_,
148151
right + radius_, bottom + radius_);
149152
return coverage.TransformBounds(transform);
150153
}

impeller/entity/geometry/point_field_geometry.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,31 @@
1010
namespace impeller {
1111

1212
/// @brief A geometry class specialized for Canvas::DrawPoints.
13+
///
14+
/// Does not hold ownership of the allocated point data, which is expected to be
15+
/// maintained via the display list structure.
1316
class PointFieldGeometry final : public Geometry {
1417
public:
15-
PointFieldGeometry(std::vector<Point> points, Scalar radius, bool round);
18+
PointFieldGeometry(const Point* points,
19+
size_t point_count,
20+
Scalar radius,
21+
bool round);
1622

1723
~PointFieldGeometry() override;
1824

25+
// |Geometry|
26+
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
27+
1928
private:
2029
// |Geometry|
2130
GeometryResult GetPositionBuffer(const ContentContext& renderer,
2231
const Entity& entity,
2332
RenderPass& pass) const override;
2433

25-
// |Geometry|
26-
std::optional<Rect> GetCoverage(const Matrix& transform) const override;
27-
28-
std::vector<Point> points_;
34+
size_t point_count_;
2935
Scalar radius_;
3036
bool round_;
37+
const Point* points_;
3138

3239
PointFieldGeometry(const PointFieldGeometry&) = delete;
3340

0 commit comments

Comments
 (0)