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

Commit ae5231b

Browse files
authored
[Impeller] Change Path::CreatePolyline from tolerance to scale, and make it required (#39917)
[Impeller] Change Path::CreatePolyline from tolerance to scale, and make it required
1 parent 3d82bdc commit ae5231b

File tree

9 files changed

+47
-48
lines changed

9 files changed

+47
-48
lines changed

impeller/entity/contents/texture_contents.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ bool TextureContents::Render(const ContentContext& renderer,
123123
VertexBufferBuilder<VS::PerVertexData> vertex_builder;
124124
{
125125
const auto tess_result = renderer.GetTessellator()->Tessellate(
126-
path_.GetFillType(), path_.CreatePolyline(),
126+
path_.GetFillType(), path_.CreatePolyline(1.0f),
127127
[this, &vertex_builder, &coverage_rect, &texture_size](
128128
const float* vertices, size_t vertices_size,
129129
const uint16_t* indices, size_t indices_size) {

impeller/entity/geometry.cc

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,11 @@ GeometryResult FillPathGeometry::GetPositionBuffer(
5353
const ContentContext& renderer,
5454
const Entity& entity,
5555
RenderPass& pass) {
56-
auto tolerance =
57-
kDefaultCurveTolerance / entity.GetTransformation().GetMaxBasisLength();
58-
5956
VertexBuffer vertex_buffer;
6057
auto& host_buffer = pass.GetTransientsBuffer();
6158
auto tesselation_result = renderer.GetTessellator()->Tessellate(
62-
path_.GetFillType(), path_.CreatePolyline(tolerance),
59+
path_.GetFillType(),
60+
path_.CreatePolyline(entity.GetTransformation().GetMaxBasisLength()),
6361
[&vertex_buffer, &host_buffer](
6462
const float* vertices, size_t vertices_count, const uint16_t* indices,
6563
size_t indices_count) {
@@ -151,7 +149,7 @@ StrokePathGeometry::JoinProc StrokePathGeometry::GetJoinProc(Join stroke_join) {
151149
join_proc = [](VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
152150
const Point& position, const Point& start_offset,
153151
const Point& end_offset, Scalar miter_limit,
154-
Scalar tolerance) {
152+
Scalar scale) {
155153
CreateBevelAndGetDirection(vtx_builder, position, start_offset,
156154
end_offset);
157155
};
@@ -160,7 +158,7 @@ StrokePathGeometry::JoinProc StrokePathGeometry::GetJoinProc(Join stroke_join) {
160158
join_proc = [](VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
161159
const Point& position, const Point& start_offset,
162160
const Point& end_offset, Scalar miter_limit,
163-
Scalar tolerance) {
161+
Scalar scale) {
164162
Point start_normal = start_offset.Normalize();
165163
Point end_normal = end_offset.Normalize();
166164

@@ -189,7 +187,7 @@ StrokePathGeometry::JoinProc StrokePathGeometry::GetJoinProc(Join stroke_join) {
189187
join_proc = [](VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
190188
const Point& position, const Point& start_offset,
191189
const Point& end_offset, Scalar miter_limit,
192-
Scalar tolerance) {
190+
Scalar scale) {
193191
Point start_normal = start_offset.Normalize();
194192
Point end_normal = end_offset.Normalize();
195193

@@ -216,7 +214,7 @@ StrokePathGeometry::JoinProc StrokePathGeometry::GetJoinProc(Join stroke_join) {
216214

217215
auto arc_points = CubicPathComponent(start_offset, start_handle,
218216
middle_handle, middle)
219-
.CreatePolyline(tolerance);
217+
.CreatePolyline(scale);
220218

221219
VS::PerVertexData vtx;
222220
for (const auto& point : arc_points) {
@@ -238,8 +236,7 @@ StrokePathGeometry::CapProc StrokePathGeometry::GetCapProc(Cap stroke_cap) {
238236
switch (stroke_cap) {
239237
case Cap::kButt:
240238
cap_proc = [](VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
241-
const Point& position, const Point& offset,
242-
Scalar tolerance) {
239+
const Point& position, const Point& offset, Scalar scale) {
243240
VS::PerVertexData vtx;
244241
vtx.position = position + offset;
245242
vtx_builder.AppendVertex(vtx);
@@ -249,8 +246,7 @@ StrokePathGeometry::CapProc StrokePathGeometry::GetCapProc(Cap stroke_cap) {
249246
break;
250247
case Cap::kRound:
251248
cap_proc = [](VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
252-
const Point& position, const Point& offset,
253-
Scalar tolerance) {
249+
const Point& position, const Point& offset, Scalar scale) {
254250
VS::PerVertexData vtx;
255251

256252
Point forward(offset.y, -offset.x);
@@ -260,7 +256,7 @@ StrokePathGeometry::CapProc StrokePathGeometry::GetCapProc(Cap stroke_cap) {
260256
CubicPathComponent(
261257
offset, offset + forward * PathBuilder::kArcApproximationMagic,
262258
forward + offset * PathBuilder::kArcApproximationMagic, forward)
263-
.CreatePolyline(tolerance);
259+
.CreatePolyline(scale);
264260

265261
vtx.position = position + offset;
266262
vtx_builder.AppendVertex(vtx);
@@ -276,8 +272,7 @@ StrokePathGeometry::CapProc StrokePathGeometry::GetCapProc(Cap stroke_cap) {
276272
break;
277273
case Cap::kSquare:
278274
cap_proc = [](VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
279-
const Point& position, const Point& offset,
280-
Scalar tolerance) {
275+
const Point& position, const Point& offset, Scalar scale) {
281276
VS::PerVertexData vtx;
282277

283278
Point forward(offset.y, -offset.x);
@@ -305,9 +300,9 @@ VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
305300
Cap cap,
306301
const StrokePathGeometry::JoinProc& join_proc,
307302
const StrokePathGeometry::CapProc& cap_proc,
308-
Scalar tolerance) {
303+
Scalar scale) {
309304
VertexBufferBuilder<VS::PerVertexData> vtx_builder;
310-
auto polyline = path.CreatePolyline();
305+
auto polyline = path.CreatePolyline(scale);
311306

312307
VS::PerVertexData vtx;
313308

@@ -333,8 +328,8 @@ VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
333328
switch (contour_end_point_i - contour_start_point_i) {
334329
case 1: {
335330
Point p = polyline.points[contour_start_point_i];
336-
cap_proc(vtx_builder, p, {-stroke_width * 0.5f, 0}, tolerance);
337-
cap_proc(vtx_builder, p, {stroke_width * 0.5f, 0}, tolerance);
331+
cap_proc(vtx_builder, p, {-stroke_width * 0.5f, 0}, scale);
332+
cap_proc(vtx_builder, p, {stroke_width * 0.5f, 0}, scale);
338333
continue;
339334
}
340335
case 0:
@@ -381,7 +376,7 @@ VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
381376
}
382377
auto cap_offset = direction * stroke_width * 0.5;
383378
cap_proc(vtx_builder, polyline.points[contour_start_point_i], cap_offset,
384-
tolerance);
379+
scale);
385380
}
386381

387382
// Generate contour geometry.
@@ -402,7 +397,7 @@ VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
402397

403398
// Generate join from the current line to the next line.
404399
join_proc(vtx_builder, polyline.points[point_i], previous_offset,
405-
offset, scaled_miter_limit, tolerance);
400+
offset, scaled_miter_limit, scale);
406401
}
407402
}
408403

@@ -412,10 +407,10 @@ VertexBuffer StrokePathGeometry::CreateSolidStrokeVertices(
412407
Vector2(-contour.end_direction.y, contour.end_direction.x) *
413408
stroke_width * 0.5;
414409
cap_proc(vtx_builder, polyline.points[contour_end_point_i - 1],
415-
cap_offset, tolerance);
410+
cap_offset, scale);
416411
} else {
417412
join_proc(vtx_builder, polyline.points[contour_start_point_i], offset,
418-
contour_first_offset, scaled_miter_limit, tolerance);
413+
contour_first_offset, scaled_miter_limit, scale);
419414
}
420415
}
421416

@@ -437,15 +432,11 @@ GeometryResult StrokePathGeometry::GetPositionBuffer(
437432
Scalar min_size = 1.0f / sqrt(std::abs(determinant));
438433
Scalar stroke_width = std::max(stroke_width_, min_size);
439434

440-
auto tolerance =
441-
kDefaultCurveTolerance /
442-
(stroke_width_ * entity.GetTransformation().GetMaxBasisLength());
443-
444435
auto& host_buffer = pass.GetTransientsBuffer();
445436
auto vertex_buffer = CreateSolidStrokeVertices(
446437
path_, host_buffer, stroke_width, miter_limit_ * stroke_width_ * 0.5,
447438
stroke_cap_, GetJoinProc(stroke_join_), GetCapProc(stroke_cap_),
448-
tolerance);
439+
entity.GetTransformation().GetMaxBasisLength());
449440

450441
return GeometryResult{
451442
.type = PrimitiveType::kTriangleStrip,

impeller/entity/geometry.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,14 +134,14 @@ class StrokePathGeometry : public Geometry {
134134
std::function<void(VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
135135
const Point& position,
136136
const Point& offset,
137-
Scalar tolerance)>;
137+
Scalar scale)>;
138138
using JoinProc =
139139
std::function<void(VertexBufferBuilder<VS::PerVertexData>& vtx_builder,
140140
const Point& position,
141141
const Point& start_offset,
142142
const Point& end_offset,
143143
Scalar miter_limit,
144-
Scalar tolerance)>;
144+
Scalar scale)>;
145145

146146
// |Geometry|
147147
GeometryResult GetPositionBuffer(const ContentContext& renderer,
@@ -167,7 +167,7 @@ class StrokePathGeometry : public Geometry {
167167
Cap cap,
168168
const JoinProc& join_proc,
169169
const CapProc& cap_proc,
170-
Scalar tolerance);
170+
Scalar scale);
171171

172172
static StrokePathGeometry::JoinProc GetJoinProc(Join stroke_join);
173173

impeller/geometry/geometry_benchmarks.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ static void BM_Polyline(benchmark::State& state, Args&&... args) {
2929
size_t point_count = 0u;
3030
size_t single_point_count = 0u;
3131
while (state.KeepRunning()) {
32-
auto polyline = path.CreatePolyline();
32+
auto polyline = path.CreatePolyline(1.0f);
3333
single_point_count = polyline.points.size();
3434
point_count += single_point_count;
3535
if (tessellate) {

impeller/geometry/geometry_unittests.cc

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "impeller/geometry/rect.h"
1818
#include "impeller/geometry/scalar.h"
1919
#include "impeller/geometry/size.h"
20-
#include "path_component.h"
2120

2221
namespace impeller {
2322
namespace testing {
@@ -577,7 +576,7 @@ TEST(GeometryTest, EmptyPath) {
577576
path.GetContourComponentAtIndex(0, c);
578577
ASSERT_POINT_NEAR(c.destination, Point());
579578

580-
Path::Polyline polyline = path.CreatePolyline();
579+
Path::Polyline polyline = path.CreatePolyline(1.0f);
581580
ASSERT_TRUE(polyline.points.empty());
582581
ASSERT_TRUE(polyline.contours.empty());
583582
}
@@ -1596,7 +1595,7 @@ TEST(GeometryTest, PathCreatePolyLineDoesNotDuplicatePoints) {
15961595
path.AddContourComponent({40, 40});
15971596
path.AddLinearComponent({40, 40}, {50, 50});
15981597

1599-
auto polyline = path.CreatePolyline();
1598+
auto polyline = path.CreatePolyline(1.0f);
16001599

16011600
ASSERT_EQ(polyline.contours.size(), 2u);
16021601
ASSERT_EQ(polyline.points.size(), 5u);
@@ -1682,7 +1681,7 @@ TEST(GeometryTest, PathCreatePolylineGeneratesCorrectContourData) {
16821681
.LineTo({200, 200})
16831682
.Close()
16841683
.TakePath()
1685-
.CreatePolyline();
1684+
.CreatePolyline(1.0f);
16861685
ASSERT_EQ(polyline.points.size(), 6u);
16871686
ASSERT_EQ(polyline.contours.size(), 2u);
16881687
ASSERT_EQ(polyline.contours[0].is_closed, false);
@@ -1699,7 +1698,7 @@ TEST(GeometryTest, PolylineGetContourPointBoundsReturnsCorrectRanges) {
16991698
.LineTo({200, 200})
17001699
.Close()
17011700
.TakePath()
1702-
.CreatePolyline();
1701+
.CreatePolyline(1.0f);
17031702
size_t a1, a2, b1, b2;
17041703
std::tie(a1, a2) = polyline.GetContourPointBounds(0);
17051704
std::tie(b1, b2) = polyline.GetContourPointBounds(1);
@@ -1713,7 +1712,7 @@ TEST(GeometryTest, PathAddRectPolylineHasCorrectContourData) {
17131712
Path::Polyline polyline = PathBuilder{}
17141713
.AddRect(Rect::MakeLTRB(50, 60, 70, 80))
17151714
.TakePath()
1716-
.CreatePolyline();
1715+
.CreatePolyline(1.0f);
17171716
ASSERT_EQ(polyline.contours.size(), 1u);
17181717
ASSERT_TRUE(polyline.contours[0].is_closed);
17191718
ASSERT_EQ(polyline.contours[0].start_index, 0u);
@@ -1738,7 +1737,7 @@ TEST(GeometryTest, PathPolylineDuplicatesAreRemovedForSameContour) {
17381737
.LineTo({0, 100})
17391738
.LineTo({0, 100}) // Insert duplicate at end of contour.
17401739
.TakePath()
1741-
.CreatePolyline();
1740+
.CreatePolyline(1.0f);
17421741
ASSERT_EQ(polyline.contours.size(), 2u);
17431742
ASSERT_EQ(polyline.contours[0].start_index, 0u);
17441743
ASSERT_TRUE(polyline.contours[0].is_closed);

impeller/geometry/path.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <optional>
88

99
#include "impeller/geometry/path_component.h"
10+
#include "path_component.h"
1011

1112
namespace impeller {
1213

@@ -221,8 +222,9 @@ bool Path::UpdateContourComponentAtIndex(size_t index,
221222
return true;
222223
}
223224

224-
Path::Polyline Path::CreatePolyline(Scalar tolerance) const {
225+
Path::Polyline Path::CreatePolyline(Scalar scale) const {
225226
Polyline polyline;
227+
auto tolerance = kDefaultCurveTolerance / scale;
226228

227229
std::optional<Point> previous_contour_point;
228230
auto collect_points = [&polyline, &previous_contour_point](

impeller/geometry/path.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <vector>
1212

1313
#include "impeller/geometry/path_component.h"
14+
#include "path_component.h"
1415

1516
namespace impeller {
1617

@@ -122,7 +123,12 @@ class Path {
122123
bool UpdateContourComponentAtIndex(size_t index,
123124
const ContourComponent& contour);
124125

125-
Polyline CreatePolyline(Scalar tolerance = kDefaultCurveTolerance) const;
126+
/// Callers must provide the scale factor for how this path will be
127+
/// transformed.
128+
///
129+
/// It is suitable to use the max basis length of the matrix used to transform
130+
/// the path. If the provided scale is 0, curves will revert to lines.
131+
Polyline CreatePolyline(Scalar scale) const;
126132

127133
std::optional<Rect> GetBoundingBox() const;
128134

impeller/renderer/renderer_unittests.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ TEST_P(RendererTest, CanRenderInstanced) {
396396
PathBuilder{}
397397
.AddRect(Rect::MakeXYWH(10, 10, 100, 100))
398398
.TakePath()
399-
.CreatePolyline(),
399+
.CreatePolyline(1.0f),
400400
[&builder](const float* vertices, size_t vertices_size,
401401
const uint16_t* indices, size_t indices_size) {
402402
for (auto i = 0u; i < vertices_size; i += 2) {

impeller/tessellator/tessellator_unittests.cc

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
1414
// Zero points.
1515
{
1616
Tessellator t;
17-
auto polyline = PathBuilder{}.TakePath().CreatePolyline();
17+
auto polyline = PathBuilder{}.TakePath().CreatePolyline(1.0f);
1818
Tessellator::Result result = t.Tessellate(
1919
FillType::kPositive, polyline,
2020
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
@@ -27,7 +27,8 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
2727
// One point.
2828
{
2929
Tessellator t;
30-
auto polyline = PathBuilder{}.LineTo({0, 0}).TakePath().CreatePolyline();
30+
auto polyline =
31+
PathBuilder{}.LineTo({0, 0}).TakePath().CreatePolyline(1.0f);
3132
Tessellator::Result result = t.Tessellate(
3233
FillType::kPositive, polyline,
3334
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
@@ -40,7 +41,7 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
4041
{
4142
Tessellator t;
4243
auto polyline =
43-
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline();
44+
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline(1.0f);
4445
Tessellator::Result result = t.Tessellate(
4546
FillType::kPositive, polyline,
4647
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
@@ -58,7 +59,7 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
5859
auto coord = i * 1.0f;
5960
builder.AddLine({coord, coord}, {coord + 1, coord + 1});
6061
}
61-
auto polyline = builder.TakePath().CreatePolyline();
62+
auto polyline = builder.TakePath().CreatePolyline(1.0f);
6263
Tessellator::Result result = t.Tessellate(
6364
FillType::kPositive, polyline,
6465
[](const float* vertices, size_t vertices_size, const uint16_t* indices,
@@ -72,7 +73,7 @@ TEST(TessellatorTest, TessellatorBuilderReturnsCorrectResultStatus) {
7273
{
7374
Tessellator t;
7475
auto polyline =
75-
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline();
76+
PathBuilder{}.AddLine({0, 0}, {0, 1}).TakePath().CreatePolyline(1.0f);
7677
Tessellator::Result result = t.Tessellate(
7778
FillType::kPositive, polyline,
7879
[](const float* vertices, size_t vertices_size, const uint16_t* indices,

0 commit comments

Comments
 (0)