Skip to content

Commit 6291a51

Browse files
author
Jonah Williams
authored
[Android] add HCPP platform views benchmark and integration test. (flutter#163018)
Adds a benchmark and integration test of HCPP using a Pixel 7.
1 parent e8a0fbb commit 6291a51

File tree

7 files changed

+251
-2
lines changed

7 files changed

+251
-2
lines changed

.ci.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,6 +3210,16 @@ targets:
32103210
["devicelab", "android", "linux", "pixel", "7pro"]
32113211
task_name: platform_views_scroll_perf_impeller__timeline_summary
32123212

3213+
- name: Linux_pixel_7pro platform_views_hcpp_scroll_perf__timeline_summary
3214+
recipe: devicelab/devicelab_drone
3215+
presubmit: false
3216+
bringup: true
3217+
timeout: 60
3218+
properties:
3219+
tags: >
3220+
["devicelab", "android", "linux", "pixel", "7pro"]
3221+
task_name: platform_views_hcpp_scroll_perf__timeline_summary
3222+
32133223
# linux mokey benchmark
32143224
- name: Linux_mokey platform_view__start_up
32153225
recipe: devicelab/devicelab_drone

TESTOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
/dev/devicelab/bin/tasks/complex_layout_scroll_perf_impeller__timeline_summary.dart @jonahwilliams @flutter/engine
109109
/dev/devicelab/bin/tasks/complex_layout_scroll_perf_impeller_gles__timeline_summary.dart @jonahwilliams @flutter/engine
110110
/dev/devicelab/bin/tasks/rrect_blur_perf__timeline_summary.dart @gaaclarke @flutter/engine
111+
/dev/devicelab/bin/tasks/platform_views_hcpp_scroll_perf__timeline_summary.dart @jonahwilliams @flutter/engine
111112

112113
## Windows Android DeviceLab tests
113114
/dev/devicelab/bin/tasks/basic_material_app_win__compile.dart @bkonyi @flutter/tool
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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:flutter/foundation.dart';
6+
import 'package:flutter/gestures.dart';
7+
import 'package:flutter/material.dart';
8+
import 'package:flutter/rendering.dart';
9+
import 'package:flutter/services.dart';
10+
11+
void main() {
12+
runApp(const PlatformViewApp());
13+
}
14+
15+
class PlatformViewApp extends StatefulWidget {
16+
const PlatformViewApp({super.key});
17+
18+
@override
19+
PlatformViewAppState createState() => PlatformViewAppState();
20+
}
21+
22+
class PlatformViewAppState extends State<PlatformViewApp> {
23+
@override
24+
Widget build(BuildContext context) {
25+
return MaterialApp(
26+
theme: ThemeData.light(),
27+
title: 'Advanced Layout',
28+
home: const PlatformViewLayout(),
29+
);
30+
}
31+
}
32+
33+
class PlatformViewLayout extends StatelessWidget {
34+
const PlatformViewLayout({super.key});
35+
36+
@override
37+
Widget build(BuildContext context) {
38+
return Scaffold(
39+
appBar: AppBar(title: const Text('Platform View Scrolling Layout')),
40+
body: ListView.builder(
41+
key: const Key('platform-views-scroll'), // This key is used by the driver test.
42+
itemCount: 200,
43+
itemBuilder: (BuildContext context, int index) {
44+
return Padding(
45+
padding: const EdgeInsets.all(5.0),
46+
child: Material(
47+
elevation: (index % 5 + 1).toDouble(),
48+
color: Colors.white,
49+
child: const Stack(children: <Widget>[_AndroidPlatformView(), RotationContainer()]),
50+
),
51+
);
52+
},
53+
),
54+
);
55+
}
56+
}
57+
58+
final class _AndroidPlatformView extends StatelessWidget {
59+
const _AndroidPlatformView();
60+
61+
static const String viewType = 'benchmarks/platform_views_layout/DummyPlatformView';
62+
63+
@override
64+
Widget build(BuildContext context) {
65+
return SizedBox(
66+
width: 400,
67+
height: 200,
68+
child: PlatformViewLink(
69+
viewType: viewType,
70+
surfaceFactory: (BuildContext context, PlatformViewController controller) {
71+
return AndroidViewSurface(
72+
controller: controller as AndroidViewController,
73+
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
74+
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
75+
);
76+
},
77+
onCreatePlatformView: (PlatformViewCreationParams params) {
78+
return PlatformViewsService.initHybridAndroidView(
79+
id: params.id,
80+
viewType: viewType,
81+
layoutDirection: TextDirection.ltr,
82+
creationParamsCodec: const StandardMessageCodec(),
83+
)
84+
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
85+
..create();
86+
},
87+
),
88+
);
89+
}
90+
}
91+
92+
class RotationContainer extends StatefulWidget {
93+
const RotationContainer({super.key});
94+
95+
@override
96+
State<RotationContainer> createState() => _RotationContainerState();
97+
}
98+
99+
class _RotationContainerState extends State<RotationContainer> with SingleTickerProviderStateMixin {
100+
late AnimationController _rotationController;
101+
102+
@override
103+
void initState() {
104+
super.initState();
105+
_rotationController = AnimationController(
106+
vsync: this,
107+
duration: const Duration(seconds: 1),
108+
value: 1,
109+
);
110+
_rotationController.repeat();
111+
}
112+
113+
@override
114+
void dispose() {
115+
_rotationController.dispose();
116+
super.dispose();
117+
}
118+
119+
@override
120+
Widget build(BuildContext context) {
121+
return RotationTransition(
122+
turns: Tween<double>(begin: 0.0, end: 1.0).animate(_rotationController),
123+
child: Container(color: Colors.purple, width: 50.0, height: 50.0),
124+
);
125+
}
126+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
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:flutter/widgets.dart';
6+
import 'package:flutter_driver/driver_extension.dart';
7+
8+
import 'package:platform_views_layout/main_hcpp.dart' as app;
9+
10+
void main() {
11+
enableFlutterDriverExtension();
12+
runApp(const app.PlatformViewApp());
13+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
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:flutter_driver/flutter_driver.dart';
6+
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
7+
8+
void main() {
9+
group('scrolling performance test', () {
10+
late FlutterDriver driver;
11+
12+
setUpAll(() async {
13+
driver = await FlutterDriver.connect();
14+
15+
await driver.waitUntilFirstFrameRasterized();
16+
});
17+
18+
tearDownAll(() async {
19+
driver.close();
20+
});
21+
22+
Future<void> testScrollPerf(String listKey, String summaryName) async {
23+
// The slight initial delay avoids starting the timing during a
24+
// period of increased load on the device. Without this delay, the
25+
// benchmark has greater noise.
26+
// See: https://github.com/flutter/flutter/issues/19434
27+
await Future<void>.delayed(const Duration(milliseconds: 250));
28+
29+
await driver.forceGC();
30+
31+
final Timeline timeline = await driver.traceAction(() async {
32+
// Find the scrollable stock list
33+
final SerializableFinder list = find.byValueKey(listKey);
34+
35+
for (int j = 0; j < 5; j += 1) {
36+
// Scroll down
37+
for (int i = 0; i < 5; i += 1) {
38+
await driver.scroll(list, 0.0, -300.0, const Duration(milliseconds: 300));
39+
await Future<void>.delayed(const Duration(milliseconds: 500));
40+
}
41+
42+
// Scroll up
43+
for (int i = 0; i < 5; i += 1) {
44+
await driver.scroll(list, 0.0, 300.0, const Duration(milliseconds: 300));
45+
await Future<void>.delayed(const Duration(milliseconds: 500));
46+
}
47+
}
48+
});
49+
50+
final TimelineSummary summary = TimelineSummary.summarize(timeline);
51+
await summary.writeTimelineToFile(summaryName, pretty: true);
52+
}
53+
54+
test('platform_views_scroll_perf', () async {
55+
// Disable frame sync, since there are ongoing animations.
56+
await driver.runUnsynchronized(() async {
57+
await testScrollPerf('platform-views-scroll', 'platform_views_hcpp_scroll_perf');
58+
});
59+
}, timeout: Timeout.none);
60+
});
61+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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:flutter_devicelab/framework/devices.dart';
6+
import 'package:flutter_devicelab/framework/framework.dart';
7+
import 'package:flutter_devicelab/tasks/perf_tests.dart';
8+
9+
Future<void> main() async {
10+
deviceOperatingSystem = DeviceOperatingSystem.android;
11+
await task(createAndroidHCPPScrollPerfTest());
12+
}

dev/devicelab/lib/tasks/perf_tests.dart

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,19 @@ TaskFunction createAndroidTextureScrollPerfTest({bool? enableImpeller}) {
107107
).run;
108108
}
109109

110+
TaskFunction createAndroidHCPPScrollPerfTest() {
111+
return PerfTest(
112+
'${flutterDirectory.path}/dev/benchmarks/platform_views_layout',
113+
'test_driver/scroll_perf_hcpp.dart',
114+
'platform_views_hcpp_scroll_perf',
115+
testDriver: 'test_driver/scroll_perf_hcpp_test.dart',
116+
needsFullTimeline: false,
117+
enableImpeller: true,
118+
enableSurfaceControl: true,
119+
enableMergedPlatformThread: true,
120+
).run;
121+
}
122+
110123
TaskFunction createAndroidViewScrollPerfTest() {
111124
return PerfTest(
112125
'${flutterDirectory.path}/dev/benchmarks/platform_views_layout_hybrid_composition',
@@ -847,6 +860,13 @@ void _addMetadataToManifest(String testDirectory, List<(String, String)> keyPair
847860
file.writeAsStringSync(xmlDoc.toXmlString(pretty: true, indent: ' '));
848861
}
849862

863+
void _addSurfaceControlSupportToManifest(String testDirectory) {
864+
final List<(String, String)> keyPairs = <(String, String)>[
865+
('io.flutter.embedding.android.EnableSurfaceControl', 'true'),
866+
];
867+
_addMetadataToManifest(testDirectory, keyPairs);
868+
}
869+
850870
void _addMergedPlatformThreadSupportToManifest(String testDirectory) {
851871
final List<(String, String)> keyPairs = <(String, String)>[
852872
('io.flutter.embedding.android.EnableMergedPlatformUIThread', 'true'),
@@ -1204,6 +1224,7 @@ class PerfTest {
12041224
this.forceOpenGLES,
12051225
this.disablePartialRepaint = false,
12061226
this.enableMergedPlatformThread = false,
1227+
this.enableSurfaceControl = false,
12071228
this.createPlatforms = const <String>[],
12081229
}) : _resultFilename = resultFilename;
12091230

@@ -1225,6 +1246,7 @@ class PerfTest {
12251246
this.forceOpenGLES,
12261247
this.disablePartialRepaint = false,
12271248
this.enableMergedPlatformThread = false,
1249+
this.enableSurfaceControl = false,
12281250
this.createPlatforms = const <String>[],
12291251
}) : saveTraceFile = false,
12301252
timelineFileName = null,
@@ -1281,6 +1303,9 @@ class PerfTest {
12811303
/// Whether the UI thread should be the platform thread.
12821304
final bool enableMergedPlatformThread;
12831305

1306+
/// Whether to enable SurfaceControl swapchain.
1307+
final bool enableSurfaceControl;
1308+
12841309
/// Number of seconds to time out the test after, allowing debug callbacks to run.
12851310
final int? timeoutSeconds;
12861311

@@ -1376,6 +1401,9 @@ class PerfTest {
13761401
if (enableMergedPlatformThread) {
13771402
_addMergedPlatformThreadSupportToManifest(testDirectory);
13781403
}
1404+
if (enableSurfaceControl) {
1405+
_addSurfaceControlSupportToManifest(testDirectory);
1406+
}
13791407
}
13801408
if (disablePartialRepaint || enableMergedPlatformThread) {
13811409
changedPlist = true;
@@ -1450,8 +1478,6 @@ class PerfTest {
14501478
recordGPU = false;
14511479
}
14521480

1453-
// TODO(liyuqian): Remove isAndroid restriction once
1454-
// https://github.com/flutter/flutter/issues/61567 is fixed.
14551481
final bool isAndroid = deviceOperatingSystem == DeviceOperatingSystem.android;
14561482
return TaskResult.success(
14571483
data,

0 commit comments

Comments
 (0)