[M108 Migration][VD] Avoid pending frame counter becoming negative
[platform/framework/web/chromium-efl.git] / cc / metrics / total_frame_counter.cc
1 // Copyright 2020 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/metrics/total_frame_counter.h"
6
7 #include <cmath>
8
9 #include "base/logging.h"
10 #include "components/viz/common/frame_sinks/begin_frame_args.h"
11
12 namespace cc {
13
14 TotalFrameCounter::TotalFrameCounter() = default;
15
16 void TotalFrameCounter::OnShow(base::TimeTicks timestamp) {
17   DCHECK(last_shown_timestamp_.is_null());
18   DCHECK(latest_interval_.is_zero());
19   last_shown_timestamp_ = timestamp;
20 }
21
22 void TotalFrameCounter::OnHide(base::TimeTicks timestamp) {
23   // It is possible to hide right after being shown before receiving any
24   // BeginFrameArgs.
25   if (!latest_interval_.is_zero())
26     UpdateTotalFramesSinceLastVisible(timestamp);
27   last_shown_timestamp_ = base::TimeTicks();
28   latest_interval_ = base::TimeDelta();
29 }
30
31 void TotalFrameCounter::OnBeginFrame(const viz::BeginFrameArgs& args) {
32   // In tests, it is possible to receive begin-frames when invisible. Ignore
33   // these.
34   if (last_shown_timestamp_.is_null())
35     return;
36
37   if (!latest_interval_.is_zero() && latest_interval_ != args.interval) {
38     UpdateTotalFramesSinceLastVisible(args.frame_time);
39     last_shown_timestamp_ = args.frame_time;
40   }
41
42   latest_interval_ = args.interval;
43 }
44
45 void TotalFrameCounter::Reset() {
46   total_frames_ = 0;
47   latest_interval_ = {};
48   // If the compositor is visible, then update the visible timestamp to current
49   // time.
50   if (!last_shown_timestamp_.is_null())
51     last_shown_timestamp_ = base::TimeTicks::Now();
52 }
53
54 void TotalFrameCounter::UpdateTotalFramesSinceLastVisible(
55     base::TimeTicks until) {
56   total_frames_ = ComputeTotalVisibleFrames(until);
57 }
58
59 size_t TotalFrameCounter::ComputeTotalVisibleFrames(
60     base::TimeTicks until) const {
61   DCHECK(!until.is_null());
62
63   if (last_shown_timestamp_.is_null() || latest_interval_.is_zero()) {
64     // The compositor may be currently invisible, or has just been made visible
65     // but has yet to receive a BeginFrameArgs.
66     return total_frames_;
67   }
68
69   DCHECK_GE(until, last_shown_timestamp_);
70   auto frames_since =
71       std::ceil((until - last_shown_timestamp_) / latest_interval_);
72   return total_frames_ + frames_since;
73 }
74
75 }  // namespace cc