44
55import 'dart:async' ;
66import 'dart:collection' ;
7- import 'dart:developer' ;
7+ import 'dart:developer' as developer ;
88import 'dart:ui' as ui show window;
99import 'dart:ui' show VoidCallback;
1010
@@ -550,7 +550,8 @@ abstract class SchedulerBinding extends BindingBase {
550550 }
551551 Duration _currentFrameTimeStamp;
552552
553- int _debugFrameNumber = 0 ;
553+ int _profileFrameNumber = 0 ;
554+ final Stopwatch _profileFrameStopwatch = new Stopwatch ();
554555 String _debugBanner;
555556
556557 /// Called by the engine to prepare the framework to produce a new frame.
@@ -577,22 +578,27 @@ abstract class SchedulerBinding extends BindingBase {
577578 /// statements printed during a frame from those printed between frames (e.g.
578579 /// in response to events or timers).
579580 void handleBeginFrame (Duration rawTimeStamp) {
580- Timeline .startSync ('Frame' );
581+ developer. Timeline .startSync ('Frame' );
581582 _firstRawTimeStampInEpoch ?? = rawTimeStamp;
582583 _currentFrameTimeStamp = _adjustForEpoch (rawTimeStamp ?? _lastRawTimeStamp);
583584 if (rawTimeStamp != null )
584585 _lastRawTimeStamp = rawTimeStamp;
585586
587+ profile (() {
588+ _profileFrameNumber += 1 ;
589+ _profileFrameStopwatch.reset ();
590+ _profileFrameStopwatch.start ();
591+ });
592+
586593 assert (() {
587- _debugFrameNumber += 1 ;
588594 if (debugPrintBeginFrameBanner || debugPrintEndFrameBanner) {
589595 final StringBuffer frameTimeStampDescription = new StringBuffer ();
590596 if (rawTimeStamp != null ) {
591597 _debugDescribeTimeStamp (_currentFrameTimeStamp, frameTimeStampDescription);
592598 } else {
593599 frameTimeStampDescription.write ('(warm-up frame)' );
594600 }
595- _debugBanner = '▄▄▄▄▄▄▄▄ Frame ${_debugFrameNumber .toString ().padRight (7 )} ${frameTimeStampDescription .toString ().padLeft (18 )} ▄▄▄▄▄▄▄▄' ;
601+ _debugBanner = '▄▄▄▄▄▄▄▄ Frame ${_profileFrameNumber .toString ().padRight (7 )} ${frameTimeStampDescription .toString ().padLeft (18 )} ▄▄▄▄▄▄▄▄' ;
596602 if (debugPrintBeginFrameBanner)
597603 debugPrint (_debugBanner);
598604 }
@@ -603,7 +609,7 @@ abstract class SchedulerBinding extends BindingBase {
603609 _hasScheduledFrame = false ;
604610 try {
605611 // TRANSIENT FRAME CALLBACKS
606- Timeline .startSync ('Animate' );
612+ developer. Timeline .startSync ('Animate' );
607613 _schedulerPhase = SchedulerPhase .transientCallbacks;
608614 final Map <int , _FrameCallbackEntry > callbacks = _transientCallbacks;
609615 _transientCallbacks = < int , _FrameCallbackEntry > {};
@@ -628,7 +634,7 @@ abstract class SchedulerBinding extends BindingBase {
628634 /// useful when working with frame callbacks.
629635 void handleDrawFrame () {
630636 assert (_schedulerPhase == SchedulerPhase .midFrameMicrotasks);
631- Timeline .finishSync (); // end the "Animate" phase
637+ developer. Timeline .finishSync (); // end the "Animate" phase
632638 try {
633639 // PERSISTENT FRAME CALLBACKS
634640 _schedulerPhase = SchedulerPhase .persistentCallbacks;
@@ -644,14 +650,22 @@ abstract class SchedulerBinding extends BindingBase {
644650 _invokeFrameCallback (callback, _currentFrameTimeStamp);
645651 } finally {
646652 _schedulerPhase = SchedulerPhase .idle;
647- _currentFrameTimeStamp = null ;
648- Timeline .finishSync ();
653+ developer.Timeline .finishSync (); // end the Frame
654+ profile (() {
655+ _profileFrameStopwatch.stop ();
656+ developer.postEvent ('Flutter.Frame' , < String , dynamic > {
657+ 'number' : _profileFrameNumber,
658+ 'startTime' : _currentFrameTimeStamp.inMicroseconds,
659+ 'elapsed' : _profileFrameStopwatch.elapsedMicroseconds
660+ });
661+ });
649662 assert (() {
650663 if (debugPrintEndFrameBanner)
651664 debugPrint ('▀' * _debugBanner.length);
652665 _debugBanner = null ;
653666 return true ;
654667 });
668+ _currentFrameTimeStamp = null ;
655669 }
656670
657671 // All frame-related callbacks have been executed. Run lower-priority tasks.
0 commit comments