From 9c934041bdbe18cdd24ac1ac41d16f79840d45c9 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Thu, 27 Jan 2022 13:25:17 -0800 Subject: [PATCH] Add benchmarks to measure impact of alpha saveLayers in DisplayLists (#97336) --- .ci.yaml | 22 +++ TESTOWNERS | 2 + .../macrobenchmarks/lib/common.dart | 3 + .../lib/src/opacity_peephole.dart | 127 ++++++++++++++++++ ..._col_of_alpha_savelayer_rows_perf_e2e.dart | 19 +++ ...ole_grid_of_alpha_savelayers_perf_e2e.dart | 19 +++ ...lpha_savelayer_rows_perf__e2e_summary.dart | 14 ++ ...of_alpha_savelayers_perf__e2e_summary.dart | 14 ++ dev/devicelab/lib/tasks/perf_tests.dart | 14 ++ 9 files changed, 234 insertions(+) create mode 100644 dev/benchmarks/macrobenchmarks/test/opacity_peephole_col_of_alpha_savelayer_rows_perf_e2e.dart create mode 100644 dev/benchmarks/macrobenchmarks/test/opacity_peephole_grid_of_alpha_savelayers_perf_e2e.dart create mode 100644 dev/devicelab/bin/tasks/opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary.dart create mode 100644 dev/devicelab/bin/tasks/opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary.dart diff --git a/.ci.yaml b/.ci.yaml index 36cb6170d9..5d40ec5bcc 100755 --- a/.ci.yaml +++ b/.ci.yaml @@ -2282,6 +2282,28 @@ targets: task_name: opacity_peephole_fade_transition_text_perf__e2e_summary scheduler: luci + - name: Linux_android opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary + bringup: true + recipe: devicelab/devicelab_drone + presubmit: false + timeout: 60 + properties: + tags: > + ["devicelab","android","linux"] + task_name: opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary + scheduler: luci + + - name: Linux_android opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary + bringup: true + recipe: devicelab/devicelab_drone + presubmit: false + timeout: 60 + properties: + tags: > + ["devicelab","android","linux"] + task_name: opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary + scheduler: luci + - name: Mac build_aar_module_test recipe: devicelab/devicelab_drone timeout: 60 diff --git a/TESTOWNERS b/TESTOWNERS index f815ee23b3..f6e0b858af 100644 --- a/TESTOWNERS +++ b/TESTOWNERS @@ -66,6 +66,8 @@ /dev/devicelab/bin/tasks/opacity_peephole_one_rect_perf__e2e_summary.dart @flar @flutter/engine /dev/devicelab/bin/tasks/opacity_peephole_opacity_of_grid_perf__e2e_summary.dart @flar @flutter/engine /dev/devicelab/bin/tasks/opacity_peephole_fade_transition_text_perf__e2e_summary.dart @flar @flutter/engine +/dev/devicelab/bin/tasks/opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary.dart @flar @flutter/engine +/dev/devicelab/bin/tasks/opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary.dart @flar @flutter/engine ## Windows Android DeviceLab tests /dev/devicelab/bin/tasks/basic_material_app_win__compile.dart @zanderso @flutter/tool diff --git a/dev/benchmarks/macrobenchmarks/lib/common.dart b/dev/benchmarks/macrobenchmarks/lib/common.dart index aec0147c68..0fded346da 100644 --- a/dev/benchmarks/macrobenchmarks/lib/common.dart +++ b/dev/benchmarks/macrobenchmarks/lib/common.dart @@ -32,6 +32,9 @@ const String kOpacityPeepholeGridOfOpacityRouteName = '$kOpacityPeepholeRouteNam const String kOpacityPeepholeOpacityOfGridRouteName = '$kOpacityPeepholeRouteName/opacity_of_grid'; const String kOpacityPeepholeOpacityOfColOfRowsRouteName = '$kOpacityPeepholeRouteName/opacity_of_col_of_rows'; const String kOpacityPeepholeFadeTransitionTextRouteName = '$kOpacityPeepholeRouteName/fade_transition_text'; +const String kOpacityPeepholeGridOfRectsWithAlphaRouteName = '$kOpacityPeepholeRouteName/grid_of_rects_with_alpha'; +const String kOpacityPeepholeGridOfAlphaSaveLayerRectsRouteName = '$kOpacityPeepholeRouteName/grid_of_alpha_savelayer_rects'; +const String kOpacityPeepholeColumnOfAlphaSaveLayerRowsOfRectsRouteName = '$kOpacityPeepholeRouteName/column_of_alpha_save_layer_rows_of_rects'; const String kScrollableName = '/macrobenchmark_listview'; const String kOpacityScrollableName = '$kOpacityPeepholeRouteName/listview'; diff --git a/dev/benchmarks/macrobenchmarks/lib/src/opacity_peephole.dart b/dev/benchmarks/macrobenchmarks/lib/src/opacity_peephole.dart index 19001375d0..46e5095455 100644 --- a/dev/benchmarks/macrobenchmarks/lib/src/opacity_peephole.dart +++ b/dev/benchmarks/macrobenchmarks/lib/src/opacity_peephole.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:math'; + import 'package:flutter/material.dart'; import '../common.dart'; @@ -284,8 +286,133 @@ List allOpacityPeepholeCases = [ ); }, ), + OpacityPeepholeCase.forValue( + route: kOpacityPeepholeGridOfRectsWithAlphaRouteName, + name: 'Grid of Rectangles with alpha', + builder: (double v) { + return Opacity( + opacity: _opacity(v), + child: SizedBox.expand( + child: CustomPaint( + painter: RectGridPainter((Canvas canvas, Size size) { + const int numRows = 10; + const int numCols = 7; + const double rectWidth = 30; + const double rectHeight = 30; + final double hGap = (size.width - numCols * rectWidth) / (numCols + 1); + final double vGap = (size.height - numRows * rectHeight) / (numRows + 1); + final double gap = min(hGap, vGap); + final double xOffset = (size.width - (numCols * (rectWidth + gap) - gap)) * 0.5; + final double yOffset = (size.height - (numRows * (rectHeight + gap) - gap)) * 0.5; + final Paint rectPaint = Paint(); + for (int r = 0; r < numRows; r++, v = 1 - v) { + final double y = yOffset + r * (rectHeight + gap); + double cv = v; + for (int c = 0; c < numCols; c++, cv = 1 - cv) { + final double x = xOffset + c * (rectWidth + gap); + rectPaint.color = Color.fromRGBO(_red(cv), _green(cv), _blue(cv), _opacity(cv)); + final Rect rect = Rect.fromLTWH(x, y, rectWidth, rectHeight); + canvas.drawRect(rect, rectPaint); + } + } + }), + ), + ), + ); + }, + ), + OpacityPeepholeCase.forValue( + route: kOpacityPeepholeGridOfAlphaSaveLayerRectsRouteName, + name: 'Grid of alpha SaveLayers of Rectangles', + builder: (double v) { + return Opacity( + opacity: _opacity(v), + child: SizedBox.expand( + child: CustomPaint( + painter: RectGridPainter((Canvas canvas, Size size) { + const int numRows = 10; + const int numCols = 7; + const double rectWidth = 30; + const double rectHeight = 30; + final double hGap = (size.width - numCols * rectWidth) / (numCols + 1); + final double vGap = (size.height - numRows * rectHeight) / (numRows + 1); + final double gap = min(hGap, vGap); + final double xOffset = (size.width - (numCols * (rectWidth + gap) - gap)) * 0.5; + final double yOffset = (size.height - (numRows * (rectHeight + gap) - gap)) * 0.5; + final Paint rectPaint = Paint(); + final Paint layerPaint = Paint(); + for (int r = 0; r < numRows; r++, v = 1 - v) { + final double y = yOffset + r * (rectHeight + gap); + double cv = v; + for (int c = 0; c < numCols; c++, cv = 1 - cv) { + final double x = xOffset + c * (rectWidth + gap); + rectPaint.color = Color.fromRGBO(_red(cv), _green(cv), _blue(cv), 1.0); + layerPaint.color = Color.fromRGBO(255, 255, 255, _opacity(cv)); + final Rect rect = Rect.fromLTWH(x, y, rectWidth, rectHeight); + canvas.saveLayer(null, layerPaint); + canvas.drawRect(rect, rectPaint); + canvas.restore(); + } + } + }), + ), + ), + ); + }, + ), + OpacityPeepholeCase.forValue( + route: kOpacityPeepholeColumnOfAlphaSaveLayerRowsOfRectsRouteName, + name: 'Grid with alpha SaveLayer on Rows', + builder: (double v) { + return Opacity( + opacity: _opacity(v), + child: SizedBox.expand( + child: CustomPaint( + painter: RectGridPainter((Canvas canvas, Size size) { + const int numRows = 10; + const int numCols = 7; + const double rectWidth = 30; + const double rectHeight = 30; + final double hGap = (size.width - numCols * rectWidth) / (numCols + 1); + final double vGap = (size.height - numRows * rectHeight) / (numRows + 1); + final double gap = min(hGap, vGap); + final double xOffset = (size.width - (numCols * (rectWidth + gap) - gap)) * 0.5; + final double yOffset = (size.height - (numRows * (rectHeight + gap) - gap)) * 0.5; + final Paint rectPaint = Paint(); + final Paint layerPaint = Paint(); + for (int r = 0; r < numRows; r++, v = 1 - v) { + final double y = yOffset + r * (rectHeight + gap); + layerPaint.color = Color.fromRGBO(255, 255, 255, _opacity(v)); + canvas.saveLayer(null, layerPaint); + double cv = v; + for (int c = 0; c < numCols; c++, cv = 1 - cv) { + final double x = xOffset + c * (rectWidth + gap); + rectPaint.color = Color.fromRGBO(_red(cv), _green(cv), _blue(cv), 1.0); + final Rect rect = Rect.fromLTWH(x, y, rectWidth, rectHeight); + canvas.drawRect(rect, rectPaint); + } + canvas.restore(); + } + }), + ), + ), + ); + }, + ), ]; +class RectGridPainter extends CustomPainter { + RectGridPainter(this.painter); + + final void Function(Canvas canvas, Size size) painter; + + @override + void paint(Canvas canvas, Size size) => painter(canvas, size); + + @override + bool shouldRepaint(CustomPainter oldDelegate) => true; +} + Map opacityPeepholeRoutes = { for (OpacityPeepholeCase variant in allOpacityPeepholeCases) variant.route: variant.buildPage, diff --git a/dev/benchmarks/macrobenchmarks/test/opacity_peephole_col_of_alpha_savelayer_rows_perf_e2e.dart b/dev/benchmarks/macrobenchmarks/test/opacity_peephole_col_of_alpha_savelayer_rows_perf_e2e.dart new file mode 100644 index 0000000000..1b2071beb0 --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/test/opacity_peephole_col_of_alpha_savelayer_rows_perf_e2e.dart @@ -0,0 +1,19 @@ +// 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:macrobenchmarks/common.dart'; + +import 'util.dart'; + +void main() { + macroPerfTestMultiPageE2E( + 'opacity_peephole_col_of_alpha_save_layer_rows', + [ + ScrollableButtonRoute(kScrollableName, kOpacityPeepholeRouteName), + ScrollableButtonRoute(kOpacityScrollableName, kOpacityPeepholeColumnOfAlphaSaveLayerRowsOfRectsRouteName), + ], + pageDelay: const Duration(seconds: 1), + duration: const Duration(seconds: 10), + ); +} diff --git a/dev/benchmarks/macrobenchmarks/test/opacity_peephole_grid_of_alpha_savelayers_perf_e2e.dart b/dev/benchmarks/macrobenchmarks/test/opacity_peephole_grid_of_alpha_savelayers_perf_e2e.dart new file mode 100644 index 0000000000..c0efba7c1c --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/test/opacity_peephole_grid_of_alpha_savelayers_perf_e2e.dart @@ -0,0 +1,19 @@ +// 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:macrobenchmarks/common.dart'; + +import 'util.dart'; + +void main() { + macroPerfTestMultiPageE2E( + 'opacity_peephole_grid_of_alpha_savelayers', + [ + ScrollableButtonRoute(kScrollableName, kOpacityPeepholeRouteName), + ScrollableButtonRoute(kOpacityScrollableName, kOpacityPeepholeGridOfAlphaSaveLayerRectsRouteName), + ], + pageDelay: const Duration(seconds: 1), + duration: const Duration(seconds: 10), + ); +} diff --git a/dev/devicelab/bin/tasks/opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary.dart b/dev/devicelab/bin/tasks/opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary.dart new file mode 100644 index 0000000000..a50531f27b --- /dev/null +++ b/dev/devicelab/bin/tasks/opacity_peephole_col_of_alpha_savelayer_rows_perf__e2e_summary.dart @@ -0,0 +1,14 @@ +// 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/framework/devices.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/tasks/perf_tests.dart'; + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.android; + await task(createOpacityPeepholeColOfAlphaSaveLayerRowsPerfE2ETest()); +} diff --git a/dev/devicelab/bin/tasks/opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary.dart b/dev/devicelab/bin/tasks/opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary.dart new file mode 100644 index 0000000000..eb3e46db34 --- /dev/null +++ b/dev/devicelab/bin/tasks/opacity_peephole_grid_of_alpha_savelayers_perf__e2e_summary.dart @@ -0,0 +1,14 @@ +// 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/framework/devices.dart'; +import 'package:flutter_devicelab/framework/framework.dart'; +import 'package:flutter_devicelab/tasks/perf_tests.dart'; + +Future main() async { + deviceOperatingSystem = DeviceOperatingSystem.android; + await task(createOpacityPeepholeGridOfAlphaSaveLayersPerfE2ETest()); +} diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart index 306464e562..d8f95f5549 100644 --- a/dev/devicelab/lib/tasks/perf_tests.dart +++ b/dev/devicelab/lib/tasks/perf_tests.dart @@ -519,6 +519,20 @@ TaskFunction createOpacityPeepholeFadeTransitionTextPerfE2ETest() { ).run; } +TaskFunction createOpacityPeepholeGridOfAlphaSaveLayersPerfE2ETest() { + return PerfTest.e2e( + '${flutterDirectory.path}/dev/benchmarks/macrobenchmarks', + 'test/opacity_peephole_grid_of_alpha_savelayers_perf_e2e.dart', + ).run; +} + +TaskFunction createOpacityPeepholeColOfAlphaSaveLayerRowsPerfE2ETest() { + return PerfTest.e2e( + '${flutterDirectory.path}/dev/benchmarks/macrobenchmarks', + 'test/opacity_peephole_col_of_alpha_savelayer_rows_perf_e2e.dart', + ).run; +} + Map _average(List> results, int iterations) { final Map tally = {}; for (final Map item in results) {