void handleBeginFrame(Duration rawTimeStamp)

Called by the engine to produce a new frame.

This function first calls all the callbacks registered by scheduleFrameCallback/addFrameCallback, then calls all the callbacks registered by addPersistentFrameCallback, which typically drive the rendering pipeline, and finally calls the callbacks registered by addPostFrameCallback.

If the given time stamp is null, the time stamp from the last frame is reused.

To have a banner shown at the start of every frame in debug mode, set debugPrintBeginFrameBanner to true. The banner will be printed to the console using debugPrint and will contain the frame number (which increments by one for each frame), and the time stamp of the frame. If the given time stamp was null, then the string "warm-up frame" is shown instead of the time stamp. This allows you to distinguish frames eagerly pushed by the framework from those requested by the engine in response to the vsync signal from the operating system.

You can also show a banner at the end of every frame by setting debugPrintEndFrameBanner to true. This allows you to distinguish log statements printed during a frame from those printed between frames (e.g. in response to events or timers).

Source

void handleBeginFrame(Duration rawTimeStamp) {
  Timeline.startSync('Frame');
  _firstRawTimeStampInEpoch ??= rawTimeStamp;
  _currentFrameTimeStamp = _adjustForEpoch(rawTimeStamp ?? _lastRawTimeStamp);
  if (rawTimeStamp != null)
    _lastRawTimeStamp = rawTimeStamp;

  String debugBanner;
  assert(() {
    _debugFrameNumber += 1;
    if (debugPrintBeginFrameBanner || debugPrintEndFrameBanner) {
      StringBuffer frameTimeStampDescription = new StringBuffer();
      if (rawTimeStamp != null) {
        _debugDescribeTimeStamp(_currentFrameTimeStamp, frameTimeStampDescription);
      } else {
        frameTimeStampDescription.write('(warm-up frame)');
      }
      debugBanner = '▄▄▄▄▄▄▄▄ Frame ${_debugFrameNumber.toString().padRight(7)}   ${frameTimeStampDescription.toString().padLeft(18)} ▄▄▄▄▄▄▄▄';
      if (debugPrintBeginFrameBanner)
        debugPrint(debugBanner);
    }
    return true;
  });

  assert(schedulerPhase == SchedulerPhase.idle);
  _hasScheduledFrame = false;
  try {

    // TRANSIENT FRAME CALLBACKS
    _schedulerPhase = SchedulerPhase.transientCallbacks;
    _invokeTransientFrameCallbacks(_currentFrameTimeStamp);

    // PERSISTENT FRAME CALLBACKS
    _schedulerPhase = SchedulerPhase.persistentCallbacks;
    for (FrameCallback callback in _persistentCallbacks)
      _invokeFrameCallback(callback, _currentFrameTimeStamp);

    // POST-FRAME CALLBACKS
    _schedulerPhase = SchedulerPhase.postFrameCallbacks;
    List<FrameCallback> localPostFrameCallbacks =
        new List<FrameCallback>.from(_postFrameCallbacks);
    _postFrameCallbacks.clear();
    for (FrameCallback callback in localPostFrameCallbacks)
      _invokeFrameCallback(callback, _currentFrameTimeStamp);

  } finally {
    _schedulerPhase = SchedulerPhase.idle;
    _currentFrameTimeStamp = null;
    Timeline.finishSync();
    assert(() {
      if (debugPrintEndFrameBanner)
        debugPrint('▀' * debugBanner.length);
      return true;
    });
  }

  // All frame-related callbacks have been executed. Run lower-priority tasks.
  _runTasks();
}