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

Commit dfa3d33

Browse files
[devicelab] track performance of animated image filter (#115850)
* [devicelab] track performance of animated image filter * ++ * make animations repeat and add dispose * make duration more consistently 10sec
1 parent f777c9f commit dfa3d33

11 files changed

+146
-3
lines changed

.ci.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,16 @@ targets:
13901390
["devicelab", "android", "linux"]
13911391
task_name: animated_complex_opacity_perf__e2e_summary
13921392

1393+
- name: Linux_android animated_complex_image_filtered_perf__e2e_summary
1394+
recipe: devicelab/devicelab_drone
1395+
presubmit: false
1396+
bringup: true
1397+
timeout: 60
1398+
properties:
1399+
tags: >
1400+
["devicelab", "android", "linux"]
1401+
task_name: animated_complex_image_filtered_perf__e2e_summary
1402+
13931403
- name: Linux_android animated_placeholder_perf__e2e_summary
13941404
recipe: devicelab/devicelab_drone
13951405
presubmit: false

TESTOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
/dev/devicelab/bin/tasks/gradient_dynamic_perf__e2e_summary.dart @flar @flutter/engine
8686
/dev/devicelab/bin/tasks/gradient_static_perf__e2e_summary.dart @flar @flutter/engine
8787
/dev/devicelab/bin/tasks/animated_complex_opacity_perf__e2e_summary.dart @jonahwilliams @flutter/engine
88+
/dev/devicelab/bin/tasks/animated_complex_image_filtered_perf__e2e_summary.dart @jonahwilliams @flutter/engine
8889
/dev/devicelab/bin/tasks/spell_check_test.dart @camsim99 @flutter/android
8990

9091
## Windows Android DeviceLab tests

dev/benchmarks/macrobenchmarks/lib/common.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ const String kAnimatedImageRouteName = '/animated_image';
3131
const String kOpacityPeepholeRouteName = '/opacity_peephole';
3232
const String kGradientPerfRouteName = '/gradient_perf';
3333
const String kAnimatedComplexOpacityPerfRouteName = '/animated_complex_opacity';
34+
const String kAnimatedComplexImageFilteredPerfRouteName = '/animated_complex_image_filtered';
3435
const String kListTextLayoutRouteName = '/list_text_layout';
3536

3637
const String kOpacityPeepholeOneRectRouteName = '$kOpacityPeepholeRouteName/one_big_rect';

dev/benchmarks/macrobenchmarks/lib/main.dart

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

77
import 'common.dart';
88

9+
import 'src/animated_complex_image_filtered.dart';
910
import 'src/animated_complex_opacity.dart';
1011
import 'src/animated_image.dart';
1112
import 'src/animated_placeholder.dart';
@@ -82,6 +83,7 @@ class MacrobenchmarksApp extends StatelessWidget {
8283
...gradientPerfRoutes,
8384
kAnimatedComplexOpacityPerfRouteName: (BuildContext context) => const AnimatedComplexOpacity(),
8485
kListTextLayoutRouteName: (BuildContext context) => const ColumnOfText(),
86+
kAnimatedComplexImageFilteredPerfRouteName: (BuildContext context) => const AnimatedComplexImageFiltered(),
8587
},
8688
);
8789
}
@@ -295,6 +297,13 @@ class HomePage extends StatelessWidget {
295297
Navigator.pushNamed(context, kAnimatedComplexOpacityPerfRouteName);
296298
},
297299
),
300+
ElevatedButton(
301+
key: const Key(kAnimatedComplexImageFilteredPerfRouteName),
302+
child: const Text('Animated complex image filtered perf'),
303+
onPressed: () {
304+
Navigator.pushNamed(context, kAnimatedComplexImageFilteredPerfRouteName);
305+
},
306+
),
298307
ElevatedButton(
299308
key: const Key(kListTextLayoutRouteName),
300309
child: const Text('A list with lots of text'),
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:ui' as ui;
6+
import 'package:flutter/material.dart';
7+
8+
// Various tests to verify that Animated image filtered layers do not
9+
// dirty children even without explicit repaint boundaries. These intentionally use
10+
// text to ensure we don't measure the opacity peephole case.
11+
class AnimatedComplexImageFiltered extends StatefulWidget {
12+
const AnimatedComplexImageFiltered({ super.key });
13+
14+
@override
15+
State<AnimatedComplexImageFiltered> createState() => _AnimatedComplexImageFilteredState();
16+
}
17+
18+
class _AnimatedComplexImageFilteredState extends State<AnimatedComplexImageFiltered> with SingleTickerProviderStateMixin {
19+
late final AnimationController controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 5000));
20+
late final Animation<double> animation = controller.drive(Tween<double>(begin: 0.0, end: 1.0));
21+
ui.ImageFilter imageFilter = ui.ImageFilter.blur();
22+
23+
@override
24+
void initState() {
25+
super.initState();
26+
controller.repeat();
27+
animation.addListener(() {
28+
setState(() {
29+
imageFilter = ui.ImageFilter.blur(sigmaX: animation.value * 5, sigmaY: animation.value * 5);
30+
});
31+
});
32+
}
33+
34+
@override
35+
void dispose() {
36+
controller.dispose();
37+
super.dispose();
38+
}
39+
40+
@override
41+
Widget build(BuildContext context) {
42+
return MaterialApp(
43+
home: Scaffold(
44+
body: ListView(
45+
children: <Widget>[
46+
for (int i = 0; i < 20; i++)
47+
ImageFiltered(
48+
imageFilter: imageFilter,
49+
child: Center(
50+
child: Transform.scale(scale: 1.01, child: const ModeratelyComplexWidget()),
51+
),
52+
),
53+
],
54+
),
55+
),
56+
);
57+
}
58+
}
59+
60+
class ModeratelyComplexWidget extends StatelessWidget {
61+
const ModeratelyComplexWidget({ super.key });
62+
63+
@override
64+
Widget build(BuildContext context) {
65+
return const Material(
66+
elevation: 10,
67+
clipBehavior: Clip.hardEdge,
68+
child: ListTile(
69+
leading: Icon(Icons.abc, size: 24),
70+
title: DecoratedBox(decoration: BoxDecoration(color: Colors.red), child: Text('Hello World')),
71+
trailing: FlutterLogo(),
72+
),
73+
);
74+
}
75+
}

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@ class _AnimatedComplexOpacityState extends State<AnimatedComplexOpacity> with Si
2121
@override
2222
void initState() {
2323
super.initState();
24-
controller.forward(from: 0.0);
24+
controller.repeat();
25+
}
26+
27+
@override
28+
void dispose() {
29+
controller.dispose();
30+
super.dispose();
2531
}
2632

2733
@override
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:macrobenchmarks/common.dart';
6+
7+
import 'util.dart';
8+
9+
void main() {
10+
macroPerfTestE2E(
11+
'animated_complex_image_filtered_perf',
12+
kAnimatedComplexImageFilteredPerfRouteName,
13+
pageDelay: const Duration(seconds: 1),
14+
duration: const Duration(seconds: 10),
15+
);
16+
}

dev/benchmarks/macrobenchmarks/test/animated_complex_opacity_perf_e2e.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ void main() {
1111
'animated_complex_opacity_perf',
1212
kAnimatedComplexOpacityPerfRouteName,
1313
pageDelay: const Duration(seconds: 1),
14-
duration: const Duration(seconds: 5),
14+
duration: const Duration(seconds: 10),
1515
);
1616
}

dev/benchmarks/macrobenchmarks/test/animated_placeholder_perf_e2e.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ void main() {
1111
'animated_placeholder_perf',
1212
kAnimatedPlaceholderRouteName,
1313
pageDelay: const Duration(seconds: 1),
14-
duration: const Duration(seconds: 5),
14+
duration: const Duration(seconds: 10),
1515
);
1616
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'dart:async';
6+
7+
import 'package:flutter_devicelab/framework/devices.dart';
8+
import 'package:flutter_devicelab/framework/framework.dart';
9+
import 'package:flutter_devicelab/tasks/perf_tests.dart';
10+
11+
Future<void> main() async {
12+
deviceOperatingSystem = DeviceOperatingSystem.android;
13+
await task(createAnimatedComplexImageFilteredPerfE2ETest());
14+
}

dev/devicelab/lib/tasks/perf_tests.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,17 @@ TaskFunction createAnimatedComplexOpacityPerfE2ETest({
627627
).run;
628628
}
629629

630+
TaskFunction createAnimatedComplexImageFilteredPerfE2ETest({
631+
bool enableImpeller = false,
632+
}) {
633+
return PerfTest.e2e(
634+
'${flutterDirectory.path}/dev/benchmarks/macrobenchmarks',
635+
'test/animated_complex_image_filtered_perf_e2e.dart',
636+
enableImpeller: enableImpeller,
637+
).run;
638+
}
639+
640+
630641
Map<String, dynamic> _average(List<Map<String, dynamic>> results, int iterations) {
631642
final Map<String, dynamic> tally = <String, dynamic>{};
632643
for (final Map<String, dynamic> item in results) {

0 commit comments

Comments
 (0)