[Impeller] move path out of PathBuilder in TakePath. (#50444)
We should move this path so we don't end up allocating/deallocating twice.
Fixes https://github.com/flutter/flutter/issues/142873
diff --git a/impeller/geometry/path.cc b/impeller/geometry/path.cc
index 1e175de..2eb682f 100644
--- a/impeller/geometry/path.cc
+++ b/impeller/geometry/path.cc
@@ -15,11 +15,7 @@
Path::Path() : data_(new Data()) {}
-Path::Path(const Data& data) : data_(new Data(data)) {
- FML_DCHECK(data_->points.size() == data_->points.capacity());
- FML_DCHECK(data_->components.size() == data_->components.capacity());
- FML_DCHECK(data_->contours.size() == data_->contours.capacity());
-}
+Path::Path(Data data) : data_(std::make_shared<Data>(std::move(data))) {}
Path::~Path() = default;
diff --git a/impeller/geometry/path.h b/impeller/geometry/path.h
index ccca96a..ea01338 100644
--- a/impeller/geometry/path.h
+++ b/impeller/geometry/path.h
@@ -200,6 +200,9 @@
// builder from affecting the existing taken paths.
struct Data {
Data() = default;
+
+ Data(Data&& other) = default;
+
Data(const Data& other) = default;
~Data() = default;
@@ -211,11 +214,9 @@
std::vector<ContourComponent> contours;
std::optional<Rect> bounds;
-
- bool locked = false;
};
- explicit Path(const Data& data);
+ explicit Path(Data data);
std::shared_ptr<const Data> data_;
};
diff --git a/impeller/geometry/path_builder.cc b/impeller/geometry/path_builder.cc
index c70a049..5cc9e28 100644
--- a/impeller/geometry/path_builder.cc
+++ b/impeller/geometry/path_builder.cc
@@ -22,7 +22,7 @@
Path PathBuilder::TakePath(FillType fill) {
prototype_.fill = fill;
UpdateBounds();
- return Path(prototype_);
+ return Path(std::move(prototype_));
}
void PathBuilder::Reserve(size_t point_size, size_t verb_size) {
diff --git a/impeller/geometry/path_unittests.cc b/impeller/geometry/path_unittests.cc
index a848d2e..52434cf 100644
--- a/impeller/geometry/path_unittests.cc
+++ b/impeller/geometry/path_unittests.cc
@@ -486,7 +486,7 @@
}
}
-TEST(PathTest, PathBuilderDoesNotMutateTakenPaths) {
+TEST(PathTest, PathBuilderDoesNotMutateCopiedPaths) {
auto test_isolation =
[](const std::function<void(PathBuilder & builder)>& mutator,
bool will_close, Point mutation_offset, const std::string& label) {
@@ -525,23 +525,23 @@
}
};
- auto path1 = builder.TakePath();
+ auto path1 = builder.CopyPath();
verify_path(path1, false, false, {},
"Initial Path1 state before " + label);
for (int i = 0; i < 10; i++) {
- auto path = builder.TakePath();
+ auto path = builder.CopyPath();
verify_path(
path, false, false, {},
- "Extra TakePath #" + std::to_string(i + 1) + " for " + label);
+ "Extra CopyPath #" + std::to_string(i + 1) + " for " + label);
}
mutator(builder);
verify_path(path1, false, false, {},
"Path1 state after subsequent " + label);
- auto path2 = builder.TakePath();
+ auto path2 = builder.CopyPath();
verify_path(path1, false, false, {},
- "Path1 state after subsequent " + label + " and TakePath");
+ "Path1 state after subsequent " + label + " and CopyPath");
verify_path(path2, true, will_close, mutation_offset,
"Initial Path2 state with subsequent " + label);
};