mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
165 lines
5 KiB
Dart
165 lines
5 KiB
Dart
// Copyright 2017 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/material.dart';
|
|
import 'package:flutter/scheduler.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_driver/driver_extension.dart';
|
|
|
|
void main() {
|
|
enableFlutterDriverExtension();
|
|
debugPrint('Application starting...');
|
|
runApp(MyApp());
|
|
}
|
|
|
|
class MyApp extends StatefulWidget {
|
|
@override
|
|
State createState() => MyAppState();
|
|
}
|
|
|
|
const MethodChannel channel = MethodChannel('texture');
|
|
|
|
enum FrameState { initial, slow, afterSlow, fast, afterFast }
|
|
|
|
class MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
|
|
int _widgetBuilds = 0;
|
|
FrameState _state;
|
|
String _summary = '';
|
|
IconData _icon;
|
|
double _flutterFrameRate;
|
|
|
|
Future<void> _summarizeStats() async {
|
|
final double framesProduced = await channel.invokeMethod('getProducedFrameRate');
|
|
final double framesConsumed = await channel.invokeMethod('getConsumedFrameRate');
|
|
_summary = '''
|
|
Produced: ${framesProduced.toStringAsFixed(1)}fps
|
|
Consumed: ${framesConsumed.toStringAsFixed(1)}fps
|
|
Widget builds: $_widgetBuilds''';
|
|
}
|
|
|
|
Future<void> _nextState() async {
|
|
switch (_state) {
|
|
case FrameState.initial:
|
|
debugPrint('Starting .5x speed test...');
|
|
_widgetBuilds = 0;
|
|
_summary = 'Producing texture frames at .5x speed...';
|
|
_state = FrameState.slow;
|
|
_icon = Icons.stop;
|
|
channel.invokeMethod<void>('start', _flutterFrameRate ~/ 2);
|
|
break;
|
|
case FrameState.slow:
|
|
debugPrint('Stopping .5x speed test...');
|
|
await channel.invokeMethod<void>('stop');
|
|
await _summarizeStats();
|
|
_icon = Icons.fast_forward;
|
|
_state = FrameState.afterSlow;
|
|
break;
|
|
case FrameState.afterSlow:
|
|
debugPrint('Starting 2x speed test...');
|
|
_widgetBuilds = 0;
|
|
_summary = 'Producing texture frames at 2x speed...';
|
|
_state = FrameState.fast;
|
|
_icon = Icons.stop;
|
|
channel.invokeMethod<void>('start', (_flutterFrameRate * 2).toInt());
|
|
break;
|
|
case FrameState.fast:
|
|
debugPrint('Stopping 2x speed test...');
|
|
await channel.invokeMethod<void>('stop');
|
|
await _summarizeStats();
|
|
_state = FrameState.afterFast;
|
|
_icon = Icons.replay;
|
|
break;
|
|
case FrameState.afterFast:
|
|
debugPrint('Test complete.');
|
|
_summary = 'Press play to start again';
|
|
_state = FrameState.initial;
|
|
_icon = Icons.play_arrow;
|
|
break;
|
|
}
|
|
setState(() {});
|
|
}
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_calibrate();
|
|
}
|
|
|
|
static const int calibrationTickCount = 600;
|
|
|
|
/// Measures Flutter's frame rate.
|
|
Future<void> _calibrate() async {
|
|
debugPrint('Awaiting calm (3 second pause)...');
|
|
await Future<void>.delayed(const Duration(milliseconds: 3000));
|
|
debugPrint('Calibrating...');
|
|
DateTime startTime;
|
|
int tickCount = 0;
|
|
Ticker ticker;
|
|
ticker = createTicker((Duration time) {
|
|
tickCount += 1;
|
|
if (tickCount == calibrationTickCount) { // about 10 seconds
|
|
final Duration elapsed = DateTime.now().difference(startTime);
|
|
ticker.stop();
|
|
ticker.dispose();
|
|
setState(() {
|
|
_flutterFrameRate = tickCount * 1000 / elapsed.inMilliseconds;
|
|
debugPrint('Calibrated: frame rate ${_flutterFrameRate.toStringAsFixed(1)}fps.');
|
|
_summary = '''
|
|
Flutter frame rate is ${_flutterFrameRate.toStringAsFixed(1)}fps.
|
|
Press play to produce texture frames.''';
|
|
_icon = Icons.play_arrow;
|
|
_state = FrameState.initial;
|
|
});
|
|
} else {
|
|
if ((tickCount % (calibrationTickCount ~/ 20)) == 0)
|
|
debugPrint('Calibrating... ${(100.0 * tickCount / calibrationTickCount).floor()}%');
|
|
}
|
|
});
|
|
ticker.start();
|
|
startTime = DateTime.now();
|
|
setState(() {
|
|
_summary = 'Calibrating...';
|
|
_icon = null;
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
_widgetBuilds += 1;
|
|
return MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
Container(
|
|
width: 300.0,
|
|
height: 200.0,
|
|
child: const Texture(textureId: 0),
|
|
),
|
|
Container(
|
|
width: 300.0,
|
|
height: 60.0,
|
|
color: Colors.grey,
|
|
child: Center(
|
|
child: Text(
|
|
_summary,
|
|
key: const ValueKey<String>('summary'),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
floatingActionButton: _icon == null ? null : FloatingActionButton(
|
|
key: const ValueKey<String>('fab'),
|
|
child: Icon(_icon),
|
|
onPressed: _nextState,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|