Unverified Commit b176042c authored by Emmanuel Garcia's avatar Emmanuel Garcia Committed by GitHub

Add benchmark for hybrid composition on Android (#55609)

parent deb0fa37
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
class AndroidPlatformView extends StatelessWidget {
/// Creates a platform view for Android, which is rendered as a
/// native view.
/// `viewType` identifies the type of Android view to create.
const AndroidPlatformView({
Key key,
@required this.viewType,
}) : assert(viewType != null),
super(key: key);
/// The unique identifier for the view type to be embedded by this widget.
///
/// A PlatformViewFactory for this type must have been registered.
final String viewType;
@override
Widget build(BuildContext context) {
return PlatformViewLink(
viewType: viewType,
onCreatePlatformView: _onCreateAndroidView,
surfaceFactory: (BuildContext context, PlatformViewController controller) {
return PlatformViewSurface(
controller: controller,
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
);
},
);
}
PlatformViewController _onCreateAndroidView(PlatformViewCreationParams params) {
final _AndroidViewController controller = _AndroidViewController(params.id, viewType);
controller._initialize().then((_) { params.onPlatformViewCreated(params.id); });
return controller;
}
}
// TODO(egarciad): The Android view controller should be defined in the framework.
// https://github.com/flutter/flutter/issues/55904
class _AndroidViewController extends PlatformViewController {
_AndroidViewController(
this.viewId,
this.viewType,
);
@override
final int viewId;
/// The unique identifier for the Android view type to be embedded by this widget.
///
/// A PlatformViewFactory for this type must have been registered.
final String viewType;
bool _initialized = false;
Future<void> _initialize() async {
// TODO(egarciad): Initialize platform view.
_initialized = true;
}
@override
void clearFocus() {
// TODO(egarciad): Implement clear focus.
}
@override
void dispatchPointerEvent(PointerEvent event) {
// TODO(egarciad): Implement dispatchPointerEvent
}
@override
void dispose() {
if (_initialized) {
// TODO(egarciad): Dispose the android view.
}
}
}
...@@ -7,13 +7,23 @@ import 'dart:io'; ...@@ -7,13 +7,23 @@ import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show timeDilation; import 'package:flutter/scheduler.dart' show timeDilation;
import 'android_platform_view.dart';
void main() { void main() {
runApp( runApp(
PlatformViewApp() const PlatformViewApp()
); );
} }
class PlatformViewApp extends StatefulWidget { class PlatformViewApp extends StatefulWidget {
const PlatformViewApp({
Key key,
this.enableHybridCompositionOnAndroid = false,
}) : super(key: key);
/// Whether to use render the Android view as a platform view or a texture.
final bool enableHybridCompositionOnAndroid;
@override @override
PlatformViewAppState createState() => PlatformViewAppState(); PlatformViewAppState createState() => PlatformViewAppState();
...@@ -37,7 +47,6 @@ class PlatformViewAppState extends State<PlatformViewApp> { ...@@ -37,7 +47,6 @@ class PlatformViewAppState extends State<PlatformViewApp> {
} }
} }
class PlatformViewLayout extends StatelessWidget { class PlatformViewLayout extends StatelessWidget {
const PlatformViewLayout({ Key key }) : super(key: key); const PlatformViewLayout({ Key key }) : super(key: key);
...@@ -74,15 +83,23 @@ class DummyPlatformView extends StatelessWidget { ...@@ -74,15 +83,23 @@ class DummyPlatformView extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
const String viewType = 'benchmarks/platform_views_layout/DummyPlatformView'; const String viewType = 'benchmarks/platform_views_layout/DummyPlatformView';
StatefulWidget nativeView; Widget nativeView;
if (Platform.isIOS) { if (Platform.isIOS) {
nativeView = const UiKitView( nativeView = const UiKitView(
viewType: viewType, viewType: viewType,
); );
} else if (Platform.isAndroid) { } else if (Platform.isAndroid) {
nativeView = const AndroidView( final PlatformViewApp app = PlatformViewApp.of(context).widget;
viewType: viewType, assert(app != null);
); if (app.enableHybridCompositionOnAndroid) {
nativeView = const AndroidPlatformView(
viewType: viewType,
);
} else {
nativeView = const AndroidView(
viewType: viewType,
);
}
} else { } else {
assert(false, 'Invalid platform'); assert(false, 'Invalid platform');
} }
......
...@@ -2,8 +2,7 @@ name: platform_views_layout ...@@ -2,8 +2,7 @@ name: platform_views_layout
description: A benchmark for platform views. description: A benchmark for platform views.
environment: environment:
# The pub client defaults to an <2.0.0 sdk constraint which we need to explicitly overwrite. sdk: ">=2.2.0 <3.0.0"
sdk: ">=2.0.0-dev.68.0 <3.0.0"
dependencies: dependencies:
flutter: flutter:
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/widgets.dart';
import 'package:flutter_driver/driver_extension.dart';
import 'package:platform_views_layout/main.dart' as app;
void main() {
enableFlutterDriverExtension();
runApp(
const app.PlatformViewApp(
enableHybridCompositionOnAndroid: false,
)
);
}
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/widgets.dart';
import 'package:flutter_driver/driver_extension.dart';
import 'package:platform_views_layout/main.dart' as app;
void main() {
enableFlutterDriverExtension();
runApp(
const app.PlatformViewApp(
enableHybridCompositionOnAndroid: true,
)
);
}
...@@ -2,10 +2,12 @@ ...@@ -2,10 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/widgets.dart';
import 'package:flutter_driver/driver_extension.dart'; import 'package:flutter_driver/driver_extension.dart';
import 'package:platform_views_layout/main.dart' as app; import 'package:platform_views_layout/main.dart' as app;
void main() { void main() {
enableFlutterDriverExtension(); enableFlutterDriverExtension();
app.main(); runApp(const app.PlatformViewApp());
} }
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter_devicelab/tasks/perf_tests.dart';
import 'package:flutter_devicelab/framework/adb.dart';
import 'package:flutter_devicelab/framework/framework.dart';
Future<void> main() async {
deviceOperatingSystem = DeviceOperatingSystem.android;
await task(createAndroidViewScrollPerfTest());
}
...@@ -10,5 +10,5 @@ import 'package:flutter_devicelab/framework/framework.dart'; ...@@ -10,5 +10,5 @@ import 'package:flutter_devicelab/framework/framework.dart';
Future<void> main() async { Future<void> main() async {
deviceOperatingSystem = DeviceOperatingSystem.android; deviceOperatingSystem = DeviceOperatingSystem.android;
await task(createPlatformViewsScrollPerfTest()); await task(createAndroidTextureScrollPerfTest());
} }
...@@ -10,5 +10,5 @@ import 'package:flutter_devicelab/framework/framework.dart'; ...@@ -10,5 +10,5 @@ import 'package:flutter_devicelab/framework/framework.dart';
Future<void> main() async { Future<void> main() async {
deviceOperatingSystem = DeviceOperatingSystem.ios; deviceOperatingSystem = DeviceOperatingSystem.ios;
await task(createPlatformViewsScrollPerfTest()); await task(createUiKitViewScrollPerfTest());
} }
...@@ -30,11 +30,30 @@ TaskFunction createTilesScrollPerfTest() { ...@@ -30,11 +30,30 @@ TaskFunction createTilesScrollPerfTest() {
).run; ).run;
} }
TaskFunction createPlatformViewsScrollPerfTest() { TaskFunction createUiKitViewScrollPerfTest() {
return PerfTest( return PerfTest(
'${flutterDirectory.path}/dev/benchmarks/platform_views_layout', '${flutterDirectory.path}/dev/benchmarks/platform_views_layout',
'test_driver/scroll_perf.dart', 'test_driver/uikit_view_scroll_perf.dart',
'platform_views_scroll_perf',
testDriver: 'test_driver/scroll_perf_test.dart',
).run;
}
TaskFunction createAndroidTextureScrollPerfTest() {
return PerfTest(
'${flutterDirectory.path}/dev/benchmarks/platform_views_layout',
'test_driver/android_texture_scroll_perf.dart',
'platform_views_scroll_perf', 'platform_views_scroll_perf',
testDriver: 'test_driver/scroll_perf_test.dart',
).run;
}
TaskFunction createAndroidViewScrollPerfTest() {
return PerfTest(
'${flutterDirectory.path}/dev/benchmarks/platform_views_layout',
'test_driver/android_view_scroll_perf.dart',
'android_view_scroll_perf',
testDriver: 'test_driver/scroll_perf_test.dart',
).run; ).run;
} }
...@@ -235,15 +254,22 @@ class StartupTest { ...@@ -235,15 +254,22 @@ class StartupTest {
/// performance. /// performance.
class PerfTest { class PerfTest {
const PerfTest( const PerfTest(
this.testDirectory, this.testDirectory,
this.testTarget, this.testTarget,
this.timelineFileName, this.timelineFileName, {
{this.needsMeasureCpuGPu = false}); this.needsMeasureCpuGPu = false,
this.testDriver,
});
/// The directory where the app under test is defined.
final String testDirectory; final String testDirectory;
/// The main entry-point file of the application, as run on the device.
final String testTarget; final String testTarget;
// The prefix name of the filename such as `<timelineFileName>.timeline_summary.json`.
final String timelineFileName; final String timelineFileName;
/// The test file to run on the host.
final String testDriver;
/// Whether to collect CPU and GPU metrics.
final bool needsMeasureCpuGPu; final bool needsMeasureCpuGPu;
Future<TaskResult> run() { Future<TaskResult> run() {
...@@ -259,6 +285,8 @@ class PerfTest { ...@@ -259,6 +285,8 @@ class PerfTest {
'--trace-startup', // Enables "endless" timeline event buffering. '--trace-startup', // Enables "endless" timeline event buffering.
'-t', '-t',
testTarget, testTarget,
if (testDriver != null)
'--driver', testDriver,
'-d', '-d',
deviceId, deviceId,
]); ]);
......
...@@ -152,6 +152,12 @@ tasks: ...@@ -152,6 +152,12 @@ tasks:
stage: devicelab stage: devicelab
required_agent_capabilities: ["linux/android"] required_agent_capabilities: ["linux/android"]
android_view_scroll_perf__timeline_summary:
description: >
Measures the runtime performance of Android views in the platform view layout sample app on Android.
stage: devicelab
required_agent_capabilities: ["linux/android"]
home_scroll_perf__timeline_summary: home_scroll_perf__timeline_summary:
description: > description: >
Measures the runtime performance of scrolling the material page in the Measures the runtime performance of scrolling the material page in the
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment