diff --git a/.ci.yaml b/.ci.yaml index 2c68e5d5dd..fcf4b37a46 100644 --- a/.ci.yaml +++ b/.ci.yaml @@ -3234,6 +3234,28 @@ targets: ["devicelab", "ios", "mac"] task_name: animated_advanced_blend_perf_ios__timeline_summary + # Uses Impeller. + - name: Linux_pixel_7pro rrect_blur_perf__timeline_summary + recipe: devicelab/devicelab_drone + presubmit: false + bringup: true + timeout: 60 + properties: + ignore_flakiness: "true" + tags: > + ["devicelab", "android", "linux", "pixel", "7pro"] + task_name: rrect_blur_perf__timeline_summary + + - name: Mac_ios rrect_blur_perf_ios__timeline_summary + recipe: devicelab/devicelab_drone + presubmit: false + bringup: true + timeout: 60 + properties: + tags: > + ["devicelab", "ios", "mac"] + task_name: rrect_blur_perf_ios__timeline_summary + # Uses Impeller. - name: Linux_pixel_7pro animated_blur_backdrop_filter_perf_opengles__timeline_summary recipe: devicelab/devicelab_drone diff --git a/TESTOWNERS b/TESTOWNERS index cca4907add..bc6b20234d 100644 --- a/TESTOWNERS +++ b/TESTOWNERS @@ -106,6 +106,7 @@ /dev/devicelab/bin/tasks/dynamic_path_tessellation_perf__timeline_summary.dart @jonahwilliams @flutter/engine /dev/devicelab/bin/tasks/complex_layout_scroll_perf_impeller__timeline_summary.dart @jonahwilliams @flutter/engine /dev/devicelab/bin/tasks/complex_layout_scroll_perf_impeller_gles__timeline_summary.dart @jonahwilliams @flutter/engine +/dev/devicelab/bin/tasks/rrect_blur_perf__timeline_summary.dart @gaaclarke @flutter/engine ## Windows Android DeviceLab tests /dev/devicelab/bin/tasks/basic_material_app_win__compile.dart @zanderso @flutter/tool @@ -223,6 +224,7 @@ /dev/devicelab/bin/tasks/draw_atlas_perf_ios__timeline_summary.dart @jonahwilliams @flutter/engine /dev/devicelab/bin/tasks/static_path_tessellation_perf_ios__timeline_summary.dart @jonahwilliams @flutter/engine /dev/devicelab/bin/tasks/dynamic_path_tessellation_perf_ios__timeline_summary.dart @jonahwilliams @flutter/engine +/dev/devicelab/bin/tasks/rrect_blur_perf_ios__timeline_summary.dart @gaaclarke @flutter/engine ## Host only DeviceLab tests /dev/devicelab/bin/tasks/animated_complex_opacity_perf_macos__e2e_summary.dart @cbracken @flutter/desktop diff --git a/dev/benchmarks/macrobenchmarks/lib/common.dart b/dev/benchmarks/macrobenchmarks/lib/common.dart index 0b4b380799..643ab264b2 100644 --- a/dev/benchmarks/macrobenchmarks/lib/common.dart +++ b/dev/benchmarks/macrobenchmarks/lib/common.dart @@ -41,6 +41,7 @@ const String kDrawPointsPageRougeName = '/draw_points'; const String kDrawVerticesPageRouteName = '/draw_vertices'; const String kDrawAtlasPageRouteName = '/draw_atlas'; const String kAnimatedAdvancedBlend = '/animated_advanced_blend'; +const String kRRectBlurRouteName = '/rrect_blur'; const String kOpacityPeepholeOneRectRouteName = '$kOpacityPeepholeRouteName/one_big_rect'; const String kOpacityPeepholeColumnOfOpacityRouteName = '$kOpacityPeepholeRouteName/column_of_opacity'; diff --git a/dev/benchmarks/macrobenchmarks/lib/main.dart b/dev/benchmarks/macrobenchmarks/lib/main.dart index 23ec7817c4..6d97d592fa 100644 --- a/dev/benchmarks/macrobenchmarks/lib/main.dart +++ b/dev/benchmarks/macrobenchmarks/lib/main.dart @@ -36,6 +36,7 @@ import 'src/picture_cache.dart'; import 'src/picture_cache_complexity_scoring.dart'; import 'src/post_backdrop_filter.dart'; import 'src/raster_cache_use_memory.dart'; +import 'src/rrect_blur.dart' show RRectBlur; import 'src/shader_mask_cache.dart'; import 'src/simple_animation.dart'; import 'src/simple_scroll.dart'; @@ -98,6 +99,7 @@ class MacrobenchmarksApp extends StatelessWidget { kDrawVerticesPageRouteName: (BuildContext context) => const DrawVerticesPage(), kDrawAtlasPageRouteName: (BuildContext context) => const DrawAtlasPage(), kAnimatedAdvancedBlend: (BuildContext context) => const AnimatedAdvancedBlend(), + kRRectBlurRouteName: (BuildContext context) => const RRectBlur(), kVeryLongPictureScrollingRouteName: (BuildContext context) => const VeryLongPictureScrollingPerf(), }, ); @@ -375,6 +377,13 @@ class HomePage extends StatelessWidget { Navigator.pushNamed(context, kAnimatedAdvancedBlend); }, ), + ElevatedButton( + key: const Key(kRRectBlurRouteName), + child: const Text('Rounded Rect Blur'), + onPressed: () { + Navigator.pushNamed(context, kRRectBlurRouteName); + }, + ), ElevatedButton( key: const Key(kVeryLongPictureScrollingRouteName), child: const Text('Very Long Picture Scrolling'), diff --git a/dev/benchmarks/macrobenchmarks/lib/src/rrect_blur.dart b/dev/benchmarks/macrobenchmarks/lib/src/rrect_blur.dart new file mode 100644 index 0000000000..dba0474afc --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/lib/src/rrect_blur.dart @@ -0,0 +1,99 @@ +// 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:math' show cos, sin; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; + +class RRectBlur extends StatefulWidget { + const RRectBlur({super.key}); + + @override + State createState() => _DrawPointsPageState(); +} + +class _DrawPointsPageState extends State + with SingleTickerProviderStateMixin { + late final AnimationController controller; + double tick = 0.0; + + @override + void initState() { + super.initState(); + controller = + AnimationController(vsync: this, duration: const Duration(hours: 1)); + controller.addListener(() { + setState(() { + tick += 1; + }); + }); + controller.forward(from: 0); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return CustomPaint( + size: const Size(500, 500), + painter: PointsPainter(tick), + child: Container(), + ); + } +} + +class PointsPainter extends CustomPainter { + PointsPainter(this.tick); + + final double tick; + + final Float32List data = Float32List(8000); + + static const List kColors = [ + Colors.red, + Colors.blue, + Colors.green, + Colors.yellow, + Colors.orange, + Colors.purple, + Colors.pink, + Colors.deepPurple, + ]; + + @override + void paint(Canvas canvas, Size size) { + if (size.width == 0) { + return; + } + final double halfHeight = size.height / 2.0; + const double freq = 0.25; + for (int i = 0; i < size.width / 10; ++i) { + final double radius = + 25 * cos(i + (1.0 * 2.0 * 3.1415 * tick) / 60.0) + + 25; + final Paint paint = Paint() + ..style = PaintingStyle.fill + ..filterQuality = FilterQuality.low + ..maskFilter = MaskFilter.blur(BlurStyle.normal, radius); + final double yval = + halfHeight * sin(i + (freq * 2.0 * 3.1415 * tick) / 60.0) + + halfHeight; + canvas.drawCircle( + Offset(10.0 * i, yval), + 50, + paint..color = kColors[i % kColors.length], + ); + } + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) { + return true; + } +} diff --git a/dev/benchmarks/macrobenchmarks/test_driver/rrect_blur_perf_test.dart b/dev/benchmarks/macrobenchmarks/test_driver/rrect_blur_perf_test.dart new file mode 100644 index 0000000000..03425e178c --- /dev/null +++ b/dev/benchmarks/macrobenchmarks/test_driver/rrect_blur_perf_test.dart @@ -0,0 +1,16 @@ +// 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() { + macroPerfTest( + 'rrect_blur_perf', + kRRectBlurRouteName, + pageDelay: const Duration(seconds: 1), + duration: const Duration(seconds: 10), + ); +} diff --git a/dev/devicelab/bin/tasks/rrect_blur_perf__timeline_summary.dart b/dev/devicelab/bin/tasks/rrect_blur_perf__timeline_summary.dart new file mode 100644 index 0000000000..41392866f7 --- /dev/null +++ b/dev/devicelab/bin/tasks/rrect_blur_perf__timeline_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(createRRectBlurPerfTest(enableImpeller: true)); +} diff --git a/dev/devicelab/bin/tasks/rrect_blur_perf_ios__timeline_summary.dart b/dev/devicelab/bin/tasks/rrect_blur_perf_ios__timeline_summary.dart new file mode 100644 index 0000000000..bac282e751 --- /dev/null +++ b/dev/devicelab/bin/tasks/rrect_blur_perf_ios__timeline_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.ios; + await task(createRRectBlurPerfTest(enableImpeller: true)); +} diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart index c6d1a2e22a..ba5c92f935 100644 --- a/dev/devicelab/lib/tasks/perf_tests.dart +++ b/dev/devicelab/lib/tasks/perf_tests.dart @@ -666,6 +666,21 @@ TaskFunction createAnimatedAdvancedBlendPerfTest({ ).run; } +TaskFunction createRRectBlurPerfTest({ + bool? enableImpeller, + bool? forceOpenGLES, +}) { + return PerfTest( + '${flutterDirectory.path}/dev/benchmarks/macrobenchmarks', + 'test_driver/run_app.dart', + 'rrect_blur_test', + enableImpeller: enableImpeller, + forceOpenGLES: forceOpenGLES, + testDriver: 'test_driver/rrect_blur_perf_test.dart', + saveTraceFile: true, + ).run; +} + TaskFunction createAnimatedBlurBackropFilterPerfTest({ bool? enableImpeller, bool? forceOpenGLES,