| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "cc/metrics/total_frame_counter.h" |
| |
| #include "base/logging.h" |
| #include "components/viz/common/frame_sinks/begin_frame_args.h" |
| |
| namespace cc { |
| |
| TotalFrameCounter::TotalFrameCounter() = default; |
| |
| void TotalFrameCounter::OnShow(base::TimeTicks timestamp) { |
| DCHECK(last_shown_timestamp_.is_null()); |
| DCHECK(latest_interval_.is_zero()); |
| last_shown_timestamp_ = timestamp; |
| } |
| |
| void TotalFrameCounter::OnHide(base::TimeTicks timestamp) { |
| // It is possible to hide right after being shown before receiving any |
| // BeginFrameArgs. |
| if (!latest_interval_.is_zero()) |
| UpdateTotalFramesSinceLastVisible(timestamp); |
| last_shown_timestamp_ = base::TimeTicks(); |
| latest_interval_ = base::TimeDelta(); |
| } |
| |
| void TotalFrameCounter::OnBeginFrame(const viz::BeginFrameArgs& args) { |
| // In tests, it is possible to receive begin-frames when invisible. Ignore |
| // these. |
| if (last_shown_timestamp_.is_null()) |
| return; |
| |
| if (!latest_interval_.is_zero() && latest_interval_ != args.interval) { |
| UpdateTotalFramesSinceLastVisible(args.frame_time); |
| last_shown_timestamp_ = args.frame_time; |
| } |
| |
| latest_interval_ = args.interval; |
| } |
| |
| void TotalFrameCounter::Reset() { |
| total_frames_ = 0; |
| latest_interval_ = {}; |
| // If the compositor is visible, then update the visible timestamp to current |
| // time. |
| if (!last_shown_timestamp_.is_null()) |
| last_shown_timestamp_ = base::TimeTicks::Now(); |
| } |
| |
| void TotalFrameCounter::UpdateTotalFramesSinceLastVisible( |
| base::TimeTicks until) { |
| total_frames_ = ComputeTotalVisibleFrames(until); |
| } |
| |
| size_t TotalFrameCounter::ComputeTotalVisibleFrames( |
| base::TimeTicks until) const { |
| DCHECK(!until.is_null()); |
| |
| if (last_shown_timestamp_.is_null() || latest_interval_.is_zero()) { |
| // The compositor may be currently invisible, or has just been made visible |
| // but has yet to receive a BeginFrameArgs. |
| return total_frames_; |
| } |
| |
| DCHECK_GE(until, last_shown_timestamp_); |
| auto frames_since = |
| std::round((until - last_shown_timestamp_) / latest_interval_); |
| return total_frames_ + frames_since; |
| } |
| |
| } // namespace cc |