Unverified Commit 446179f6 authored by Devon Carew's avatar Devon Carew Committed by GitHub

update the Flutter.Frame event to use new engine APIs (#34243)

* update the Flutter.Frame event to use new engine APIs

* add a test

* update test
parent 22ca3f96
......@@ -4,8 +4,8 @@
import 'dart:async';
import 'dart:collection';
import 'dart:developer';
import 'dart:ui' show AppLifecycleState;
import 'dart:developer' show Flow, Timeline;
import 'dart:ui' show AppLifecycleState, FramePhase, FrameTiming;
import 'package:collection/collection.dart' show PriorityQueue, HeapPriorityQueue;
import 'package:flutter/foundation.dart';
......@@ -198,6 +198,17 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
window.onDrawFrame = _handleDrawFrame;
SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
readInitialLifecycleStateFromNativeWindow();
if (!kReleaseMode) {
int frameNumber = 0;
window.onReportTimings = (List<FrameTiming> timings) {
for (FrameTiming frameTiming in timings) {
frameNumber += 1;
_profileFramePostEvent(frameNumber, frameTiming);
}
};
}
}
/// The current [SchedulerBinding], if one has been created.
......@@ -842,8 +853,7 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
}
Duration _currentFrameTimeStamp;
int _profileFrameNumber = 0;
final Stopwatch _profileFrameStopwatch = Stopwatch();
int _debugFrameNumber = 0;
String _debugBanner;
bool _ignoreNextEngineDrawFrame = false;
......@@ -894,13 +904,9 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
if (rawTimeStamp != null)
_lastRawTimeStamp = rawTimeStamp;
if (!kReleaseMode) {
_profileFrameNumber += 1;
_profileFrameStopwatch.reset();
_profileFrameStopwatch.start();
}
assert(() {
_debugFrameNumber += 1;
if (debugPrintBeginFrameBanner || debugPrintEndFrameBanner) {
final StringBuffer frameTimeStampDescription = StringBuffer();
if (rawTimeStamp != null) {
......@@ -908,7 +914,7 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
} else {
frameTimeStampDescription.write('(warm-up frame)');
}
_debugBanner = '▄▄▄▄▄▄▄▄ Frame ${_profileFrameNumber.toString().padRight(7)} ${frameTimeStampDescription.toString().padLeft(18)} ▄▄▄▄▄▄▄▄';
_debugBanner = '▄▄▄▄▄▄▄▄ Frame ${_debugFrameNumber.toString().padRight(7)} ${frameTimeStampDescription.toString().padLeft(18)} ▄▄▄▄▄▄▄▄';
if (debugPrintBeginFrameBanner)
debugPrint(_debugBanner);
}
......@@ -961,10 +967,6 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
} finally {
_schedulerPhase = SchedulerPhase.idle;
Timeline.finishSync(); // end the Frame
if (!kReleaseMode) {
_profileFrameStopwatch.stop();
_profileFramePostEvent();
}
assert(() {
if (debugPrintEndFrameBanner)
debugPrint('▀' * _debugBanner.length);
......@@ -975,11 +977,13 @@ mixin SchedulerBinding on BindingBase, ServicesBinding {
}
}
void _profileFramePostEvent() {
void _profileFramePostEvent(int frameNumber, FrameTiming frameTiming) {
postEvent('Flutter.Frame', <String, dynamic>{
'number': _profileFrameNumber,
'startTime': _currentFrameTimeStamp.inMicroseconds,
'elapsed': _profileFrameStopwatch.elapsedMicroseconds,
'number': frameNumber,
'startTime': frameTiming.timestampInMicroseconds(FramePhase.buildStart),
'elapsed': frameTiming.totalSpan.inMicroseconds,
'build': frameTiming.buildDuration.inMicroseconds,
'raster': frameTiming.rasterDuration.inMicroseconds,
});
}
......
......@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:ui' show window, FrameTiming;
import 'package:flutter/foundation.dart';
import 'package:flutter/scheduler.dart';
......@@ -10,7 +11,18 @@ import 'package:flutter/services.dart';
import '../flutter_test_alternative.dart';
class TestSchedulerBinding extends BindingBase with ServicesBinding, SchedulerBinding { }
class TestSchedulerBinding extends BindingBase with ServicesBinding, SchedulerBinding {
final Map<String, List<Map<String, dynamic>>> eventsDispatched = <String, List<Map<String, dynamic>>>{};
@override
void postEvent(String eventKind, Map<dynamic, dynamic> eventData) {
getEventsDispatched(eventKind).add(eventData);
}
List<Map<String, dynamic>> getEventsDispatched(String eventKind) {
return eventsDispatched.putIfAbsent(eventKind, () => <Map<String, dynamic>>[]);
}
}
class TestStrategy {
int allowedPriority = 10000;
......@@ -21,7 +33,8 @@ class TestStrategy {
}
void main() {
SchedulerBinding scheduler;
TestSchedulerBinding scheduler;
setUpAll(() {
scheduler = TestSchedulerBinding();
});
......@@ -116,4 +129,23 @@ void main() {
expect(timerQueueTasks.length, 2);
expect(taskExecuted, false);
});
test('Flutter.Frame event fired', () async {
window.onReportTimings(<FrameTiming>[FrameTiming(<int>[
// build start, build finish
10000, 15000,
// raster start, raster finish
16000, 20000,
])]);
final List<Map<String, dynamic>> events = scheduler.getEventsDispatched('Flutter.Frame');
expect(events, hasLength(1));
final Map<String, dynamic> event = events.first;
expect(event['number'], isNonNegative);
expect(event['startTime'], 10000);
expect(event['elapsed'], 10000);
expect(event['build'], 5000);
expect(event['raster'], 4000);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment