Add MissedDeadlineFrames to track frames that miss the vsync deadline
This change adds a MissedDeadlineFrames UMA that tracks frames that
miss the vsync deadline during scroll/animations.
Bug: 1092938
Change-Id: I044985583193d94c90485f1308be5645d553af7f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2343642
Commit-Queue: Matthew Crabill <[email protected]>
Reviewed-by: Sadrul Chowdhury <[email protected]>
Reviewed-by: Xida Chen <[email protected]>
Reviewed-by: David Bokan <[email protected]>
Reviewed-by: Behdad Bakhshinategh <[email protected]>
Reviewed-by: Stephen Chenney <[email protected]>
Cr-Commit-Position: refs/heads/master@{#807596}
diff --git a/cc/metrics/frame_sequence_tracker.cc b/cc/metrics/frame_sequence_tracker.cc
index 56019f9..9e851e3d 100644
--- a/cc/metrics/frame_sequence_tracker.cc
+++ b/cc/metrics/frame_sequence_tracker.cc
@@ -361,6 +361,9 @@
DCHECK_GT(impl_throughput().frames_expected,
impl_throughput().frames_produced)
<< TRACKER_DCHECK_MSG;
+ DCHECK_GE(impl_throughput().frames_produced,
+ impl_throughput().frames_ontime)
+ << TRACKER_DCHECK_MSG;
--impl_throughput().frames_expected;
#if DCHECK_IS_ON()
++impl_throughput().frames_processed;
@@ -437,9 +440,28 @@
uint32_t impl_frames_produced = 0;
uint32_t main_frames_produced = 0;
+ uint32_t impl_frames_ontime = 0;
+ uint32_t main_frames_ontime = 0;
+
+ const auto& vsync_interval =
+ (feedback.interval.is_zero() ? viz::BeginFrameArgs::DefaultInterval()
+ : feedback.interval) *
+ 1.5;
+ DCHECK(!vsync_interval.is_zero()) << TRACKER_DCHECK_MSG;
+ base::TimeTicks safe_deadline_for_frame =
+ last_frame_presentation_timestamp_ + vsync_interval;
const bool was_presented = !feedback.failed();
if (was_presented && submitted_frame_since_last_presentation) {
+ if (!last_frame_presentation_timestamp_.is_null() &&
+ (safe_deadline_for_frame < feedback.timestamp)) {
+ DCHECK_LE(impl_throughput().frames_ontime,
+ impl_throughput().frames_produced)
+ << TRACKER_DCHECK_MSG;
+ ++impl_throughput().frames_ontime;
+ ++impl_frames_ontime;
+ }
+
DCHECK_LT(impl_throughput().frames_produced,
impl_throughput().frames_expected)
<< TRACKER_DCHECK_MSG;
@@ -474,6 +496,16 @@
metrics()->ComputeJank(FrameSequenceMetrics::ThreadType::kMain,
feedback.timestamp, feedback.interval);
}
+ if (main_frames_.size() < size_before_erase) {
+ if (!last_frame_presentation_timestamp_.is_null() &&
+ (safe_deadline_for_frame < feedback.timestamp)) {
+ DCHECK_LE(main_throughput().frames_ontime,
+ main_throughput().frames_produced)
+ << TRACKER_DCHECK_MSG;
+ ++main_throughput().frames_ontime;
+ ++main_frames_ontime;
+ }
+ }
if (impl_frames_produced > 0) {
// If there is no main frame presented, then we need to see whether or not
@@ -492,6 +524,7 @@
// frames produced so that we can apply that to aggregated throughput
// if the main frame reports no-damage later on.
impl_frames_produced_while_expecting_main_ += impl_frames_produced;
+ impl_frames_ontime_while_expecting_main_ += impl_frames_ontime;
} else {
// TODO(https://crbug.com/1066455): Determine why this DCHECK is
// causing PageLoadMetricsBrowserTests to flake, and re-enable.
@@ -499,10 +532,14 @@
// << TRACKER_DCHECK_MSG;
aggregated_throughput().frames_produced += impl_frames_produced;
impl_frames_produced_while_expecting_main_ = 0;
+ aggregated_throughput().frames_ontime += impl_frames_ontime;
+ impl_frames_ontime_while_expecting_main_ = 0;
}
} else {
aggregated_throughput().frames_produced += main_frames_produced;
impl_frames_produced_while_expecting_main_ = 0;
+ aggregated_throughput().frames_ontime += main_frames_ontime;
+ impl_frames_ontime_while_expecting_main_ = 0;
while (!expecting_main_when_submit_impl_.empty() &&
!viz::FrameTokenGT(expecting_main_when_submit_impl_.front(),
frame_token)) {
@@ -511,6 +548,8 @@
}
}
+ last_frame_presentation_timestamp_ = feedback.timestamp;
+
if (checkerboarding_.last_frame_had_checkerboarding) {
DCHECK(!checkerboarding_.last_frame_timestamp.is_null())
<< TRACKER_DCHECK_MSG;
@@ -608,6 +647,8 @@
DCHECK_GT(main_throughput().frames_expected,
main_throughput().frames_produced)
<< TRACKER_DCHECK_MSG;
+ DCHECK_GE(main_throughput().frames_produced, main_throughput().frames_ontime)
+ << TRACKER_DCHECK_MSG;
last_no_main_damage_sequence_ = args.frame_id.sequence_number;
--main_throughput().frames_expected;
// Compute the number of actually expected compositor frames during this main
@@ -634,6 +675,9 @@
aggregated_throughput().frames_produced +=
impl_frames_produced_while_expecting_main_;
impl_frames_produced_while_expecting_main_ = 0;
+ aggregated_throughput().frames_ontime +=
+ impl_frames_ontime_while_expecting_main_;
+ impl_frames_ontime_while_expecting_main_ = 0;
expecting_main_when_submit_impl_.clear();
}