Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(544)

Side by Side Diff: cc/scheduler/begin_frame_source.cc

Issue 2061273002: cc: Make BackToBackBeginFrameSource a SyntheticBeginFrameSource. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: syntheticbeginframesource: delete-DEBUG_FRAMES Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/scheduler/begin_frame_source.h ('k') | cc/scheduler/begin_frame_source_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/scheduler/begin_frame_source.h" 5 #include "cc/scheduler/begin_frame_source.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/location.h" 10 #include "base/location.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/memory/ptr_util.h"
12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/stringprintf.h" 14 #include "base/strings/stringprintf.h"
14 #include "base/trace_event/trace_event.h" 15 #include "base/trace_event/trace_event.h"
15 #include "base/trace_event/trace_event_argument.h" 16 #include "base/trace_event/trace_event_argument.h"
16 #include "cc/scheduler/delay_based_time_source.h" 17 #include "cc/scheduler/delay_based_time_source.h"
17 #include "cc/scheduler/scheduler.h" 18 #include "cc/scheduler/scheduler.h"
18 19
19 namespace cc { 20 namespace cc {
20 21
21 namespace { 22 namespace {
22 // kDoubleTickDivisor prevents the SyntheticBFS from sending BeginFrames too 23 // kDoubleTickDivisor prevents the SyntheticBFS from sending BeginFrames too
23 // often to an observer. 24 // often to an observer.
24 static const double kDoubleTickDivisor = 2.0; 25 static const double kDoubleTickDivisor = 2.0;
25 } 26 }
26 27
27 // BeginFrameObserverBase ----------------------------------------------- 28 // BeginFrameObserverBase -----------------------------------------------
28 BeginFrameObserverBase::BeginFrameObserverBase() 29 BeginFrameObserverBase::BeginFrameObserverBase()
29 : last_begin_frame_args_(), dropped_begin_frame_args_(0) { 30 : last_begin_frame_args_(), dropped_begin_frame_args_(0) {
30 } 31 }
31 32
32 const BeginFrameArgs& BeginFrameObserverBase::LastUsedBeginFrameArgs() const { 33 const BeginFrameArgs& BeginFrameObserverBase::LastUsedBeginFrameArgs() const {
33 return last_begin_frame_args_; 34 return last_begin_frame_args_;
34 } 35 }
35 void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) { 36 void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) {
36 DEBUG_FRAMES("BeginFrameObserverBase::OnBeginFrame",
37 "last args",
38 last_begin_frame_args_.AsValue(),
39 "new args",
40 args.AsValue());
41 DCHECK(args.IsValid()); 37 DCHECK(args.IsValid());
42 DCHECK(args.frame_time >= last_begin_frame_args_.frame_time); 38 DCHECK(args.frame_time >= last_begin_frame_args_.frame_time);
43 bool used = OnBeginFrameDerivedImpl(args); 39 bool used = OnBeginFrameDerivedImpl(args);
44 if (used) { 40 if (used) {
45 last_begin_frame_args_ = args; 41 last_begin_frame_args_ = args;
46 } else { 42 } else {
47 ++dropped_begin_frame_args_; 43 ++dropped_begin_frame_args_;
48 } 44 }
49 } 45 }
50 46
51 // BeginFrameSourceBase ------------------------------------------------------ 47 // SyntheticBeginFrameSource ---------------------------------------------
52 BeginFrameSourceBase::BeginFrameSourceBase() : paused_(false) {} 48 SyntheticBeginFrameSource::~SyntheticBeginFrameSource() = default;
53
54 BeginFrameSourceBase::~BeginFrameSourceBase() {}
55
56 void BeginFrameSourceBase::AddObserver(BeginFrameObserver* obs) {
57 DEBUG_FRAMES("BeginFrameSourceBase::AddObserver", "num observers",
58 observers_.size(), "to add observer", obs);
59 DCHECK(obs);
60 DCHECK(observers_.find(obs) == observers_.end())
61 << "AddObserver cannot be called with an observer that was already added";
62 bool observers_was_empty = observers_.empty();
63 observers_.insert(obs);
64 if (observers_was_empty)
65 OnNeedsBeginFramesChanged(true);
66 obs->OnBeginFrameSourcePausedChanged(paused_);
67 }
68
69 void BeginFrameSourceBase::RemoveObserver(BeginFrameObserver* obs) {
70 DEBUG_FRAMES("BeginFrameSourceBase::RemoveObserver", "num observers",
71 observers_.size(), "removed observer", obs);
72 DCHECK(obs);
73 DCHECK(observers_.find(obs) != observers_.end())
74 << "RemoveObserver cannot be called with an observer that wasn't added";
75 observers_.erase(obs);
76 if (observers_.empty())
77 OnNeedsBeginFramesChanged(false);
78 }
79
80 void BeginFrameSourceBase::CallOnBeginFrame(const BeginFrameArgs& args) {
81 DEBUG_FRAMES("BeginFrameSourceBase::CallOnBeginFrame", "num observers",
82 observers_.size(), "args", args.AsValue());
83 std::set<BeginFrameObserver*> observers(observers_);
84 for (BeginFrameObserver* obs : observers)
85 obs->OnBeginFrame(args);
86 }
87
88 void BeginFrameSourceBase::SetBeginFrameSourcePaused(bool paused) {
89 if (paused_ == paused)
90 return;
91 paused_ = paused;
92 std::set<BeginFrameObserver*> observers(observers_);
93 for (BeginFrameObserver* obs : observers)
94 obs->OnBeginFrameSourcePausedChanged(paused_);
95 }
96 49
97 // BackToBackBeginFrameSource -------------------------------------------- 50 // BackToBackBeginFrameSource --------------------------------------------
98 BackToBackBeginFrameSource::BackToBackBeginFrameSource( 51 BackToBackBeginFrameSource::BackToBackBeginFrameSource(
99 base::SingleThreadTaskRunner* task_runner) 52 std::unique_ptr<DelayBasedTimeSource> time_source)
100 : BeginFrameSourceBase(), task_runner_(task_runner), weak_factory_(this) { 53 : time_source_(std::move(time_source)), weak_factory_(this) {
101 DCHECK(task_runner); 54 time_source_->SetClient(this);
55 // The time_source_ ticks immediately, so we SetActive(true) for a single
56 // tick when we need it, and keep it as SetActive(false) otherwise.
57 time_source_->SetTimebaseAndInterval(base::TimeTicks(), base::TimeDelta());
102 } 58 }
103 59
104 BackToBackBeginFrameSource::~BackToBackBeginFrameSource() { 60 BackToBackBeginFrameSource::~BackToBackBeginFrameSource() = default;
105 }
106 61
107 base::TimeTicks BackToBackBeginFrameSource::Now() {
108 return base::TimeTicks::Now();
109 }
110
111 // BeginFrameSourceBase support
112 void BackToBackBeginFrameSource::AddObserver(BeginFrameObserver* obs) { 62 void BackToBackBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
113 BeginFrameSourceBase::AddObserver(obs); 63 DCHECK(obs);
64 DCHECK(observers_.find(obs) == observers_.end());
65 observers_.insert(obs);
114 pending_begin_frame_observers_.insert(obs); 66 pending_begin_frame_observers_.insert(obs);
115 PostPendingBeginFramesTask(); 67 obs->OnBeginFrameSourcePausedChanged(false);
68 time_source_->SetActive(true);
116 } 69 }
117 70
118 void BackToBackBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) { 71 void BackToBackBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) {
119 BeginFrameSourceBase::RemoveObserver(obs); 72 DCHECK(obs);
73 DCHECK(observers_.find(obs) != observers_.end());
74 observers_.erase(obs);
120 pending_begin_frame_observers_.erase(obs); 75 pending_begin_frame_observers_.erase(obs);
121 if (pending_begin_frame_observers_.empty()) 76 if (observers_.empty())
122 begin_frame_task_.Cancel(); 77 time_source_->SetActive(false);
123 } 78 }
124 79
125 void BackToBackBeginFrameSource::DidFinishFrame(BeginFrameObserver* obs, 80 void BackToBackBeginFrameSource::DidFinishFrame(BeginFrameObserver* obs,
126 size_t remaining_frames) { 81 size_t remaining_frames) {
127 BeginFrameSourceBase::DidFinishFrame(obs, remaining_frames);
128 if (remaining_frames == 0 && observers_.find(obs) != observers_.end()) { 82 if (remaining_frames == 0 && observers_.find(obs) != observers_.end()) {
129 pending_begin_frame_observers_.insert(obs); 83 pending_begin_frame_observers_.insert(obs);
130 PostPendingBeginFramesTask(); 84 time_source_->SetActive(true);
131 } 85 }
132 } 86 }
133 87
134 void BackToBackBeginFrameSource::PostPendingBeginFramesTask() { 88 void BackToBackBeginFrameSource::OnTimerTick() {
135 DCHECK(needs_begin_frames()); 89 base::TimeTicks frame_time = time_source_->LastTickTime();
136 DCHECK(!pending_begin_frame_observers_.empty()); 90 base::TimeDelta default_interval = BeginFrameArgs::DefaultInterval();
137 if (begin_frame_task_.IsCancelled()) { 91 BeginFrameArgs args = BeginFrameArgs::Create(
138 begin_frame_task_.Reset( 92 BEGINFRAME_FROM_HERE, frame_time, frame_time + default_interval,
139 base::Bind(&BackToBackBeginFrameSource::SendPendingBeginFrames, 93 default_interval, BeginFrameArgs::NORMAL);
140 weak_factory_.GetWeakPtr()));
141 task_runner_->PostTask(FROM_HERE, begin_frame_task_.callback());
142 }
143 }
144 94
145 void BackToBackBeginFrameSource::SendPendingBeginFrames() { 95 // This must happen after getting the LastTickTime() from the time source.
146 DCHECK(needs_begin_frames()); 96 time_source_->SetActive(false);
147 DCHECK(!begin_frame_task_.IsCancelled());
148 begin_frame_task_.Cancel();
149 97
150 base::TimeTicks now = Now(); 98 std::unordered_set<BeginFrameObserver*> pending_observers;
151 BeginFrameArgs args = BeginFrameArgs::Create(
152 BEGINFRAME_FROM_HERE, now, now + BeginFrameArgs::DefaultInterval(),
153 BeginFrameArgs::DefaultInterval(), BeginFrameArgs::NORMAL);
154
155 std::set<BeginFrameObserver*> pending_observers;
156 pending_observers.swap(pending_begin_frame_observers_); 99 pending_observers.swap(pending_begin_frame_observers_);
157 for (BeginFrameObserver* obs : pending_observers) 100 for (BeginFrameObserver* obs : pending_observers)
158 obs->OnBeginFrame(args); 101 obs->OnBeginFrame(args);
159 } 102 }
160 103
161 // SyntheticBeginFrameSource --------------------------------------------- 104 // DelayBasedBeginFrameSource ---------------------------------------------
162 SyntheticBeginFrameSource::SyntheticBeginFrameSource( 105 DelayBasedBeginFrameSource::DelayBasedBeginFrameSource(
163 base::SingleThreadTaskRunner* task_runner,
164 base::TimeDelta initial_vsync_interval)
165 : time_source_(
166 DelayBasedTimeSource::Create(initial_vsync_interval, task_runner)) {
167 time_source_->SetClient(this);
168 }
169
170 SyntheticBeginFrameSource::SyntheticBeginFrameSource(
171 std::unique_ptr<DelayBasedTimeSource> time_source) 106 std::unique_ptr<DelayBasedTimeSource> time_source)
172 : time_source_(std::move(time_source)) { 107 : time_source_(std::move(time_source)) {
173 time_source_->SetClient(this); 108 time_source_->SetClient(this);
174 } 109 }
175 110
176 SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {} 111 DelayBasedBeginFrameSource::~DelayBasedBeginFrameSource() = default;
177 112
178 void SyntheticBeginFrameSource::OnUpdateVSyncParameters( 113 void DelayBasedBeginFrameSource::OnUpdateVSyncParameters(
179 base::TimeTicks timebase, 114 base::TimeTicks timebase,
180 base::TimeDelta interval) { 115 base::TimeDelta interval) {
181 if (!authoritative_interval_.is_zero()) 116 if (!authoritative_interval_.is_zero()) {
182 interval = authoritative_interval_; 117 interval = authoritative_interval_;
118 } else if (interval.is_zero()) {
119 // TODO(brianderson): We should not be receiving 0 intervals.
120 interval = BeginFrameArgs::DefaultInterval();
121 }
183 122
184 last_timebase_ = timebase; 123 last_timebase_ = timebase;
185 time_source_->SetTimebaseAndInterval(timebase, interval); 124 time_source_->SetTimebaseAndInterval(timebase, interval);
186 } 125 }
187 126
188 void SyntheticBeginFrameSource::SetAuthoritativeVSyncInterval( 127 void DelayBasedBeginFrameSource::SetAuthoritativeVSyncInterval(
189 base::TimeDelta interval) { 128 base::TimeDelta interval) {
190 authoritative_interval_ = interval; 129 authoritative_interval_ = interval;
191 OnUpdateVSyncParameters(last_timebase_, interval); 130 OnUpdateVSyncParameters(last_timebase_, interval);
192 } 131 }
193 132
194 BeginFrameArgs SyntheticBeginFrameSource::CreateBeginFrameArgs( 133 BeginFrameArgs DelayBasedBeginFrameSource::CreateBeginFrameArgs(
195 base::TimeTicks frame_time, 134 base::TimeTicks frame_time,
196 BeginFrameArgs::BeginFrameArgsType type) { 135 BeginFrameArgs::BeginFrameArgsType type) {
197 return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, 136 return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time,
198 time_source_->NextTickTime(), 137 time_source_->NextTickTime(),
199 time_source_->Interval(), type); 138 time_source_->Interval(), type);
200 } 139 }
201 140
202 // BeginFrameSource support 141 void DelayBasedBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
203 void SyntheticBeginFrameSource::AddObserver(BeginFrameObserver* obs) { 142 DCHECK(obs);
204 BeginFrameSourceBase::AddObserver(obs); 143 DCHECK(observers_.find(obs) == observers_.end());
144
145 observers_.insert(obs);
146 obs->OnBeginFrameSourcePausedChanged(false);
147 time_source_->SetActive(true);
205 BeginFrameArgs args = CreateBeginFrameArgs( 148 BeginFrameArgs args = CreateBeginFrameArgs(
206 time_source_->NextTickTime() - time_source_->Interval(), 149 time_source_->NextTickTime() - time_source_->Interval(),
207 BeginFrameArgs::MISSED); 150 BeginFrameArgs::MISSED);
208 BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs(); 151 BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
209 if (!last_args.IsValid() || 152 if (!last_args.IsValid() ||
210 (args.frame_time > 153 (args.frame_time >
211 last_args.frame_time + args.interval / kDoubleTickDivisor)) { 154 last_args.frame_time + args.interval / kDoubleTickDivisor)) {
212 obs->OnBeginFrame(args); 155 obs->OnBeginFrame(args);
213 } 156 }
214 } 157 }
215 158
216 void SyntheticBeginFrameSource::OnNeedsBeginFramesChanged( 159 void DelayBasedBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) {
217 bool needs_begin_frames) { 160 DCHECK(obs);
218 time_source_->SetActive(needs_begin_frames); 161 DCHECK(observers_.find(obs) != observers_.end());
162
163 observers_.erase(obs);
164 if (observers_.empty())
165 time_source_->SetActive(false);
219 } 166 }
220 167
221 // DelayBasedTimeSourceClient support 168 void DelayBasedBeginFrameSource::OnTimerTick() {
222 void SyntheticBeginFrameSource::OnTimerTick() {
223 BeginFrameArgs args = CreateBeginFrameArgs(time_source_->LastTickTime(), 169 BeginFrameArgs args = CreateBeginFrameArgs(time_source_->LastTickTime(),
224 BeginFrameArgs::NORMAL); 170 BeginFrameArgs::NORMAL);
225 std::set<BeginFrameObserver*> observers(observers_); 171 std::unordered_set<BeginFrameObserver*> observers(observers_);
226 for (auto& it : observers) { 172 for (auto& obs : observers) {
227 BeginFrameArgs last_args = it->LastUsedBeginFrameArgs(); 173 BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
228 if (!last_args.IsValid() || 174 if (!last_args.IsValid() ||
229 (args.frame_time > 175 (args.frame_time >
230 last_args.frame_time + args.interval / kDoubleTickDivisor)) { 176 last_args.frame_time + args.interval / kDoubleTickDivisor))
231 it->OnBeginFrame(args); 177 obs->OnBeginFrame(args);
232 }
233 } 178 }
234 } 179 }
235 180
236 } // namespace cc 181 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/begin_frame_source.h ('k') | cc/scheduler/begin_frame_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698