blob: f60a39b08afe425615f4aa27524ab3666c9ac44f (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
// Copyright 2017 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 "components/viz/service/surfaces/surface_dependency_deadline.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/time/tick_clock.h"
#include "components/viz/common/quads/frame_deadline.h"
namespace viz {
SurfaceDependencyDeadline::SurfaceDependencyDeadline(
SurfaceDeadlineClient* client,
BeginFrameSource* begin_frame_source,
const base::TickClock* tick_clock)
: client_(client),
begin_frame_source_(begin_frame_source),
tick_clock_(tick_clock) {
DCHECK(client_);
DCHECK(begin_frame_source_);
DCHECK(tick_clock_);
}
SurfaceDependencyDeadline::~SurfaceDependencyDeadline() {
// The deadline must be canceled before destruction.
DCHECK(!deadline_);
}
bool SurfaceDependencyDeadline::Set(const FrameDeadline& frame_deadline) {
DCHECK_GT(frame_deadline.deadline_in_frames(), 0u);
CancelInternal(false);
start_time_ = frame_deadline.frame_start_time();
deadline_ = start_time_ + frame_deadline.deadline_in_frames() *
frame_deadline.frame_interval();
begin_frame_source_->AddObserver(this);
return has_deadline();
}
base::Optional<base::TimeDelta> SurfaceDependencyDeadline::Cancel() {
return CancelInternal(false);
}
void SurfaceDependencyDeadline::InheritFrom(
const SurfaceDependencyDeadline& other) {
if (*this == other)
return;
base::Optional<base::TimeDelta> duration = CancelInternal(false);
last_begin_frame_args_ = other.last_begin_frame_args_;
begin_frame_source_ = other.begin_frame_source_;
deadline_ = other.deadline_;
if (deadline_) {
if (!duration)
start_time_ = tick_clock_->NowTicks();
begin_frame_source_->AddObserver(this);
}
}
bool SurfaceDependencyDeadline::operator==(
const SurfaceDependencyDeadline& other) {
return begin_frame_source_ == other.begin_frame_source_ &&
deadline_ == other.deadline_;
}
// BeginFrameObserver implementation.
void SurfaceDependencyDeadline::OnBeginFrame(const BeginFrameArgs& args) {
last_begin_frame_args_ = args;
// OnBeginFrame might get called immediately after cancellation if some other
// deadline triggered this deadline to be canceled.
if (!deadline_)
return;
if (deadline_ > tick_clock_->NowTicks())
return;
base::Optional<base::TimeDelta> duration = CancelInternal(true);
DCHECK(duration);
client_->OnDeadline(*duration);
}
const BeginFrameArgs& SurfaceDependencyDeadline::LastUsedBeginFrameArgs()
const {
return last_begin_frame_args_;
}
bool SurfaceDependencyDeadline::WantsAnimateOnlyBeginFrames() const {
return false;
}
void SurfaceDependencyDeadline::OnBeginFrameSourcePausedChanged(bool paused) {}
base::Optional<base::TimeDelta> SurfaceDependencyDeadline::CancelInternal(
bool deadline) {
if (!deadline_)
return base::nullopt;
begin_frame_source_->RemoveObserver(this);
deadline_.reset();
base::TimeDelta duration = tick_clock_->NowTicks() - start_time_;
UMA_HISTOGRAM_TIMES("Compositing.SurfaceDependencyDeadline.Duration",
duration);
UMA_HISTOGRAM_BOOLEAN("Compositing.SurfaceDependencyDeadline.DeadlineHit",
deadline);
return duration;
}
} // namespace viz
|