Skip to content

Commit eb13bc2

Browse files
Jonah Williamsharryterkelsen
authored andcommitted
[Impeller] revert non-zero tessellation optimization. (flutter#48234)
Forgot about the winding order. partially reverts flutter#46282 See flutter/flutter#138598 Reopens flutter/flutter#135458
1 parent cc43161 commit eb13bc2

3 files changed

Lines changed: 66 additions & 152 deletions

File tree

impeller/tessellator/tessellator.cc

Lines changed: 66 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -89,142 +89,81 @@ Tessellator::Result Tessellator::Tessellate(const Path& path,
8989
constexpr int kVertexSize = 2;
9090
constexpr int kPolygonSize = 3;
9191

92-
// If we have a larger polyline and the fill type is non-zero, we can split
93-
// the tessellation up per contour. Since in general the complexity is at
94-
// least nlog(n), this speeds up the processes substantially.
95-
if (polyline.contours.size() > kMultiContourThreshold &&
96-
fill_type == FillType::kNonZero) {
97-
std::vector<Point> points;
98-
std::vector<float> data;
92+
//----------------------------------------------------------------------------
93+
/// Feed contour information to the tessellator.
94+
///
95+
static_assert(sizeof(Point) == 2 * sizeof(float));
96+
for (size_t contour_i = 0; contour_i < polyline.contours.size();
97+
contour_i++) {
98+
size_t start_point_index, end_point_index;
99+
std::tie(start_point_index, end_point_index) =
100+
polyline.GetContourPointBounds(contour_i);
101+
102+
::tessAddContour(tessellator, // the C tessellator
103+
kVertexSize, //
104+
polyline.points->data() + start_point_index, //
105+
sizeof(Point), //
106+
end_point_index - start_point_index //
107+
);
108+
}
99109

100-
//----------------------------------------------------------------------------
101-
/// Feed contour information to the tessellator.
102-
///
103-
size_t total = 0u;
104-
static_assert(sizeof(Point) == 2 * sizeof(float));
105-
for (size_t contour_i = 0; contour_i < polyline.contours.size();
106-
contour_i++) {
107-
size_t start_point_index, end_point_index;
108-
std::tie(start_point_index, end_point_index) =
109-
polyline.GetContourPointBounds(contour_i);
110-
111-
::tessAddContour(tessellator, // the C tessellator
112-
kVertexSize, //
113-
polyline.points->data() + start_point_index, //
114-
sizeof(Point), //
115-
end_point_index - start_point_index //
116-
);
117-
118-
//----------------------------------------------------------------------------
119-
/// Let's tessellate.
120-
///
121-
auto result = ::tessTesselate(tessellator, // tessellator
122-
ToTessWindingRule(fill_type), // winding
123-
TESS_POLYGONS, // element type
124-
kPolygonSize, // polygon size
125-
kVertexSize, // vertex size
126-
nullptr // normal (null is automatic)
127-
);
128-
129-
if (result != 1) {
130-
return Result::kTessellationError;
131-
}
132-
133-
int vertex_item_count = tessGetVertexCount(tessellator) * kVertexSize;
134-
auto vertices = tessGetVertices(tessellator);
135-
for (int i = 0; i < vertex_item_count; i += 2) {
136-
points.emplace_back(vertices[i], vertices[i + 1]);
137-
}
138-
139-
int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
140-
auto elements = tessGetElements(tessellator);
141-
total += element_item_count;
142-
for (int i = 0; i < element_item_count; i++) {
143-
data.emplace_back(points[elements[i]].x);
144-
data.emplace_back(points[elements[i]].y);
145-
}
146-
points.clear();
110+
//----------------------------------------------------------------------------
111+
/// Let's tessellate.
112+
///
113+
auto result = ::tessTesselate(tessellator, // tessellator
114+
ToTessWindingRule(fill_type), // winding
115+
TESS_POLYGONS, // element type
116+
kPolygonSize, // polygon size
117+
kVertexSize, // vertex size
118+
nullptr // normal (null is automatic)
119+
);
120+
121+
if (result != 1) {
122+
return Result::kTessellationError;
123+
}
124+
125+
int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
126+
127+
// We default to using a 16bit index buffer, but in cases where we generate
128+
// more tessellated data than this can contain we need to fall back to
129+
// dropping the index buffer entirely. Instead code could instead switch to
130+
// a uint32 index buffer, but this is done for simplicity with the other
131+
// fast path above.
132+
if (element_item_count < USHRT_MAX) {
133+
int vertex_item_count = tessGetVertexCount(tessellator);
134+
auto vertices = tessGetVertices(tessellator);
135+
auto elements = tessGetElements(tessellator);
136+
137+
// libtess uses an int index internally due to usage of -1 as a sentinel
138+
// value.
139+
std::vector<uint16_t> indices(element_item_count);
140+
for (int i = 0; i < element_item_count; i++) {
141+
indices[i] = static_cast<uint16_t>(elements[i]);
147142
}
148-
if (!callback(data.data(), total, nullptr, 0u)) {
143+
if (!callback(vertices, vertex_item_count, indices.data(),
144+
element_item_count)) {
149145
return Result::kInputError;
150146
}
151147
} else {
152-
//----------------------------------------------------------------------------
153-
/// Feed contour information to the tessellator.
154-
///
155-
static_assert(sizeof(Point) == 2 * sizeof(float));
156-
for (size_t contour_i = 0; contour_i < polyline.contours.size();
157-
contour_i++) {
158-
size_t start_point_index, end_point_index;
159-
std::tie(start_point_index, end_point_index) =
160-
polyline.GetContourPointBounds(contour_i);
161-
162-
::tessAddContour(tessellator, // the C tessellator
163-
kVertexSize, //
164-
polyline.points->data() + start_point_index, //
165-
sizeof(Point), //
166-
end_point_index - start_point_index //
167-
);
168-
}
169-
170-
//----------------------------------------------------------------------------
171-
/// Let's tessellate.
172-
///
173-
auto result = ::tessTesselate(tessellator, // tessellator
174-
ToTessWindingRule(fill_type), // winding
175-
TESS_POLYGONS, // element type
176-
kPolygonSize, // polygon size
177-
kVertexSize, // vertex size
178-
nullptr // normal (null is automatic)
179-
);
148+
std::vector<Point> points;
149+
std::vector<float> data;
180150

181-
if (result != 1) {
182-
return Result::kTessellationError;
151+
int vertex_item_count = tessGetVertexCount(tessellator) * kVertexSize;
152+
auto vertices = tessGetVertices(tessellator);
153+
points.reserve(vertex_item_count);
154+
for (int i = 0; i < vertex_item_count; i += 2) {
155+
points.emplace_back(vertices[i], vertices[i + 1]);
183156
}
184157

185158
int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
186-
187-
// We default to using a 16bit index buffer, but in cases where we generate
188-
// more tessellated data than this can contain we need to fall back to
189-
// dropping the index buffer entirely. Instead code could instead switch to
190-
// a uint32 index buffer, but this is done for simplicity with the other
191-
// fast path above.
192-
if (element_item_count < USHRT_MAX) {
193-
int vertex_item_count = tessGetVertexCount(tessellator);
194-
auto vertices = tessGetVertices(tessellator);
195-
auto elements = tessGetElements(tessellator);
196-
197-
// libtess uses an int index internally due to usage of -1 as a sentinel
198-
// value.
199-
std::vector<uint16_t> indices(element_item_count);
200-
for (int i = 0; i < element_item_count; i++) {
201-
indices[i] = static_cast<uint16_t>(elements[i]);
202-
}
203-
if (!callback(vertices, vertex_item_count, indices.data(),
204-
element_item_count)) {
205-
return Result::kInputError;
206-
}
207-
} else {
208-
std::vector<Point> points;
209-
std::vector<float> data;
210-
211-
int vertex_item_count = tessGetVertexCount(tessellator) * kVertexSize;
212-
auto vertices = tessGetVertices(tessellator);
213-
points.reserve(vertex_item_count);
214-
for (int i = 0; i < vertex_item_count; i += 2) {
215-
points.emplace_back(vertices[i], vertices[i + 1]);
216-
}
217-
218-
int element_item_count = tessGetElementCount(tessellator) * kPolygonSize;
219-
auto elements = tessGetElements(tessellator);
220-
data.reserve(element_item_count);
221-
for (int i = 0; i < element_item_count; i++) {
222-
data.emplace_back(points[elements[i]].x);
223-
data.emplace_back(points[elements[i]].y);
224-
}
225-
if (!callback(data.data(), element_item_count, nullptr, 0u)) {
226-
return Result::kInputError;
227-
}
159+
auto elements = tessGetElements(tessellator);
160+
data.reserve(element_item_count);
161+
for (int i = 0; i < element_item_count; i++) {
162+
data.emplace_back(points[elements[i]].x);
163+
data.emplace_back(points[elements[i]].y);
164+
}
165+
if (!callback(data.data(), element_item_count, nullptr, 0u)) {
166+
return Result::kInputError;
228167
}
229168
}
230169

impeller/tessellator/tessellator.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ class Tessellator {
4545

4646
~Tessellator();
4747

48-
/// @brief An arbitrary value to determine when a multi-contour non-zero fill
49-
/// path should be split into multiple tessellations.
50-
static constexpr size_t kMultiContourThreshold = 30u;
51-
5248
/// @brief A callback that returns the results of the tessellation.
5349
///
5450
/// The index buffer may not be populated, in which case [indices] will

impeller/tessellator/tessellator_unittests.cc

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,27 +79,6 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
7979
ASSERT_EQ(result, Tessellator::Result::kInputError);
8080
}
8181

82-
// More than 30 contours, non-zero fill mode.
83-
{
84-
Tessellator t;
85-
PathBuilder builder = {};
86-
for (auto i = 0u; i < Tessellator::kMultiContourThreshold + 1; i++) {
87-
builder.AddCircle(Point(i, i), 4);
88-
}
89-
auto path = builder.TakePath(FillType::kNonZero);
90-
bool no_indices = false;
91-
Tessellator::Result result = t.Tessellate(
92-
path, 1.0f,
93-
[&no_indices](const float* vertices, size_t vertices_count,
94-
const uint16_t* indices, size_t indices_count) {
95-
no_indices = indices == nullptr;
96-
return true;
97-
});
98-
99-
ASSERT_TRUE(no_indices);
100-
ASSERT_EQ(result, Tessellator::Result::kSuccess);
101-
}
102-
10382
// More than uint16 points, odd fill mode.
10483
{
10584
Tessellator t;

0 commit comments

Comments
 (0)