Skip to content

Commit dc78960

Browse files
authored
add Impeller path stroke tessellation benchmark (#166939)
We currently benchmark path tessellation on Android and iOS, but only for filled paths. We will now run those same benchmarks also with stroking in a new set of benchmarks.
1 parent 1f6588f commit dc78960

12 files changed

+316
-21
lines changed

.ci.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2375,6 +2375,29 @@ targets:
23752375
["devicelab", "android", "linux", "pixel", "7pro"]
23762376
task_name: static_path_tessellation_perf__timeline_summary
23772377

2378+
2379+
# Uses Impeller.
2380+
- name: Linux_pixel_7pro dynamic_path_stroke_tessellation_perf__timeline_summary
2381+
recipe: devicelab/devicelab_drone
2382+
presubmit: false
2383+
bringup: true
2384+
timeout: 60
2385+
properties:
2386+
tags: >
2387+
["devicelab", "android", "linux", "pixel", "7pro"]
2388+
task_name: dynamic_path_stroke_tessellation_perf__timeline_summary
2389+
2390+
# Uses Impeller.
2391+
- name: Linux_pixel_7pro static_path_stroke_tessellation_perf__timeline_summary
2392+
recipe: devicelab/devicelab_drone
2393+
presubmit: false
2394+
bringup: true
2395+
timeout: 60
2396+
properties:
2397+
tags: >
2398+
["devicelab", "android", "linux", "pixel", "7pro"]
2399+
task_name: static_path_stroke_tessellation_perf__timeline_summary
2400+
23782401
# Uses Impeller.
23792402
- name: Linux_pixel_7pro hello_world_impeller
23802403
recipe: devicelab/devicelab_drone
@@ -3600,6 +3623,26 @@ targets:
36003623
["devicelab", "ios", "mac"]
36013624
task_name: dynamic_path_tessellation_perf_ios__timeline_summary
36023625

3626+
- name: Mac_ios static_path_stroke_tessellation_perf_ios__timeline_summary
3627+
recipe: devicelab/devicelab_drone
3628+
presubmit: false
3629+
bringup: true
3630+
timeout: 60
3631+
properties:
3632+
tags: >
3633+
["devicelab", "ios", "mac"]
3634+
task_name: static_path_stroke_tessellation_perf_ios__timeline_summary
3635+
3636+
- name: Mac_ios dynamic_path_stroke_tessellation_perf_ios__timeline_summary
3637+
recipe: devicelab/devicelab_drone
3638+
presubmit: false
3639+
bringup: true
3640+
timeout: 60
3641+
properties:
3642+
tags: >
3643+
["devicelab", "ios", "mac"]
3644+
task_name: dynamic_path_stroke_tessellation_perf_ios__timeline_summary
3645+
36033646
- name: Staging_build_linux analyze
36043647
presubmit: false
36053648
bringup: true

TESTOWNERS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@
105105
/dev/devicelab/bin/tasks/draw_atlas_perf__timeline_summary.dart @jonahwilliams @flutter/engine
106106
/dev/devicelab/bin/tasks/static_path_tessellation_perf__timeline_summary.dart @jonahwilliams @flutter/engine
107107
/dev/devicelab/bin/tasks/dynamic_path_tessellation_perf__timeline_summary.dart @jonahwilliams @flutter/engine
108+
/dev/devicelab/bin/tasks/static_path_stroke_tessellation_perf__timeline_summary.dart @flar @flutter/engine
109+
/dev/devicelab/bin/tasks/dynamic_path_stroke_tessellation_perf__timeline_summary.dart @flar @flutter/engine
108110
/dev/devicelab/bin/tasks/complex_layout_scroll_perf_impeller__timeline_summary.dart @jonahwilliams @flutter/engine
109111
/dev/devicelab/bin/tasks/complex_layout_scroll_perf_impeller_gles__timeline_summary.dart @jonahwilliams @flutter/engine
110112
/dev/devicelab/bin/tasks/rrect_blur_perf__timeline_summary.dart @gaaclarke @flutter/engine
@@ -229,6 +231,8 @@
229231
/dev/devicelab/bin/tasks/draw_atlas_perf_ios__timeline_summary.dart @jonahwilliams @flutter/engine
230232
/dev/devicelab/bin/tasks/static_path_tessellation_perf_ios__timeline_summary.dart @jonahwilliams @flutter/engine
231233
/dev/devicelab/bin/tasks/dynamic_path_tessellation_perf_ios__timeline_summary.dart @jonahwilliams @flutter/engine
234+
/dev/devicelab/bin/tasks/static_path_stroke_tessellation_perf_ios__timeline_summary.dart @flar @flutter/engine
235+
/dev/devicelab/bin/tasks/dynamic_path_stroke_tessellation_perf_ios__timeline_summary.dart @flar @flutter/engine
232236
/dev/devicelab/bin/tasks/rrect_blur_perf_ios__timeline_summary.dart @gaaclarke @flutter/engine
233237

234238
## Host only DeviceLab tests

dev/benchmarks/macrobenchmarks/lib/common.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const String kPictureCacheComplexityScoringRouteName = '/picture_cache_complexit
1212
const String kLargeImageChangerRouteName = '/large_image_changer';
1313
const String kLargeImagesRouteName = '/large_images';
1414
const String kPathTessellationRouteName = '/path_tessellation';
15+
const String kPathStrokeTessellationRouteName = '/path_stroke_tessellation';
1516
const String kTextRouteName = '/text';
1617
const String kVeryLongPictureScrollingRouteName = '/very_long_picture_scrolling';
1718
const String kFullscreenTextRouteName = '/fullscreen_text';

dev/benchmarks/macrobenchmarks/lib/main.dart

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ class MacrobenchmarksApp extends StatelessWidget {
6969
kLargeImageChangerRouteName: (BuildContext context) => const LargeImageChangerPage(),
7070
kLargeImagesRouteName: (BuildContext context) => const LargeImagesPage(),
7171
kTextRouteName: (BuildContext context) => const TextPage(),
72-
kPathTessellationRouteName: (BuildContext context) => const PathTessellationPage(),
72+
kPathTessellationRouteName:
73+
(BuildContext context) => const PathTessellationPage(paintStyle: PaintingStyle.fill),
74+
kPathStrokeTessellationRouteName:
75+
(BuildContext context) => const PathTessellationPage(paintStyle: PaintingStyle.stroke),
7376
kFullscreenTextRouteName: (BuildContext context) => const TextFieldPage(),
7477
kAnimatedPlaceholderRouteName: (BuildContext context) => const AnimatedPlaceholderPage(),
7578
kClipperCacheRouteName: (BuildContext context) => const ClipperCachePage(),
@@ -188,6 +191,13 @@ class HomePage extends StatelessWidget {
188191
Navigator.pushNamed(context, kPathTessellationRouteName);
189192
},
190193
),
194+
ElevatedButton(
195+
key: const Key(kPathStrokeTessellationRouteName),
196+
child: const Text('Path Stroke Tessellation'),
197+
onPressed: () {
198+
Navigator.pushNamed(context, kPathStrokeTessellationRouteName);
199+
},
200+
),
191201
ElevatedButton(
192202
key: const Key(kTextRouteName),
193203
child: const Text('Text'),

dev/benchmarks/macrobenchmarks/lib/src/path_tessellation.dart

Lines changed: 127 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import 'package:flutter/material.dart';
66

77
class PathTessellationPage extends StatefulWidget {
8-
const PathTessellationPage({super.key});
8+
const PathTessellationPage({super.key, required this.paintStyle});
9+
10+
final PaintingStyle paintStyle;
911

1012
@override
1113
State<PathTessellationPage> createState() => _PathTessellationPageState();
@@ -39,7 +41,10 @@ class _PathTessellationPageState extends State<PathTessellationPage>
3941
return Container(
4042
margin: const EdgeInsets.all(1.0),
4143
decoration: BoxDecoration(color: Colors.white.withOpacity(0.2)),
42-
child: IconRow(iconSize: (30 + 0.5 * (index % 10)) * scale),
44+
child: IconRow(
45+
iconSize: (30 + 0.5 * (index % 10)) * scale,
46+
paintStyle: widget.paintStyle,
47+
),
4348
);
4449
},
4550
itemCount: 200,
@@ -52,7 +57,7 @@ class _PathTessellationPageState extends State<PathTessellationPage>
5257
child: Container(
5358
color: Colors.black.withOpacity(0.7),
5459
height: 100,
55-
child: IconRow(iconSize: 50.0 * scale),
60+
child: IconRow(iconSize: 50.0 * scale, paintStyle: widget.paintStyle),
5661
),
5762
),
5863
Positioned(
@@ -64,7 +69,10 @@ class _PathTessellationPageState extends State<PathTessellationPage>
6469
child: Column(
6570
crossAxisAlignment: CrossAxisAlignment.stretch,
6671
children: <Widget>[
67-
SizedBox(height: 100, child: IconRow(iconSize: 55.0 * scale)),
72+
SizedBox(
73+
height: 100,
74+
child: IconRow(iconSize: 55.0 * scale, paintStyle: widget.paintStyle),
75+
),
6876
MaterialButton(
6977
textColor: Colors.white,
7078
key: const Key('animate_button'), // this key is used by the driver test
@@ -89,9 +97,10 @@ class _PathTessellationPageState extends State<PathTessellationPage>
8997
}
9098

9199
class IconRow extends StatelessWidget {
92-
const IconRow({super.key, required this.iconSize});
100+
const IconRow({super.key, required this.iconSize, required this.paintStyle});
93101

94102
final double iconSize;
103+
final PaintingStyle paintStyle;
95104

96105
@override
97106
Widget build(BuildContext context) {
@@ -100,23 +109,23 @@ class IconRow extends StatelessWidget {
100109
children: <Widget>[
101110
SizedBox.square(
102111
dimension: iconSize,
103-
child: CustomPaint(painter: _SettingsIconPainter(), willChange: true),
112+
child: CustomPaint(painter: _SettingsIconPainter(paintStyle), willChange: true),
104113
),
105114
SizedBox.square(
106115
dimension: iconSize,
107-
child: CustomPaint(painter: _CameraIconPainter(), willChange: true),
116+
child: CustomPaint(painter: _CameraIconPainter(paintStyle), willChange: true),
108117
),
109118
SizedBox.square(
110119
dimension: iconSize,
111-
child: CustomPaint(painter: _CalendarIconPainter(), willChange: true),
120+
child: CustomPaint(painter: _CalendarIconPainter(paintStyle), willChange: true),
112121
),
113122
SizedBox.square(
114123
dimension: iconSize,
115-
child: CustomPaint(painter: _ConversationIconPainter(), willChange: true),
124+
child: CustomPaint(painter: _ConversationIconPainter(paintStyle), willChange: true),
116125
),
117126
SizedBox.square(
118127
dimension: iconSize,
119-
child: CustomPaint(painter: _GeometryIconPainter(), willChange: true),
128+
child: CustomPaint(painter: _GeometryIconPainter(paintStyle), willChange: true),
120129
),
121130
],
122131
);
@@ -181,19 +190,47 @@ Path _pathFromString(String pathString) {
181190
}
182191

183192
class _SettingsIconPainter extends CustomPainter {
193+
_SettingsIconPainter(this.paintStyle);
194+
195+
final PaintingStyle paintStyle;
196+
184197
@override
185198
void paint(Canvas canvas, Size size) {
186199
final Matrix4 scale = Matrix4.diagonal3Values(size.width / 20, size.height / 20, 1.0);
187200

188201
Path path;
189202
path = _path1.transform(scale.storage)..fillType = PathFillType.evenOdd;
190-
canvas.drawPath(path, Paint()..color = const Color(0x60F84F39));
203+
canvas.drawPath(
204+
path,
205+
Paint()
206+
..color = const Color(0x60F84F39)
207+
..style = paintStyle
208+
..strokeJoin = StrokeJoin.round
209+
..strokeCap = StrokeCap.round
210+
..strokeWidth = 2.0,
211+
);
191212

192213
path = _path2.transform(scale.storage)..fillType = PathFillType.evenOdd;
193-
canvas.drawPath(path, Paint()..color = const Color(0xFFF84F39));
214+
canvas.drawPath(
215+
path,
216+
Paint()
217+
..color = const Color(0xFFF84F39)
218+
..style = paintStyle
219+
..strokeJoin = StrokeJoin.round
220+
..strokeCap = StrokeCap.round
221+
..strokeWidth = 2.0,
222+
);
194223

195224
path = _path3.transform(scale.storage)..fillType = PathFillType.evenOdd;
196-
canvas.drawPath(path, Paint()..color = const Color(0xFFF84F39));
225+
canvas.drawPath(
226+
path,
227+
Paint()
228+
..color = const Color(0xFFF84F39)
229+
..style = paintStyle
230+
..strokeJoin = StrokeJoin.round
231+
..strokeCap = StrokeCap.round
232+
..strokeWidth = 2.0,
233+
);
197234
}
198235

199236
static final Path _path1 = _pathFromString(
@@ -213,16 +250,36 @@ class _SettingsIconPainter extends CustomPainter {
213250
}
214251

215252
class _CameraIconPainter extends CustomPainter {
253+
_CameraIconPainter(this.paintStyle);
254+
255+
final PaintingStyle paintStyle;
256+
216257
@override
217258
void paint(Canvas canvas, Size size) {
218259
final Matrix4 scale = Matrix4.diagonal3Values(size.width / 20, size.height / 20, 1.0);
219260

220261
Path path;
221262
path = _path1.transform(scale.storage)..fillType = PathFillType.evenOdd;
222-
canvas.drawPath(path, Paint()..color = const Color(0xFFF84F39));
263+
canvas.drawPath(
264+
path,
265+
Paint()
266+
..color = const Color(0xFFF84F39)
267+
..style = paintStyle
268+
..strokeJoin = StrokeJoin.round
269+
..strokeCap = StrokeCap.round
270+
..strokeWidth = 2.0,
271+
);
223272

224273
path = _path2.transform(scale.storage)..fillType = PathFillType.evenOdd;
225-
canvas.drawPath(path, Paint()..color = const Color(0x60F84F39));
274+
canvas.drawPath(
275+
path,
276+
Paint()
277+
..color = const Color(0x60F84F39)
278+
..style = paintStyle
279+
..strokeJoin = StrokeJoin.round
280+
..strokeCap = StrokeCap.round
281+
..strokeWidth = 2.0,
282+
);
226283
}
227284

228285
static final Path _path1 = _pathFromString(
@@ -239,16 +296,36 @@ class _CameraIconPainter extends CustomPainter {
239296
}
240297

241298
class _CalendarIconPainter extends CustomPainter {
299+
_CalendarIconPainter(this.paintStyle);
300+
301+
final PaintingStyle paintStyle;
302+
242303
@override
243304
void paint(Canvas canvas, Size size) {
244305
final Matrix4 scale = Matrix4.diagonal3Values(size.width / 20, size.height / 20, 1.0);
245306

246307
Path path;
247308
path = _path1.transform(scale.storage)..fillType = PathFillType.evenOdd;
248-
canvas.drawPath(path, Paint()..color = const Color(0x60F84F39));
309+
canvas.drawPath(
310+
path,
311+
Paint()
312+
..color = const Color(0x60F84F39)
313+
..style = paintStyle
314+
..strokeJoin = StrokeJoin.round
315+
..strokeCap = StrokeCap.round
316+
..strokeWidth = 2.0,
317+
);
249318

250319
path = _path2.transform(scale.storage)..fillType = PathFillType.evenOdd;
251-
canvas.drawPath(path, Paint()..color = const Color(0xFFF84F39));
320+
canvas.drawPath(
321+
path,
322+
Paint()
323+
..color = const Color(0xFFF84F39)
324+
..style = paintStyle
325+
..strokeJoin = StrokeJoin.round
326+
..strokeCap = StrokeCap.round
327+
..strokeWidth = 2.0,
328+
);
252329
}
253330

254331
static final Path _path1 = _pathFromString(
@@ -265,16 +342,36 @@ class _CalendarIconPainter extends CustomPainter {
265342
}
266343

267344
class _ConversationIconPainter extends CustomPainter {
345+
_ConversationIconPainter(this.paintStyle);
346+
347+
final PaintingStyle paintStyle;
348+
268349
@override
269350
void paint(Canvas canvas, Size size) {
270351
final Matrix4 scale = Matrix4.diagonal3Values(size.width / 20, size.height / 20, 1.0);
271352

272353
Path path;
273354
path = _path1.transform(scale.storage)..fillType = PathFillType.evenOdd;
274-
canvas.drawPath(path, Paint()..color = const Color(0x60F84F39));
355+
canvas.drawPath(
356+
path,
357+
Paint()
358+
..color = const Color(0x60F84F39)
359+
..style = paintStyle
360+
..strokeJoin = StrokeJoin.round
361+
..strokeCap = StrokeCap.round
362+
..strokeWidth = 2.0,
363+
);
275364

276365
path = _path2.transform(scale.storage)..fillType = PathFillType.evenOdd;
277-
canvas.drawPath(path, Paint()..color = const Color(0xFFF84F39));
366+
canvas.drawPath(
367+
path,
368+
Paint()
369+
..color = const Color(0xFFF84F39)
370+
..style = paintStyle
371+
..strokeJoin = StrokeJoin.round
372+
..strokeCap = StrokeCap.round
373+
..strokeWidth = 2.0,
374+
);
278375
}
279376

280377
static final Path _path1 = _pathFromString(
@@ -291,12 +388,22 @@ class _ConversationIconPainter extends CustomPainter {
291388
}
292389

293390
class _GeometryIconPainter extends CustomPainter {
391+
_GeometryIconPainter(this.paintStyle);
392+
393+
final PaintingStyle paintStyle;
394+
294395
@override
295396
void paint(Canvas canvas, Size canvasSize) {
296397
const Size size = Size(20, 20);
297398
canvas.scale(canvasSize.width / size.width, canvasSize.height / size.height);
298399

299-
final Paint paint = Paint()..color = const Color(0xFFF84F39);
400+
final Paint paint =
401+
Paint()
402+
..color = const Color(0xFFF84F39)
403+
..style = paintStyle
404+
..strokeJoin = StrokeJoin.round
405+
..strokeCap = StrokeCap.round
406+
..strokeWidth = 2.0;
300407
final Rect frame = Offset.zero & size;
301408
canvas.drawDRRect(
302409
RRect.fromRectAndRadius(frame, const Radius.elliptical(5, 4)),

0 commit comments

Comments
 (0)