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

Commit 213e294

Browse files
[Impeller] Refactor all tessellation calls to use builder callback, rename. (#36706)
1 parent 48d42f7 commit 213e294

File tree

8 files changed

+66
-179
lines changed

8 files changed

+66
-179
lines changed

impeller/entity/contents/texture_contents.cc

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,24 @@ bool TextureContents::Render(const ContentContext& renderer,
119119
{
120120
const auto tess_result = renderer.GetTessellator()->Tessellate(
121121
path_.GetFillType(), path_.CreatePolyline(),
122-
[this, &vertex_builder, &coverage_rect, &texture_size](Point vtx) {
123-
VS::PerVertexData data;
124-
data.position = vtx;
125-
auto coverage_coords =
126-
(vtx - coverage_rect->origin) / coverage_rect->size;
127-
data.texture_coords =
128-
(source_rect_.origin + source_rect_.size * coverage_coords) /
129-
texture_size;
130-
vertex_builder.AppendVertex(data);
122+
[this, &vertex_builder, &coverage_rect, &texture_size](
123+
const float* vertices, size_t vertices_size,
124+
const uint16_t* indices, size_t indices_size) {
125+
for (auto i = 0u; i < vertices_size; i++) {
126+
VS::PerVertexData data;
127+
Point vtx = {vertices[i], vertices[i + 1]};
128+
data.position = vtx;
129+
auto coverage_coords =
130+
(vtx - coverage_rect->origin) / coverage_rect->size;
131+
data.texture_coords =
132+
(source_rect_.origin + source_rect_.size * coverage_coords) /
133+
texture_size;
134+
vertex_builder.AppendVertex(data);
135+
}
136+
for (auto i = 0u; i < indices_size; i++) {
137+
vertex_builder.AppendIndex(indices[i]);
138+
}
139+
return true;
131140
});
132141

133142
if (tess_result == Tessellator::Result::kInputError) {

impeller/entity/geometry.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ GeometryResult PathGeometry::GetPositionBuffer(
184184
std::shared_ptr<Tessellator> tessellator,
185185
ISize render_target_size) {
186186
VertexBuffer vertex_buffer;
187-
auto tesselation_result = tessellator->TessellateBuilder(
187+
auto tesselation_result = tessellator->Tessellate(
188188
path_.GetFillType(), path_.CreatePolyline(),
189189
[&vertex_buffer, &host_buffer](
190190
const float* vertices, size_t vertices_count, const uint16_t* indices,

impeller/geometry/geometry_benchmarks.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,10 @@ static void BM_Polyline(benchmark::State& state, Args&&... args) {
3333
single_point_count = polyline.points.size();
3434
point_count += single_point_count;
3535
if (tessellate) {
36-
tess.Tessellate(FillType::kNonZero, polyline, [](Point) {});
36+
tess.Tessellate(
37+
FillType::kNonZero, polyline,
38+
[](const float* vertices, size_t vertices_size,
39+
const uint16_t* indices, size_t indices_size) { return true; });
3740
}
3841
}
3942
state.counters["SinglePointCount"] = single_point_count;

impeller/renderer/renderer_unittests.cc

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -397,18 +397,25 @@ TEST_P(RendererTest, CanRenderInstanced) {
397397

398398
VertexBufferBuilder<VS::PerVertexData> builder;
399399

400-
ASSERT_EQ(
401-
Tessellator::Result::kSuccess,
402-
Tessellator{}.Tessellate(FillType::kPositive,
403-
PathBuilder{}
404-
.AddRect(Rect::MakeXYWH(10, 10, 100, 100))
405-
.TakePath()
406-
.CreatePolyline(),
407-
[&builder](Point vtx) {
408-
VS::PerVertexData data;
409-
data.vtx = vtx;
410-
builder.AppendVertex(data);
411-
}));
400+
ASSERT_EQ(Tessellator::Result::kSuccess,
401+
Tessellator{}.Tessellate(
402+
FillType::kPositive,
403+
PathBuilder{}
404+
.AddRect(Rect::MakeXYWH(10, 10, 100, 100))
405+
.TakePath()
406+
.CreatePolyline(),
407+
[&builder](const float* vertices, size_t vertices_size,
408+
const uint16_t* indices, size_t indices_size) {
409+
for (auto i = 0u; i < vertices_size; i += 2) {
410+
VS::PerVertexData data;
411+
data.vtx = {vertices[i], vertices[i + 1]};
412+
builder.AppendVertex(data);
413+
}
414+
for (auto i = 0u; i < indices_size; i++) {
415+
builder.AppendIndex(indices[i]);
416+
}
417+
return true;
418+
}));
412419

413420
ASSERT_NE(GetContext(), nullptr);
414421
auto pipeline =

impeller/tessellator/c/tessellator.cc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,22 @@ struct Vertices* Tessellate(PathBuilder* builder,
4646
auto smoothing = SmoothingApproximation(scale, angle_tolerance, cusp_limit);
4747
auto polyline = path.CreatePolyline(smoothing);
4848
std::vector<float> points;
49-
if (Tessellator{}.Tessellate(path.GetFillType(), polyline,
50-
[&points](Point vertex) {
51-
points.push_back(vertex.x);
52-
points.push_back(vertex.y);
53-
}) != Tessellator::Result::kSuccess) {
49+
if (Tessellator{}.Tessellate(
50+
path.GetFillType(), polyline,
51+
[&points](const float* vertices, size_t vertices_size,
52+
const uint16_t* indices, size_t indices_size) {
53+
// Results are expected to be re-duplicated.
54+
std::vector<Point> raw_points;
55+
for (auto i = 0u; i < vertices_size; i += 2) {
56+
raw_points.emplace_back(Point{vertices[i], vertices[i + 1]});
57+
}
58+
for (auto i = 0u; i < indices_size; i++) {
59+
auto point = raw_points[indices[i]];
60+
points.push_back(point.x);
61+
points.push_back(point.y);
62+
}
63+
return true;
64+
}) != Tessellator::Result::kSuccess) {
5465
return nullptr;
5566
}
5667

impeller/tessellator/tessellator.cc

Lines changed: 0 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -53,82 +53,6 @@ static int ToTessWindingRule(FillType fill_type) {
5353
}
5454

5555
Tessellator::Result Tessellator::Tessellate(
56-
FillType fill_type,
57-
const Path::Polyline& polyline,
58-
const VertexCallback& callback) const {
59-
if (!callback) {
60-
return Result::kInputError;
61-
}
62-
63-
if (polyline.points.empty()) {
64-
return Result::kInputError;
65-
}
66-
67-
auto tessellator = c_tessellator_.get();
68-
if (!tessellator) {
69-
return Result::kTessellationError;
70-
}
71-
72-
constexpr int kVertexSize = 2;
73-
constexpr int kPolygonSize = 3;
74-
75-
//----------------------------------------------------------------------------
76-
/// Feed contour information to the tessellator.
77-
///
78-
static_assert(sizeof(Point) == 2 * sizeof(float));
79-
for (size_t contour_i = 0; contour_i < polyline.contours.size();
80-
contour_i++) {
81-
size_t start_point_index, end_point_index;
82-
std::tie(start_point_index, end_point_index) =
83-
polyline.GetContourPointBounds(contour_i);
84-
85-
::tessAddContour(tessellator, // the C tessellator
86-
kVertexSize, //
87-
polyline.points.data() + start_point_index, //
88-
sizeof(Point), //
89-
end_point_index - start_point_index //
90-
);
91-
}
92-
93-
//----------------------------------------------------------------------------
94-
/// Let's tessellate.
95-
///
96-
auto result = ::tessTesselate(tessellator, // tessellator
97-
ToTessWindingRule(fill_type), // winding
98-
TESS_POLYGONS, // element type
99-
kPolygonSize, // polygon size
100-
kVertexSize, // vertex size
101-
nullptr // normal (null is automatic)
102-
);
103-
104-
if (result != 1) {
105-
return Result::kTessellationError;
106-
}
107-
108-
// TODO(csg): This copy can be elided entirely for the current use case.
109-
std::vector<Point> points;
110-
std::vector<uint32_t> indices;
111-
112-
int vertexItemCount = tessGetVertexCount(tessellator) * kVertexSize;
113-
auto vertices = tessGetVertices(tessellator);
114-
for (int i = 0; i < vertexItemCount; i += 2) {
115-
points.emplace_back(vertices[i], vertices[i + 1]);
116-
}
117-
118-
int elementItemCount = tessGetElementCount(tessellator) * kPolygonSize;
119-
auto elements = tessGetElements(tessellator);
120-
for (int i = 0; i < elementItemCount; i++) {
121-
indices.emplace_back(elements[i]);
122-
}
123-
124-
for (auto index : indices) {
125-
auto vtx = points[index];
126-
callback(vtx);
127-
}
128-
return Result::kSuccess;
129-
}
130-
131-
Tessellator::Result Tessellator::TessellateBuilder(
13256
FillType fill_type,
13357
const Path::Polyline& polyline,
13458
const BuilderCallback& callback) const {

impeller/tessellator/tessellator.h

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,26 +43,11 @@ class Tessellator {
4343

4444
~Tessellator();
4545

46-
using VertexCallback = std::function<void(Point)>;
4746
using BuilderCallback = std::function<bool(const float* vertices,
4847
size_t vertices_size,
4948
const uint16_t* indices,
5049
size_t indices_size)>;
5150

52-
//----------------------------------------------------------------------------
53-
/// @brief Generates filled triangles from the polyline. A callback is
54-
/// invoked for each vertex of the triangle.
55-
///
56-
/// @param[in] fill_type The fill rule to use when filling.
57-
/// @param[in] polyline The polyline
58-
/// @param[in] callback The callback
59-
///
60-
/// @return The result status of the tessellation.
61-
///
62-
Tessellator::Result Tessellate(FillType fill_type,
63-
const Path::Polyline& polyline,
64-
const VertexCallback& callback) const;
65-
6651
//----------------------------------------------------------------------------
6752
/// @brief Generates filled triangles from the polyline. A callback is
6853
/// invoked once for the entire tessellation.
@@ -73,9 +58,9 @@ class Tessellator {
7358
///
7459
/// @return The result status of the tessellation.
7560
///
76-
Tessellator::Result TessellateBuilder(FillType fill_type,
77-
const Path::Polyline& polyline,
78-
const BuilderCallback& callback) const;
61+
Tessellator::Result Tessellate(FillType fill_type,
62+
const Path::Polyline& polyline,
63+
const BuilderCallback& callback) const;
7964

8065
private:
8166
CTessellator c_tessellator_;

impeller/tessellator/tessellator_unittests.cc

Lines changed: 5 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -10,64 +10,12 @@
1010
namespace impeller {
1111
namespace testing {
1212

13-
TEST(TessellatorTest, TessellatorReturnsCorrectResultStatus) {
14-
// Zero points.
15-
{
16-
Tessellator t;
17-
auto polyline = PathBuilder{}.TakePath().CreatePolyline();
18-
Tessellator::Result result =
19-
t.Tessellate(FillType::kPositive, polyline, [](Point point) {});
20-
21-
ASSERT_EQ(polyline.points.size(), 0u);
22-
ASSERT_EQ(result, Tessellator::Result::kInputError);
23-
}
24-
25-
// One point.
26-
{
27-
Tessellator t;
28-
auto polyline = PathBuilder{}.LineTo({0, 0}).TakePath().CreatePolyline();
29-
Tessellator::Result result =
30-
t.Tessellate(FillType::kPositive, polyline, [](Point point) {});
31-
32-
ASSERT_EQ(polyline.points.size(), 1u);
33-
ASSERT_EQ(result, Tessellator::Result::kSuccess);
34-
}
35-
36-
// Two points.
37-
{
38-
Tessellator t;
39-
auto polyline =
40-
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline();
41-
Tessellator::Result result =
42-
t.Tessellate(FillType::kPositive, polyline, [](Point point) {});
43-
44-
ASSERT_EQ(polyline.points.size(), 2u);
45-
ASSERT_EQ(result, Tessellator::Result::kSuccess);
46-
}
47-
48-
// Many points.
49-
{
50-
Tessellator t;
51-
PathBuilder builder;
52-
for (int i = 0; i < 1000; i++) {
53-
auto coord = i * 1.0f;
54-
builder.AddLine({coord, coord}, {coord + 1, coord + 1});
55-
}
56-
auto polyline = builder.TakePath().CreatePolyline();
57-
Tessellator::Result result =
58-
t.Tessellate(FillType::kPositive, polyline, [](Point point) {});
59-
60-
ASSERT_EQ(polyline.points.size(), 2000u);
61-
ASSERT_EQ(result, Tessellator::Result::kSuccess);
62-
}
63-
}
64-
6513
TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
6614
// Zero points.
6715
{
6816
Tessellator t;
6917
auto polyline = PathBuilder{}.TakePath().CreatePolyline();
70-
Tessellator::Result result = t.TessellateBuilder(
18+
Tessellator::Result result = t.Tessellate(
7119
FillType::kPositive, polyline,
7220
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
7321
size_t indices_size) { return true; });
@@ -80,7 +28,7 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
8028
{
8129
Tessellator t;
8230
auto polyline = PathBuilder{}.LineTo({0, 0}).TakePath().CreatePolyline();
83-
Tessellator::Result result = t.TessellateBuilder(
31+
Tessellator::Result result = t.Tessellate(
8432
FillType::kPositive, polyline,
8533
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
8634
size_t indices_size) { return true; });
@@ -93,7 +41,7 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
9341
Tessellator t;
9442
auto polyline =
9543
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline();
96-
Tessellator::Result result = t.TessellateBuilder(
44+
Tessellator::Result result = t.Tessellate(
9745
FillType::kPositive, polyline,
9846
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
9947
size_t indices_size) { return true; });
@@ -111,7 +59,7 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
11159
builder.AddLine({coord, coord}, {coord + 1, coord + 1});
11260
}
11361
auto polyline = builder.TakePath().CreatePolyline();
114-
Tessellator::Result result = t.TessellateBuilder(
62+
Tessellator::Result result = t.Tessellate(
11563
FillType::kPositive, polyline,
11664
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
11765
size_t indices_size) { return true; });
@@ -125,7 +73,7 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
12573
Tessellator t;
12674
auto polyline =
12775
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline();
128-
Tessellator::Result result = t.TessellateBuilder(
76+
Tessellator::Result result = t.Tessellate(
12977
FillType::kPositive, polyline,
13078
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
13179
size_t indices_size) { return false; });

0 commit comments

Comments
 (0)