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.
This commit is contained in:
Jim Graham 2019-06-24 20:53:22 -07:00 committed by GitHub
parent d5753ccd91
commit f83fd9d467
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 191 additions and 0 deletions

View file

@ -4,3 +4,4 @@
const String kCullOpacityRouteName = '/cull_opacity';
const String kCubicBezierRouteName = '/cubic_bezier';
const String kBackdropFilterRouteName = '/backdrop_filter';

View file

@ -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);
},
),
],
),
);

View file

@ -0,0 +1,113 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class BackdropFilterPage extends StatefulWidget {
@override
_BackdropFilterPageState createState() => _BackdropFilterPageState();
}
class _BackdropFilterPageState extends State<BackdropFilterPage> 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<Widget>.generate(numRows, (int i) => w),
);
}
Widget grid(Widget w, int numRows, int numCols) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: List<Widget>.generate(numCols, (int i) => col(w, numRows)),
);
}
return Scaffold(
backgroundColor: Colors.grey,
body: Stack(
children: <Widget>[
Text('0' * 10000, style: TextStyle(color: Colors.yellow)),
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
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: <Widget>[
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; }),
),
],
),
),
],
),
],
),
);
}
}

View file

@ -326,6 +326,12 @@ class AnimatedBezierState extends State<AnimatedBezier>
playAnimation();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return CustomPaint(

View file

@ -20,6 +20,12 @@ class _CullOpacityPageState extends State<CullOpacityPage> with SingleTickerProv
_controller.repeat();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Stack(children: List<Widget>.generate(50, (int i) => Positioned(

View file

@ -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();
}

View file

@ -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),
);
}

View file

@ -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<void> main() async {
deviceOperatingSystem = DeviceOperatingSystem.android;
await task(createBackdropFilterPerfTest());
}

View file

@ -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',

View file

@ -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.