[Impeller] Refactor all tessellation calls to use builder callback, rename. (#36706)
diff --git a/impeller/entity/contents/texture_contents.cc b/impeller/entity/contents/texture_contents.cc
index d57b1e9..1a36167 100644
--- a/impeller/entity/contents/texture_contents.cc
+++ b/impeller/entity/contents/texture_contents.cc
@@ -119,15 +119,24 @@
{
const auto tess_result = renderer.GetTessellator()->Tessellate(
path_.GetFillType(), path_.CreatePolyline(),
- [this, &vertex_builder, &coverage_rect, &texture_size](Point vtx) {
- VS::PerVertexData data;
- data.position = vtx;
- auto coverage_coords =
- (vtx - coverage_rect->origin) / coverage_rect->size;
- data.texture_coords =
- (source_rect_.origin + source_rect_.size * coverage_coords) /
- texture_size;
- vertex_builder.AppendVertex(data);
+ [this, &vertex_builder, &coverage_rect, &texture_size](
+ const float* vertices, size_t vertices_size,
+ const uint16_t* indices, size_t indices_size) {
+ for (auto i = 0u; i < vertices_size; i++) {
+ VS::PerVertexData data;
+ Point vtx = {vertices[i], vertices[i + 1]};
+ data.position = vtx;
+ auto coverage_coords =
+ (vtx - coverage_rect->origin) / coverage_rect->size;
+ data.texture_coords =
+ (source_rect_.origin + source_rect_.size * coverage_coords) /
+ texture_size;
+ vertex_builder.AppendVertex(data);
+ }
+ for (auto i = 0u; i < indices_size; i++) {
+ vertex_builder.AppendIndex(indices[i]);
+ }
+ return true;
});
if (tess_result == Tessellator::Result::kInputError) {
diff --git a/impeller/entity/geometry.cc b/impeller/entity/geometry.cc
index 5cbaf27..b24452d 100644
--- a/impeller/entity/geometry.cc
+++ b/impeller/entity/geometry.cc
@@ -184,7 +184,7 @@
std::shared_ptr<Tessellator> tessellator,
ISize render_target_size) {
VertexBuffer vertex_buffer;
- auto tesselation_result = tessellator->TessellateBuilder(
+ auto tesselation_result = tessellator->Tessellate(
path_.GetFillType(), path_.CreatePolyline(),
[&vertex_buffer, &host_buffer](
const float* vertices, size_t vertices_count, const uint16_t* indices,
diff --git a/impeller/geometry/geometry_benchmarks.cc b/impeller/geometry/geometry_benchmarks.cc
index 9b66318..06b514b 100644
--- a/impeller/geometry/geometry_benchmarks.cc
+++ b/impeller/geometry/geometry_benchmarks.cc
@@ -33,7 +33,10 @@
single_point_count = polyline.points.size();
point_count += single_point_count;
if (tessellate) {
- tess.Tessellate(FillType::kNonZero, polyline, [](Point) {});
+ tess.Tessellate(
+ FillType::kNonZero, polyline,
+ [](const float* vertices, size_t vertices_size,
+ const uint16_t* indices, size_t indices_size) { return true; });
}
}
state.counters["SinglePointCount"] = single_point_count;
diff --git a/impeller/renderer/renderer_unittests.cc b/impeller/renderer/renderer_unittests.cc
index c905978..bdb63c6 100644
--- a/impeller/renderer/renderer_unittests.cc
+++ b/impeller/renderer/renderer_unittests.cc
@@ -397,18 +397,25 @@
VertexBufferBuilder<VS::PerVertexData> builder;
- ASSERT_EQ(
- Tessellator::Result::kSuccess,
- Tessellator{}.Tessellate(FillType::kPositive,
- PathBuilder{}
- .AddRect(Rect::MakeXYWH(10, 10, 100, 100))
- .TakePath()
- .CreatePolyline(),
- [&builder](Point vtx) {
- VS::PerVertexData data;
- data.vtx = vtx;
- builder.AppendVertex(data);
- }));
+ ASSERT_EQ(Tessellator::Result::kSuccess,
+ Tessellator{}.Tessellate(
+ FillType::kPositive,
+ PathBuilder{}
+ .AddRect(Rect::MakeXYWH(10, 10, 100, 100))
+ .TakePath()
+ .CreatePolyline(),
+ [&builder](const float* vertices, size_t vertices_size,
+ const uint16_t* indices, size_t indices_size) {
+ for (auto i = 0u; i < vertices_size; i += 2) {
+ VS::PerVertexData data;
+ data.vtx = {vertices[i], vertices[i + 1]};
+ builder.AppendVertex(data);
+ }
+ for (auto i = 0u; i < indices_size; i++) {
+ builder.AppendIndex(indices[i]);
+ }
+ return true;
+ }));
ASSERT_NE(GetContext(), nullptr);
auto pipeline =
diff --git a/impeller/tessellator/c/tessellator.cc b/impeller/tessellator/c/tessellator.cc
index 7a53d9c..86a4cdf 100644
--- a/impeller/tessellator/c/tessellator.cc
+++ b/impeller/tessellator/c/tessellator.cc
@@ -46,11 +46,22 @@
auto smoothing = SmoothingApproximation(scale, angle_tolerance, cusp_limit);
auto polyline = path.CreatePolyline(smoothing);
std::vector<float> points;
- if (Tessellator{}.Tessellate(path.GetFillType(), polyline,
- [&points](Point vertex) {
- points.push_back(vertex.x);
- points.push_back(vertex.y);
- }) != Tessellator::Result::kSuccess) {
+ if (Tessellator{}.Tessellate(
+ path.GetFillType(), polyline,
+ [&points](const float* vertices, size_t vertices_size,
+ const uint16_t* indices, size_t indices_size) {
+ // Results are expected to be re-duplicated.
+ std::vector<Point> raw_points;
+ for (auto i = 0u; i < vertices_size; i += 2) {
+ raw_points.emplace_back(Point{vertices[i], vertices[i + 1]});
+ }
+ for (auto i = 0u; i < indices_size; i++) {
+ auto point = raw_points[indices[i]];
+ points.push_back(point.x);
+ points.push_back(point.y);
+ }
+ return true;
+ }) != Tessellator::Result::kSuccess) {
return nullptr;
}
diff --git a/impeller/tessellator/tessellator.cc b/impeller/tessellator/tessellator.cc
index 7273231..4e2c3c5 100644
--- a/impeller/tessellator/tessellator.cc
+++ b/impeller/tessellator/tessellator.cc
@@ -55,82 +55,6 @@
Tessellator::Result Tessellator::Tessellate(
FillType fill_type,
const Path::Polyline& polyline,
- const VertexCallback& callback) const {
- if (!callback) {
- return Result::kInputError;
- }
-
- if (polyline.points.empty()) {
- return Result::kInputError;
- }
-
- auto tessellator = c_tessellator_.get();
- if (!tessellator) {
- return Result::kTessellationError;
- }
-
- constexpr int kVertexSize = 2;
- constexpr int kPolygonSize = 3;
-
- //----------------------------------------------------------------------------
- /// Feed contour information to the tessellator.
- ///
- static_assert(sizeof(Point) == 2 * sizeof(float));
- for (size_t contour_i = 0; contour_i < polyline.contours.size();
- contour_i++) {
- size_t start_point_index, end_point_index;
- std::tie(start_point_index, end_point_index) =
- polyline.GetContourPointBounds(contour_i);
-
- ::tessAddContour(tessellator, // the C tessellator
- kVertexSize, //
- polyline.points.data() + start_point_index, //
- sizeof(Point), //
- end_point_index - start_point_index //
- );
- }
-
- //----------------------------------------------------------------------------
- /// Let's tessellate.
- ///
- auto result = ::tessTesselate(tessellator, // tessellator
- ToTessWindingRule(fill_type), // winding
- TESS_POLYGONS, // element type
- kPolygonSize, // polygon size
- kVertexSize, // vertex size
- nullptr // normal (null is automatic)
- );
-
- if (result != 1) {
- return Result::kTessellationError;
- }
-
- // TODO(csg): This copy can be elided entirely for the current use case.
- std::vector<Point> points;
- std::vector<uint32_t> indices;
-
- int vertexItemCount = tessGetVertexCount(tessellator) * kVertexSize;
- auto vertices = tessGetVertices(tessellator);
- for (int i = 0; i < vertexItemCount; i += 2) {
- points.emplace_back(vertices[i], vertices[i + 1]);
- }
-
- int elementItemCount = tessGetElementCount(tessellator) * kPolygonSize;
- auto elements = tessGetElements(tessellator);
- for (int i = 0; i < elementItemCount; i++) {
- indices.emplace_back(elements[i]);
- }
-
- for (auto index : indices) {
- auto vtx = points[index];
- callback(vtx);
- }
- return Result::kSuccess;
-}
-
-Tessellator::Result Tessellator::TessellateBuilder(
- FillType fill_type,
- const Path::Polyline& polyline,
const BuilderCallback& callback) const {
if (!callback) {
return Result::kInputError;
diff --git a/impeller/tessellator/tessellator.h b/impeller/tessellator/tessellator.h
index de2b8be..3a5ae97 100644
--- a/impeller/tessellator/tessellator.h
+++ b/impeller/tessellator/tessellator.h
@@ -43,7 +43,6 @@
~Tessellator();
- using VertexCallback = std::function<void(Point)>;
using BuilderCallback = std::function<bool(const float* vertices,
size_t vertices_size,
const uint16_t* indices,
@@ -51,20 +50,6 @@
//----------------------------------------------------------------------------
/// @brief Generates filled triangles from the polyline. A callback is
- /// invoked for each vertex of the triangle.
- ///
- /// @param[in] fill_type The fill rule to use when filling.
- /// @param[in] polyline The polyline
- /// @param[in] callback The callback
- ///
- /// @return The result status of the tessellation.
- ///
- Tessellator::Result Tessellate(FillType fill_type,
- const Path::Polyline& polyline,
- const VertexCallback& callback) const;
-
- //----------------------------------------------------------------------------
- /// @brief Generates filled triangles from the polyline. A callback is
/// invoked once for the entire tessellation.
///
/// @param[in] fill_type The fill rule to use when filling.
@@ -73,9 +58,9 @@
///
/// @return The result status of the tessellation.
///
- Tessellator::Result TessellateBuilder(FillType fill_type,
- const Path::Polyline& polyline,
- const BuilderCallback& callback) const;
+ Tessellator::Result Tessellate(FillType fill_type,
+ const Path::Polyline& polyline,
+ const BuilderCallback& callback) const;
private:
CTessellator c_tessellator_;
diff --git a/impeller/tessellator/tessellator_unittests.cc b/impeller/tessellator/tessellator_unittests.cc
index 24af430..56c2478 100644
--- a/impeller/tessellator/tessellator_unittests.cc
+++ b/impeller/tessellator/tessellator_unittests.cc
@@ -10,64 +10,12 @@
namespace impeller {
namespace testing {
-TEST(TessellatorTest, TessellatorReturnsCorrectResultStatus) {
- // Zero points.
- {
- Tessellator t;
- auto polyline = PathBuilder{}.TakePath().CreatePolyline();
- Tessellator::Result result =
- t.Tessellate(FillType::kPositive, polyline, [](Point point) {});
-
- ASSERT_EQ(polyline.points.size(), 0u);
- ASSERT_EQ(result, Tessellator::Result::kInputError);
- }
-
- // One point.
- {
- Tessellator t;
- auto polyline = PathBuilder{}.LineTo({0, 0}).TakePath().CreatePolyline();
- Tessellator::Result result =
- t.Tessellate(FillType::kPositive, polyline, [](Point point) {});
-
- ASSERT_EQ(polyline.points.size(), 1u);
- ASSERT_EQ(result, Tessellator::Result::kSuccess);
- }
-
- // Two points.
- {
- Tessellator t;
- auto polyline =
- PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline();
- Tessellator::Result result =
- t.Tessellate(FillType::kPositive, polyline, [](Point point) {});
-
- ASSERT_EQ(polyline.points.size(), 2u);
- ASSERT_EQ(result, Tessellator::Result::kSuccess);
- }
-
- // Many points.
- {
- Tessellator t;
- PathBuilder builder;
- for (int i = 0; i < 1000; i++) {
- auto coord = i * 1.0f;
- builder.AddLine({coord, coord}, {coord + 1, coord + 1});
- }
- auto polyline = builder.TakePath().CreatePolyline();
- Tessellator::Result result =
- t.Tessellate(FillType::kPositive, polyline, [](Point point) {});
-
- ASSERT_EQ(polyline.points.size(), 2000u);
- ASSERT_EQ(result, Tessellator::Result::kSuccess);
- }
-}
-
TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
// Zero points.
{
Tessellator t;
auto polyline = PathBuilder{}.TakePath().CreatePolyline();
- Tessellator::Result result = t.TessellateBuilder(
+ Tessellator::Result result = t.Tessellate(
FillType::kPositive, polyline,
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
size_t indices_size) { return true; });
@@ -80,7 +28,7 @@
{
Tessellator t;
auto polyline = PathBuilder{}.LineTo({0, 0}).TakePath().CreatePolyline();
- Tessellator::Result result = t.TessellateBuilder(
+ Tessellator::Result result = t.Tessellate(
FillType::kPositive, polyline,
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
size_t indices_size) { return true; });
@@ -93,7 +41,7 @@
Tessellator t;
auto polyline =
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline();
- Tessellator::Result result = t.TessellateBuilder(
+ Tessellator::Result result = t.Tessellate(
FillType::kPositive, polyline,
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
size_t indices_size) { return true; });
@@ -111,7 +59,7 @@
builder.AddLine({coord, coord}, {coord + 1, coord + 1});
}
auto polyline = builder.TakePath().CreatePolyline();
- Tessellator::Result result = t.TessellateBuilder(
+ Tessellator::Result result = t.Tessellate(
FillType::kPositive, polyline,
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
size_t indices_size) { return true; });
@@ -125,7 +73,7 @@
Tessellator t;
auto polyline =
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline();
- Tessellator::Result result = t.TessellateBuilder(
+ Tessellator::Result result = t.Tessellate(
FillType::kPositive, polyline,
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
size_t indices_size) { return false; });