mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
This reverts commit 68fc7231b3
.
This commit is contained in:
parent
d39aad734f
commit
3068fc4f7c
@ -13,9 +13,6 @@ void main() {
|
||||
|
||||
setUpAll(() async {
|
||||
driver = await FlutterDriver.connect();
|
||||
|
||||
// TODO(liyuqian): enable the following once it's proved to be non-flaky by transition_perf_test.dart.
|
||||
// await driver.waitUntilFirstFrameRasterized();
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
|
@ -159,7 +159,6 @@ class StartupTest {
|
||||
|
||||
return TaskResult.success(data, benchmarkScoreKeys: <String>[
|
||||
'timeToFirstFrameMicros',
|
||||
'timeToFirstFrameRasterizedMicros',
|
||||
]);
|
||||
});
|
||||
}
|
||||
|
@ -251,7 +251,6 @@ tasks:
|
||||
description: >
|
||||
Measures the startup time of the Complex Layout sample app on Android.
|
||||
stage: devicelab
|
||||
flaky: true
|
||||
required_agent_capabilities: ["mac/android"]
|
||||
|
||||
hot_mode_dev_cycle__benchmark:
|
||||
@ -449,14 +448,12 @@ tasks:
|
||||
description: >
|
||||
Measures the startup time of the Flutter Gallery app on iPhone 6.
|
||||
stage: devicelab_ios
|
||||
flaky: true
|
||||
required_agent_capabilities: ["mac/ios"]
|
||||
|
||||
complex_layout_ios__start_up:
|
||||
description: >
|
||||
Measures the startup time of the Complex Layout sample app on iPhone 6.
|
||||
stage: devicelab_ios
|
||||
flaky: true
|
||||
required_agent_capabilities: ["mac/ios"]
|
||||
|
||||
flutter_gallery_ios__transition_perf:
|
||||
@ -464,7 +461,6 @@ tasks:
|
||||
Measures the performance of screen transitions in Flutter Gallery on
|
||||
iOS.
|
||||
stage: devicelab_ios
|
||||
flaky: true
|
||||
required_agent_capabilities: ["mac/ios"]
|
||||
|
||||
hello_world_ios__compile:
|
||||
@ -569,7 +565,6 @@ tasks:
|
||||
description: >
|
||||
Measures the startup time of the Flutter Gallery app on Android.
|
||||
stage: devicelab
|
||||
flaky: true
|
||||
required_agent_capabilities: ["linux/android"]
|
||||
|
||||
flutter_gallery__transition_perf:
|
||||
@ -577,7 +572,6 @@ tasks:
|
||||
Measures the performance of screen transitions in Flutter Gallery on
|
||||
Android.
|
||||
stage: devicelab
|
||||
flaky: true
|
||||
required_agent_capabilities: ["linux/android"]
|
||||
|
||||
flutter_gallery__transition_perf_with_semantics:
|
||||
@ -585,7 +579,6 @@ tasks:
|
||||
Measures the delta in performance of screen transitions without and
|
||||
with semantics enabled.
|
||||
stage: devicelab
|
||||
flaky: true
|
||||
required_agent_capabilities: ["linux/android"]
|
||||
|
||||
flutter_gallery__memory_nav:
|
||||
@ -624,7 +617,6 @@ tasks:
|
||||
description: >
|
||||
Measures the startup time of the Flutter Gallery app on 32-bit iOS (iPhone 4S).
|
||||
stage: devicelab_ios
|
||||
flaky: true
|
||||
required_agent_capabilities: ["mac/ios32"]
|
||||
|
||||
flutter_gallery_ios32__transition_perf:
|
||||
@ -632,7 +624,6 @@ tasks:
|
||||
Measures the performance of screen transitions in Flutter Gallery on
|
||||
32-bit iOS (iPhone 4S).
|
||||
stage: devicelab_ios
|
||||
flaky: true
|
||||
required_agent_capabilities: ["mac/ios32"]
|
||||
|
||||
run_without_leak_mac:
|
||||
|
@ -13,9 +13,6 @@ void main() {
|
||||
|
||||
setUpAll(() async {
|
||||
driver = await FlutterDriver.connect();
|
||||
|
||||
// TODO(liyuqian): enable the following once it's proved to be non-flaky by transition_perf_test.dart.
|
||||
// await driver.waitUntilFirstFrameRasterized();
|
||||
});
|
||||
|
||||
tearDownAll(() async {
|
||||
|
@ -183,9 +183,6 @@ void main([List<String> args = const <String>[]]) {
|
||||
setUpAll(() async {
|
||||
driver = await FlutterDriver.connect();
|
||||
|
||||
// Wait for the first frame to be rasterized.
|
||||
await driver.waitUntilFirstFrameRasterized();
|
||||
|
||||
if (args.contains('--with_semantics')) {
|
||||
print('Enabeling semantics...');
|
||||
await driver.setSemantics(true);
|
||||
@ -203,6 +200,7 @@ void main([List<String> args = const <String>[]]) {
|
||||
});
|
||||
|
||||
test('all demos', () async {
|
||||
|
||||
// Collect timeline data for just a limited set of demos to avoid OOMs.
|
||||
final Timeline timeline = await driver.traceAction(
|
||||
() async {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:developer' as developer;
|
||||
import 'dart:ui' show AppLifecycleState, Locale, AccessibilityFeatures, FrameTiming, TimingsCallback;
|
||||
import 'dart:ui' show AppLifecycleState, Locale, AccessibilityFeatures;
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
@ -550,14 +550,6 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
|
||||
int _deferFirstFrameReportCount = 0;
|
||||
bool get _reportFirstFrame => _deferFirstFrameReportCount == 0;
|
||||
|
||||
|
||||
final Completer<void> _firstFrameCompleter = Completer<void>();
|
||||
|
||||
/// Whether the Flutter engine has rasterized the first frame.
|
||||
///
|
||||
/// {@macro flutter.frame_rasterized_vs_presented}
|
||||
Future<void> get firstFrameRasterized => _firstFrameCompleter.future;
|
||||
|
||||
/// Whether the first frame has finished rendering.
|
||||
///
|
||||
/// Only useful in profile and debug builds; in release builds, this always
|
||||
@ -704,24 +696,6 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
|
||||
debugBuildingDirtyElements = true;
|
||||
return true;
|
||||
}());
|
||||
|
||||
if (_needToReportFirstFrame && _reportFirstFrame) {
|
||||
assert(!_firstFrameCompleter.isCompleted);
|
||||
// TODO(liyuqian): use a broadcast stream approach
|
||||
final TimingsCallback oldCallback = WidgetsBinding.instance.window.onReportTimings;
|
||||
WidgetsBinding.instance.window.onReportTimings = (List<FrameTiming> timings) {
|
||||
if (!kReleaseMode) {
|
||||
developer.Timeline.instantSync('Rasterized first useful frame');
|
||||
developer.postEvent('Flutter.FirstFrame', <String, dynamic>{});
|
||||
}
|
||||
if (oldCallback != null) {
|
||||
oldCallback(timings);
|
||||
}
|
||||
WidgetsBinding.instance.window.onReportTimings = oldCallback;
|
||||
_firstFrameCompleter.complete();
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
if (renderViewElement != null)
|
||||
buildOwner.buildScope(renderViewElement);
|
||||
@ -735,11 +709,12 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
|
||||
}
|
||||
if (!kReleaseMode) {
|
||||
if (_needToReportFirstFrame && _reportFirstFrame) {
|
||||
developer.Timeline.instantSync('Widgets built first useful frame');
|
||||
}
|
||||
}
|
||||
developer.Timeline.instantSync('Widgets completed first useful frame');
|
||||
developer.postEvent('Flutter.FirstFrame', <String, dynamic>{});
|
||||
_needToReportFirstFrame = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The [Element] that is at the root of the hierarchy (and which wraps the
|
||||
/// [RenderView] object at the root of the rendering hierarchy).
|
||||
|
@ -79,8 +79,6 @@ class TestServiceExtensionsBinding extends BindingBase
|
||||
await flushMicrotasks();
|
||||
if (ui.window.onDrawFrame != null)
|
||||
ui.window.onDrawFrame();
|
||||
if (ui.window.onReportTimings != null)
|
||||
ui.window.onReportTimings(<ui.FrameTiming>[]);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -132,26 +132,6 @@ class WaitUntilNoPendingFrame extends Command {
|
||||
String get kind => 'waitUntilNoPendingFrame';
|
||||
}
|
||||
|
||||
/// A Flutter Driver command that waits until the Flutter engine rasterizes the
|
||||
/// first frame.
|
||||
///
|
||||
/// {@template flutter.frame_rasterized_vs_presented}
|
||||
/// Usually, the time that a frame is rasterized is very close to the time that
|
||||
/// it gets presented on the display. Specifically, rasterization is the last
|
||||
/// expensive phase of a frame that's still in Flutter's control.
|
||||
/// {@endtemplate}
|
||||
class WaitUntilFirstFrameRasterized extends Command {
|
||||
/// Creates this command.
|
||||
const WaitUntilFirstFrameRasterized({ Duration timeout }) : super(timeout: timeout);
|
||||
|
||||
/// Deserializes this command from the value generated by [serialize].
|
||||
WaitUntilFirstFrameRasterized.deserialize(Map<String, String> json)
|
||||
: super.deserialize(json);
|
||||
|
||||
@override
|
||||
String get kind => 'waitUntilFirstFrameRasterized';
|
||||
}
|
||||
|
||||
/// Base class for Flutter Driver finders, objects that describe how the driver
|
||||
/// should search for elements.
|
||||
abstract class SerializableFinder {
|
||||
|
@ -499,14 +499,6 @@ class FlutterDriver {
|
||||
await _sendCommand(WaitUntilNoTransientCallbacks(timeout: timeout));
|
||||
}
|
||||
|
||||
/// Waits until the next [Window.onReportTimings] is called.
|
||||
///
|
||||
/// Use this method to wait for the first frame to be rasterized during the
|
||||
/// app launch.
|
||||
Future<void> waitUntilFirstFrameRasterized() async {
|
||||
await _sendCommand(const WaitUntilFirstFrameRasterized());
|
||||
}
|
||||
|
||||
Future<DriverOffset> _getOffset(SerializableFinder finder, OffsetType type, { Duration timeout }) async {
|
||||
final GetOffset command = GetOffset(finder, type, timeout: timeout);
|
||||
final GetOffsetResult result = GetOffsetResult.fromJson(await _sendCommand(command));
|
||||
|
@ -114,7 +114,6 @@ class FlutterDriverExtension {
|
||||
'waitForAbsent': _waitForAbsent,
|
||||
'waitUntilNoTransientCallbacks': _waitUntilNoTransientCallbacks,
|
||||
'waitUntilNoPendingFrame': _waitUntilNoPendingFrame,
|
||||
'waitUntilFirstFrameRasterized': _waitUntilFirstFrameRasterized,
|
||||
'get_semantics_id': _getSemanticsId,
|
||||
'get_offset': _getOffset,
|
||||
'get_diagnostics_tree': _getDiagnosticsTree,
|
||||
@ -136,7 +135,6 @@ class FlutterDriverExtension {
|
||||
'waitForAbsent': (Map<String, String> params) => WaitForAbsent.deserialize(params),
|
||||
'waitUntilNoTransientCallbacks': (Map<String, String> params) => WaitUntilNoTransientCallbacks.deserialize(params),
|
||||
'waitUntilNoPendingFrame': (Map<String, String> params) => WaitUntilNoPendingFrame.deserialize(params),
|
||||
'waitUntilFirstFrameRasterized': (Map<String, String> params) => WaitUntilFirstFrameRasterized.deserialize(params),
|
||||
'get_semantics_id': (Map<String, String> params) => GetSemanticsId.deserialize(params),
|
||||
'get_offset': (Map<String, String> params) => GetOffset.deserialize(params),
|
||||
'get_diagnostics_tree': (Map<String, String> params) => GetDiagnosticsTree.deserialize(params),
|
||||
@ -222,12 +220,6 @@ class FlutterDriverExtension {
|
||||
return RenderTree(RendererBinding.instance?.renderView?.toStringDeep());
|
||||
}
|
||||
|
||||
// This can be used to wait for the first frame being rasterized during app launch.
|
||||
Future<Result> _waitUntilFirstFrameRasterized(Command command) async {
|
||||
await WidgetsBinding.instance.firstFrameRasterized;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Waits until at the end of a frame the provided [condition] is [true].
|
||||
Future<void> _waitUntilFrame(bool condition(), [ Completer<void> completer ]) {
|
||||
completer ??= Completer<void>();
|
||||
|
@ -14,13 +14,12 @@ import 'vmservice.dart';
|
||||
// Names of some of the Timeline events we care about.
|
||||
const String _kFlutterEngineMainEnterEventName = 'FlutterEngineMainEnter';
|
||||
const String _kFrameworkInitEventName = 'Framework initialization';
|
||||
const String _kFirstFrameBuiltEventName = 'Widgets built first useful frame';
|
||||
const String _kFirstFrameRasterizedEventName = 'Rasterized first useful frame';
|
||||
const String _kFirstUsefulFrameEventName = 'Widgets completed first useful frame';
|
||||
|
||||
class Tracing {
|
||||
Tracing(this.vmService);
|
||||
|
||||
static const String firstUsefulFrameEventName = _kFirstFrameRasterizedEventName;
|
||||
static const String firstUsefulFrameEventName = _kFirstUsefulFrameEventName;
|
||||
|
||||
static Future<Tracing> connect(Uri uri) async {
|
||||
final VMService observatory = await VMService.connect(uri);
|
||||
@ -48,7 +47,7 @@ class Tracing {
|
||||
(await vmService.onTimelineEvent).listen((ServiceEvent timelineEvent) {
|
||||
final List<Map<String, dynamic>> events = timelineEvent.timelineEvents;
|
||||
for (Map<String, dynamic> event in events) {
|
||||
if (event['name'] == firstUsefulFrameEventName)
|
||||
if (event['name'] == _kFirstUsefulFrameEventName)
|
||||
whenFirstFrameRendered.complete();
|
||||
}
|
||||
});
|
||||
@ -123,23 +122,16 @@ Future<void> downloadStartupTrace(VMService observatory, { bool awaitFirstFrame
|
||||
}
|
||||
|
||||
if (awaitFirstFrame) {
|
||||
final int firstFrameBuiltTimestampMicros = extractInstantEventTimestamp(_kFirstFrameBuiltEventName);
|
||||
final int firstFrameRasterizedTimestampMicros = extractInstantEventTimestamp(_kFirstFrameRasterizedEventName);
|
||||
if (firstFrameBuiltTimestampMicros == null || firstFrameRasterizedTimestampMicros == null) {
|
||||
printTrace('First frame events are missing in the timeline: $timeline');
|
||||
throw 'First frame events are missing in the timeline. Cannot compute startup time.';
|
||||
final int firstFrameTimestampMicros = extractInstantEventTimestamp(_kFirstUsefulFrameEventName);
|
||||
if (firstFrameTimestampMicros == null) {
|
||||
printTrace('First frame event is missing in the timeline: $timeline');
|
||||
throw 'First frame event is missing in the timeline. Cannot compute startup time.';
|
||||
}
|
||||
|
||||
// To keep our old benchmarks valid, we'll preserve the
|
||||
// timeToFirstFrameMicros as the firstFrameBuiltTimestampMicros.
|
||||
// Additionally, we add timeToFirstFrameRasterizedMicros for a more accurate
|
||||
// benchmark.
|
||||
traceInfo['timeToFirstFrameRasterizedMicros'] = firstFrameRasterizedTimestampMicros - engineEnterTimestampMicros;
|
||||
final int timeToFirstFrameMicros = firstFrameBuiltTimestampMicros - engineEnterTimestampMicros;
|
||||
final int timeToFirstFrameMicros = firstFrameTimestampMicros - engineEnterTimestampMicros;
|
||||
traceInfo['timeToFirstFrameMicros'] = timeToFirstFrameMicros;
|
||||
message = 'Time to first frame: ${timeToFirstFrameMicros ~/ 1000}ms.';
|
||||
if (frameworkInitTimestampMicros != null)
|
||||
traceInfo['timeAfterFrameworkInitMicros'] = firstFrameBuiltTimestampMicros - frameworkInitTimestampMicros;
|
||||
traceInfo['timeAfterFrameworkInitMicros'] = firstFrameTimestampMicros - frameworkInitTimestampMicros;
|
||||
}
|
||||
|
||||
traceInfoFile.writeAsStringSync(toPrettyJson(traceInfo));
|
||||
|
Loading…
Reference in New Issue
Block a user