mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Memory/cpu/gpu benchmark for showing large images in succession (#64762)
This commit is contained in:
parent
3aa0243ab7
commit
b5ed913ecc
1
dev/benchmarks/macrobenchmarks/.gitignore
vendored
1
dev/benchmarks/macrobenchmarks/.gitignore
vendored
@ -1 +1,2 @@
|
||||
lib/generated_plugin_registrant.dart
|
||||
devtools_memory.json
|
||||
|
@ -8,6 +8,7 @@ const String kBackdropFilterRouteName = '/backdrop_filter';
|
||||
const String kPostBackdropFilterRouteName = '/post_backdrop_filter';
|
||||
const String kSimpleAnimationRouteName = '/simple_animation';
|
||||
const String kPictureCacheRouteName = '/picture_cache';
|
||||
const String kLargeImageChangerRouteName = '/large_image_changer';
|
||||
const String kLargeImagesRouteName = '/large_images';
|
||||
const String kTextRouteName = '/text';
|
||||
const String kAnimatedPlaceholderRouteName = '/animated_placeholder';
|
||||
|
@ -3,18 +3,20 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:macrobenchmarks/src/color_filter_and_fade.dart';
|
||||
import 'package:macrobenchmarks/src/heavy_grid_view.dart';
|
||||
import 'package:macrobenchmarks/src/large_images.dart';
|
||||
import 'package:macrobenchmarks/src/picture_cache.dart';
|
||||
|
||||
import 'common.dart';
|
||||
|
||||
import 'src/animated_placeholder.dart';
|
||||
import 'src/backdrop_filter.dart';
|
||||
import 'src/color_filter_and_fade.dart';
|
||||
import 'src/cubic_bezier.dart';
|
||||
import 'src/cull_opacity.dart';
|
||||
import 'src/filtered_child_animation.dart';
|
||||
import 'src/heavy_grid_view.dart';
|
||||
import 'src/large_image_changer.dart';
|
||||
import 'src/large_images.dart';
|
||||
import 'src/multi_widget_construction.dart';
|
||||
import 'src/picture_cache.dart';
|
||||
import 'src/post_backdrop_filter.dart';
|
||||
import 'src/simple_animation.dart';
|
||||
import 'src/simple_scroll.dart';
|
||||
@ -40,6 +42,7 @@ class MacrobenchmarksApp extends StatelessWidget {
|
||||
kPostBackdropFilterRouteName: (BuildContext context) => PostBackdropFilterPage(),
|
||||
kSimpleAnimationRouteName: (BuildContext context) => SimpleAnimationPage(),
|
||||
kPictureCacheRouteName: (BuildContext context) => PictureCachePage(),
|
||||
kLargeImageChangerRouteName: (BuildContext context) => LargeImageChangerPage(),
|
||||
kLargeImagesRouteName: (BuildContext context) => LargeImagesPage(),
|
||||
kTextRouteName: (BuildContext context) => TextPage(),
|
||||
kAnimatedPlaceholderRouteName: (BuildContext context) => AnimatedPlaceholderPage(),
|
||||
@ -162,6 +165,13 @@ class HomePage extends StatelessWidget {
|
||||
Navigator.pushNamed(context, kHeavyGridViewRouteName);
|
||||
},
|
||||
),
|
||||
RaisedButton(
|
||||
key: const Key(kLargeImageChangerRouteName),
|
||||
child: const Text('Large Image Changer'),
|
||||
onPressed: () {
|
||||
Navigator.pushNamed(context, kLargeImageChangerRouteName);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -0,0 +1,55 @@
|
||||
// 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/material.dart';
|
||||
|
||||
/// Displays a new (from image cache's perspective) large image every 500ms.
|
||||
class LargeImageChangerPage extends StatefulWidget {
|
||||
@override
|
||||
_LargeImageChangerState createState() => _LargeImageChangerState();
|
||||
}
|
||||
|
||||
class _LargeImageChangerState extends State<LargeImageChangerPage> {
|
||||
Timer _timer;
|
||||
int imageIndex = 0;
|
||||
ImageProvider currentImage;
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
currentImage = ResizeImage(
|
||||
const ExactAssetImage('assets/999x1000.png'),
|
||||
width: (MediaQuery.of(context).size.width * 2).toInt() + imageIndex,
|
||||
height: (MediaQuery.of(context).size.height * 2).toInt() + imageIndex,
|
||||
allowUpscaling: true,
|
||||
);
|
||||
_timer?.cancel();
|
||||
_timer = Timer.periodic(const Duration(seconds: 3), (Timer timer) {
|
||||
currentImage.evict().then((_) {
|
||||
setState(() {
|
||||
imageIndex = (imageIndex + 1) % 6;
|
||||
currentImage = ResizeImage(
|
||||
const ExactAssetImage('assets/999x1000.png'),
|
||||
width: (MediaQuery.of(context).size.width * 2).toInt() + imageIndex,
|
||||
height: (MediaQuery.of(context).size.height * 2).toInt() + imageIndex,
|
||||
allowUpscaling: true,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_timer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Image(image: currentImage);
|
||||
}
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
// 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/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_driver/driver_extension.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:macrobenchmarks/common.dart';
|
||||
import 'package:macrobenchmarks/main.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
enableFlutterDriverExtension(handler: (String message) async {
|
||||
if (message == 'getTargetPlatform') {
|
||||
return defaultTargetPlatform.toString();
|
||||
}
|
||||
throw UnsupportedError('Message $message unsupported');
|
||||
});
|
||||
runApp(const MacrobenchmarksApp(initialRoute: kLargeImageChangerRouteName));
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
// 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_driver/flutter_driver.dart';
|
||||
import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
|
||||
|
||||
Future<void> main() async {
|
||||
const String fileName = 'large_image_changer';
|
||||
|
||||
test('Animate for 20 seconds', () async {
|
||||
final FlutterDriver driver = await FlutterDriver.connect();
|
||||
await driver.forceGC();
|
||||
|
||||
final String targetPlatform = await driver.requestData('getTargetPlatform');
|
||||
|
||||
Timeline timeline;
|
||||
switch (targetPlatform) {
|
||||
case 'TargetPlatform.iOS':
|
||||
{
|
||||
timeline = await driver.traceAction(() async {
|
||||
await Future<void>.delayed(const Duration(seconds: 20));
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'TargetPlatorm.android':
|
||||
{
|
||||
// Just run for 20 seconds to collect memory usage. The widget itself
|
||||
// animates during this time.
|
||||
await Future<void>.delayed(const Duration(seconds: 20));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw UnsupportedError('Unsupported platform $targetPlatform');
|
||||
}
|
||||
|
||||
if (timeline != null) {
|
||||
final TimelineSummary summary = TimelineSummary.summarize(timeline);
|
||||
await summary.writeSummaryToFile(fileName, pretty: true);
|
||||
await summary.writeTimelineToFile(fileName, pretty: true);
|
||||
}
|
||||
|
||||
await driver.close();
|
||||
});
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
// 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/adb.dart';
|
||||
import 'package:flutter_devicelab/framework/framework.dart';
|
||||
import 'package:flutter_devicelab/framework/utils.dart';
|
||||
import 'package:flutter_devicelab/tasks/perf_tests.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
deviceOperatingSystem = DeviceOperatingSystem.android;
|
||||
await task(DevToolsMemoryTest(
|
||||
'${flutterDirectory.path}/dev/benchmarks/macrobenchmarks',
|
||||
'test_driver/large_image_changer.dart',
|
||||
).run);
|
||||
}
|
20
dev/devicelab/bin/tasks/large_image_changer_perf_ios.dart
Normal file
20
dev/devicelab/bin/tasks/large_image_changer_perf_ios.dart
Normal file
@ -0,0 +1,20 @@
|
||||
// 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/adb.dart';
|
||||
import 'package:flutter_devicelab/framework/framework.dart';
|
||||
import 'package:flutter_devicelab/framework/utils.dart';
|
||||
import 'package:flutter_devicelab/tasks/perf_tests.dart';
|
||||
|
||||
Future<void> main() async {
|
||||
deviceOperatingSystem = DeviceOperatingSystem.ios;
|
||||
await task(PerfTest(
|
||||
'${flutterDirectory.path}/dev/benchmarks/macrobenchmarks',
|
||||
'test_driver/large_image_changer.dart',
|
||||
'large_image_changer',
|
||||
measureCpuGpu: true,
|
||||
).run);
|
||||
}
|
@ -1125,11 +1125,15 @@ class DevToolsMemoryTest {
|
||||
.listen((String line) {
|
||||
print('run stdout: $line');
|
||||
final RegExpMatch match = RegExp(r'An Observatory debugger and profiler on .+ is available at: ((http|//)[a-zA-Z0-9:/=_\-\.\[\]]+)').firstMatch(line);
|
||||
if (match != null) {
|
||||
if (match != null && !observatoryUri.isCompleted) {
|
||||
observatoryUri.complete(match[1]);
|
||||
_observatoryUri = match[1];
|
||||
}
|
||||
}, onDone: () { observatoryUri.complete(null); });
|
||||
}, onDone: () {
|
||||
if (!observatoryUri.isCompleted) {
|
||||
observatoryUri.complete();
|
||||
}
|
||||
});
|
||||
_forwardStream(_runProcess.stderr, 'run stderr');
|
||||
|
||||
_observatoryUri = await observatoryUri.future;
|
||||
|
@ -867,6 +867,20 @@ tasks:
|
||||
stage: devicelab
|
||||
required_agent_capabilities: ["linux/android"]
|
||||
|
||||
large_image_changer_perf_android:
|
||||
description: >
|
||||
Measures memory usage when rotating through a series of large images.
|
||||
stage: devicelab
|
||||
required_agent_capabilities: ["linux/android"]
|
||||
flaky: true
|
||||
|
||||
large_image_changer_perf_ios:
|
||||
description: >
|
||||
Measures memory, cpu, and gpu usage when rotating through a series of large images.
|
||||
stage: devicelab
|
||||
required_agent_capabilities: ["mac/ios"]
|
||||
flaky: true
|
||||
|
||||
animated_placeholder_perf:
|
||||
description: >
|
||||
Measures frame build and rasterizer times, as well as frame build counts
|
||||
|
Loading…
Reference in New Issue
Block a user