| // Copyright 2014 The Flutter 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 'percentile_utils.dart'; |
| import 'timeline.dart'; |
| |
| /// Key for SceneDisplayLag timeline events. |
| const String kSceneDisplayLagEvent = 'SceneDisplayLag'; |
| |
| const String _kVsyncTransitionsMissed = 'vsync_transitions_missed'; |
| |
| /// Summarizes [TimelineEvents]s corresponding to [kSceneDisplayLagEvent] events. |
| /// |
| /// A sample event (some fields have been omitted for brevity): |
| /// ``` |
| /// { |
| /// "name": "SceneDisplayLag", |
| /// "ts": 408920509340, |
| /// "ph": "b", (this can be 'b' or 'e' for begin or end) |
| /// "args": { |
| /// "frame_target_time": "408920509340458", |
| /// "current_frame_target_time": "408920542689291", |
| /// "vsync_transitions_missed": "2" |
| /// } |
| /// }, |
| /// ``` |
| /// |
| /// `vsync_transitions_missed` corresponds to the elapsed number of frame budget |
| /// durations between when the frame was scheduled to be displayed, i.e, the |
| /// `frame_target_time` and the next vsync pulse timestamp, i.e, the |
| /// `current_frame_target_time`. |
| class SceneDisplayLagSummarizer { |
| /// Creates a SceneDisplayLagSummarizer given the timeline events. |
| SceneDisplayLagSummarizer(this.sceneDisplayLagEvents) { |
| for (final TimelineEvent event in sceneDisplayLagEvents) { |
| assert(event.name == kSceneDisplayLagEvent); |
| } |
| } |
| |
| /// The scene display lag events. |
| final List<TimelineEvent> sceneDisplayLagEvents; |
| |
| /// Computes the average of the `vsync_transitions_missed` over the lag events. |
| double computeAverageVsyncTransitionsMissed() { |
| if (sceneDisplayLagEvents.isEmpty) { |
| return 0; |
| } |
| |
| final double total = sceneDisplayLagEvents |
| .map(_getVsyncTransitionsMissed) |
| .reduce((double a, double b) => a + b); |
| return total / sceneDisplayLagEvents.length; |
| } |
| |
| /// The [percentile]-th percentile `vsync_transitions_missed` over the lag events. |
| double computePercentileVsyncTransitionsMissed(double percentile) { |
| if (sceneDisplayLagEvents.isEmpty) { |
| return 0; |
| } |
| |
| final List<double> doubles = |
| sceneDisplayLagEvents.map(_getVsyncTransitionsMissed).toList(); |
| return findPercentile(doubles, percentile); |
| } |
| |
| double _getVsyncTransitionsMissed(TimelineEvent e) { |
| assert(e.name == kSceneDisplayLagEvent); |
| assert(e.arguments!.containsKey(_kVsyncTransitionsMissed)); |
| final dynamic transitionsMissed = e.arguments![_kVsyncTransitionsMissed]; |
| assert(transitionsMissed is String); |
| return double.parse(transitionsMissed as String); |
| } |
| } |