From f83fd9d4673cece4647bfb4919d956fb5709ec92 Mon Sep 17 00:00:00 2001 From: Jim Graham <50503328+jim-flar@users.noreply.github.com> Date: Mon, 24 Jun 2019 20:53:22 -0700 Subject: [PATCH] Add test case for Flutter Issue #27677 as a benchmark. (#34870) * Add test case for Flutter Issue #27677 as a benchmark. See https://github.com/flutter/flutter/issues/27677 I got the following results running the test on a Moto E2 which will help us determine how much we can gain by analyzing the operations and eliminating unnecessary repaints based on dirty rectangles/regions. no blurs - avg 216.0 fps over 3 samples blur the group - avg 22.9 fps over 3 samples blur each txt - avg 3.4 fps over 3 samples * Added the new benchmark to be tracked on the dashboard. --- .../macrobenchmarks/lib/common.dart | 1 + dev/benchmarks/macrobenchmarks/lib/main.dart | 9 ++ .../lib/src/backdrop_filter.dart | 113 ++++++++++++++++++ .../macrobenchmarks/lib/src/cubic_bezier.dart | 6 + .../macrobenchmarks/lib/src/cull_opacity.dart | 6 + .../test_driver/backdrop_filter_perf.dart | 11 ++ .../backdrop_filter_perf_test.dart | 16 +++ ...ackdrop_filter_perf__timeline_summary.dart | 14 +++ dev/devicelab/lib/tasks/perf_tests.dart | 8 ++ dev/devicelab/manifest.yaml | 7 ++ 10 files changed, 191 insertions(+) create mode 100644 dev/benchmarks/macrobenchmarks/lib/src/backdrop_filter.dart create mode 100644 dev/benchmarks/macrobenchmarks/test_driver/backdrop_filter_perf.dart create mode 100644 dev/benchmarks/macrobenchmarks/test_driver/backdrop_filter_perf_test.dart create mode 100644 dev/devicelab/bin/tasks/backdrop_filter_perf__timeline_summary.dart diff --git a/dev/benchmarks/macrobenchmarks/lib/common.dart b/dev/benchmarks/macrobenchmarks/lib/common.dart index 741920d712c..746d824a8b4 100644 --- a/dev/benchmarks/macrobenchmarks/lib/common.dart +++ b/dev/benchmarks/macrobenchmarks/lib/common.dart @@ -4,3 +4,4 @@ const String kCullOpacityRouteName = '/cull_opacity'; const String kCubicBezierRouteName = '/cubic_bezier'; +const String kBackdropFilterRouteName = '/backdrop_filter'; diff --git a/dev/benchmarks/macrobenchmarks/lib/main.dart b/dev/benchmarks/macrobenchmarks/lib/main.dart index 0b89ba0f5eb..5f87dfda45b 100644 --- a/dev/benchmarks/macrobenchmarks/lib/main.dart +++ b/dev/benchmarks/macrobenchmarks/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'common.dart'; +import 'src/backdrop_filter.dart'; import 'src/cubic_bezier.dart'; import 'src/cull_opacity.dart'; @@ -22,6 +23,7 @@ class MacrobenchmarksApp extends StatelessWidget { '/': (BuildContext context) => HomePage(), kCullOpacityRouteName: (BuildContext context) => CullOpacityPage(), kCubicBezierRouteName: (BuildContext context) => CubicBezierPage(), + kBackdropFilterRouteName: (BuildContext context) => BackdropFilterPage(), }, ); } @@ -48,6 +50,13 @@ class HomePage extends StatelessWidget { Navigator.pushNamed(context, kCubicBezierRouteName); }, ), + RaisedButton( + key: const Key(kBackdropFilterRouteName), + child: const Text('Backdrop Filter'), + onPressed: (){ + Navigator.pushNamed(context, kBackdropFilterRouteName); + }, + ), ], ), ); diff --git a/dev/benchmarks/macrobenchmarks/lib/src/backdrop_filter.dart b/dev/benchmarks/macrobenchmarks/lib/src/backdrop_filter.dart new file mode 100644 index 00000000000..5e931171559 --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/lib/src/backdrop_filter.dart @@ -0,0 +1,113 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +class BackdropFilterPage extends StatefulWidget { + @override + _BackdropFilterPageState createState() => _BackdropFilterPageState(); +} + +class _BackdropFilterPageState extends State with TickerProviderStateMixin { + bool _blurGroup = false; + bool _blurTexts = true; + AnimationController animation; + + @override + void initState() { + super.initState(); + animation = AnimationController(vsync: this, duration: const Duration(seconds: 1)); + animation.repeat(); + } + + @override + void dispose() { + animation.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + Widget addBlur(Widget child, bool shouldBlur) { + if (shouldBlur) { + return ClipRect( + child: BackdropFilter( + filter: ImageFilter.blur(sigmaX: 5, sigmaY: 5), + child: child, + ), + ); + } else { + return child; + } + } + + final Widget txt = addBlur(Container( + padding: const EdgeInsets.all(5), + child: const Text('txt'), + ), _blurTexts); + + Widget col(Widget w, int numRows) { + return Column( + children: List.generate(numRows, (int i) => w), + ); + } + + Widget grid(Widget w, int numRows, int numCols) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: List.generate(numCols, (int i) => col(w, numRows)), + ); + } + + return Scaffold( + backgroundColor: Colors.grey, + body: Stack( + children: [ + Text('0' * 10000, style: TextStyle(color: Colors.yellow)), + Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Expanded( + child: RepaintBoundary( + child: Center( + child: AnimatedBuilder( + animation: animation, + builder: (BuildContext c, Widget w) { + final int val = (animation.value * 255).round(); + return Container( + width: 50, + height: 50, + color: Color.fromARGB(255, val, val, val)); + }), + )), + ), + const SizedBox(height: 20), + RepaintBoundary( + child: addBlur(grid(txt, 17, 5), _blurGroup), + ), + const SizedBox(height: 20), + Container( + color: Colors.white, + child:Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text('Backdrop per txt:'), + Checkbox( + value: _blurTexts, + onChanged: (bool v) => setState(() { _blurTexts = v; }), + ), + const SizedBox(width: 10), + const Text('Backdrop grid:'), + Checkbox( + value: _blurGroup, + onChanged: (bool v) => setState(() { _blurGroup = v; }), + ), + ], + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart b/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart index a14b71cda8e..8237d7e40e4 100644 --- a/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart +++ b/dev/benchmarks/macrobenchmarks/lib/src/cubic_bezier.dart @@ -326,6 +326,12 @@ class AnimatedBezierState extends State playAnimation(); } + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return CustomPaint( diff --git a/dev/benchmarks/macrobenchmarks/lib/src/cull_opacity.dart b/dev/benchmarks/macrobenchmarks/lib/src/cull_opacity.dart index c42f2e123d4..6ee3f57a9a1 100644 --- a/dev/benchmarks/macrobenchmarks/lib/src/cull_opacity.dart +++ b/dev/benchmarks/macrobenchmarks/lib/src/cull_opacity.dart @@ -20,6 +20,12 @@ class _CullOpacityPageState extends State with SingleTickerProv _controller.repeat(); } + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { return Stack(children: List.generate(50, (int i) => Positioned( diff --git a/dev/benchmarks/macrobenchmarks/test_driver/backdrop_filter_perf.dart b/dev/benchmarks/macrobenchmarks/test_driver/backdrop_filter_perf.dart new file mode 100644 index 00000000000..80361f37044 --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/test_driver/backdrop_filter_perf.dart @@ -0,0 +1,11 @@ +// Copyright 2019 The Chromium 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_driver/driver_extension.dart'; +import 'package:macrobenchmarks/main.dart' as app; + +void main() { + enableFlutterDriverExtension(); + app.main(); +} diff --git a/dev/benchmarks/macrobenchmarks/test_driver/backdrop_filter_perf_test.dart b/dev/benchmarks/macrobenchmarks/test_driver/backdrop_filter_perf_test.dart new file mode 100644 index 00000000000..8be26c374f4 --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/test_driver/backdrop_filter_perf_test.dart @@ -0,0 +1,16 @@ +// Copyright 2019 The Chromium 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:macrobenchmarks/common.dart'; + +import 'util.dart'; + +void main() { + macroPerfTest( + 'backdrop_filter_perf', + kBackdropFilterRouteName, + pageDelay: const Duration(seconds: 1), + duration: const Duration(seconds: 10), + ); +} diff --git a/dev/devicelab/bin/tasks/backdrop_filter_perf__timeline_summary.dart b/dev/devicelab/bin/tasks/backdrop_filter_perf__timeline_summary.dart new file mode 100644 index 00000000000..4e7a3068779 --- /dev/null +++ b/dev/devicelab/bin/tasks/backdrop_filter_perf__timeline_summary.dart @@ -0,0 +1,14 @@ +// Copyright 2019 The Chromium 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 main() async { + deviceOperatingSystem = DeviceOperatingSystem.android; + await task(createBackdropFilterPerfTest()); +} diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart index 7fa60591be9..c0afb077c0c 100644 --- a/dev/devicelab/lib/tasks/perf_tests.dart +++ b/dev/devicelab/lib/tasks/perf_tests.dart @@ -54,6 +54,14 @@ TaskFunction createCubicBezierPerfTest() { ).run; } +TaskFunction createBackdropFilterPerfTest() { + return PerfTest( + '${flutterDirectory.path}/dev/benchmarks/macrobenchmarks', + 'test_driver/backdrop_filter_perf.dart', + 'backdrop_filter_perf', + ).run; +} + TaskFunction createFlutterGalleryStartupTest() { return StartupTest( '${flutterDirectory.path}/examples/flutter_gallery', diff --git a/dev/devicelab/manifest.yaml b/dev/devicelab/manifest.yaml index f1422622f81..5ecb300791c 100644 --- a/dev/devicelab/manifest.yaml +++ b/dev/devicelab/manifest.yaml @@ -171,6 +171,13 @@ tasks: stage: devicelab required_agent_capabilities: ["mac/android"] + backdrop_filter_perf__timeline_summary: + description: > + Measures the runtime performance of backdrop filter blurs on Android. + stage: devicelab + required_agent_capabilities: ["mac/android"] + flaky: true + flavors_test: description: > Checks that flavored builds work on Android.