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

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

Issue 2583483002: [cc] Adds source_id and sequence_number to BeginFrameArgs. (Closed)
Patch Set: fix field ordering Created 4 years 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/atomic_sequence_num.h"
9 #include "base/auto_reset.h" 10 #include "base/auto_reset.h"
10 #include "base/location.h" 11 #include "base/location.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/stringprintf.h" 15 #include "base/strings/stringprintf.h"
15 #include "base/trace_event/trace_event.h" 16 #include "base/trace_event/trace_event.h"
16 #include "base/trace_event/trace_event_argument.h" 17 #include "base/trace_event/trace_event_argument.h"
17 #include "cc/scheduler/delay_based_time_source.h" 18 #include "cc/scheduler/delay_based_time_source.h"
18 #include "cc/scheduler/scheduler.h" 19 #include "cc/scheduler/scheduler.h"
19 20
20 namespace cc { 21 namespace cc {
21 22
22 namespace { 23 namespace {
23 // kDoubleTickDivisor prevents the SyntheticBFS from sending BeginFrames too 24 // kDoubleTickDivisor prevents the SyntheticBFS from sending BeginFrames too
24 // often to an observer. 25 // often to an observer.
25 static const double kDoubleTickDivisor = 2.0; 26 static const double kDoubleTickDivisor = 2.0;
26 } 27 }
27 28
28 // BeginFrameObserverBase ----------------------------------------------- 29 // BeginFrameObserverBase -------------------------------------------------
29 BeginFrameObserverBase::BeginFrameObserverBase() 30 BeginFrameObserverBase::BeginFrameObserverBase()
30 : last_begin_frame_args_(), dropped_begin_frame_args_(0) { 31 : last_begin_frame_args_(), dropped_begin_frame_args_(0) {
31 } 32 }
32 33
33 const BeginFrameArgs& BeginFrameObserverBase::LastUsedBeginFrameArgs() const { 34 const BeginFrameArgs& BeginFrameObserverBase::LastUsedBeginFrameArgs() const {
34 return last_begin_frame_args_; 35 return last_begin_frame_args_;
35 } 36 }
37
36 void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) { 38 void BeginFrameObserverBase::OnBeginFrame(const BeginFrameArgs& args) {
37 DCHECK(args.IsValid()); 39 DCHECK(args.IsValid());
38 DCHECK(args.frame_time >= last_begin_frame_args_.frame_time); 40 DCHECK(args.frame_time >= last_begin_frame_args_.frame_time);
41 DCHECK(args.sequence_number > last_begin_frame_args_.sequence_number ||
42 args.source_id != last_begin_frame_args_.source_id);
39 bool used = OnBeginFrameDerivedImpl(args); 43 bool used = OnBeginFrameDerivedImpl(args);
40 if (used) { 44 if (used) {
41 last_begin_frame_args_ = args; 45 last_begin_frame_args_ = args;
42 } else { 46 } else {
43 ++dropped_begin_frame_args_; 47 ++dropped_begin_frame_args_;
44 } 48 }
45 } 49 }
46 50
51 // BeginFrameSource -------------------------------------------------------
52 namespace {
53 static base::StaticAtomicSequenceNumber g_next_source_id;
54 } // namespace
55
56 BeginFrameSource::BeginFrameSource() : source_id_(g_next_source_id.GetNext()) {}
57
58 uint32_t BeginFrameSource::source_id() const {
59 return source_id_;
60 }
61
62 // StubBeginFrameSource ---------------------------------------------------
47 bool StubBeginFrameSource::IsThrottled() const { 63 bool StubBeginFrameSource::IsThrottled() const {
48 return true; 64 return true;
49 } 65 }
50 66
51 // SyntheticBeginFrameSource --------------------------------------------- 67 // SyntheticBeginFrameSource ----------------------------------------------
52 SyntheticBeginFrameSource::~SyntheticBeginFrameSource() = default; 68 SyntheticBeginFrameSource::~SyntheticBeginFrameSource() = default;
53 69
54 // BackToBackBeginFrameSource -------------------------------------------- 70 // BackToBackBeginFrameSource ---------------------------------------------
55 BackToBackBeginFrameSource::BackToBackBeginFrameSource( 71 BackToBackBeginFrameSource::BackToBackBeginFrameSource(
56 std::unique_ptr<DelayBasedTimeSource> time_source) 72 std::unique_ptr<DelayBasedTimeSource> time_source)
57 : time_source_(std::move(time_source)), weak_factory_(this) { 73 : time_source_(std::move(time_source)),
74 next_sequence_number_(BeginFrameArgs::kStartingFrameNumber),
75 weak_factory_(this) {
58 time_source_->SetClient(this); 76 time_source_->SetClient(this);
59 // The time_source_ ticks immediately, so we SetActive(true) for a single 77 // The time_source_ ticks immediately, so we SetActive(true) for a single
60 // tick when we need it, and keep it as SetActive(false) otherwise. 78 // tick when we need it, and keep it as SetActive(false) otherwise.
61 time_source_->SetTimebaseAndInterval(base::TimeTicks(), base::TimeDelta()); 79 time_source_->SetTimebaseAndInterval(base::TimeTicks(), base::TimeDelta());
62 } 80 }
63 81
64 BackToBackBeginFrameSource::~BackToBackBeginFrameSource() = default; 82 BackToBackBeginFrameSource::~BackToBackBeginFrameSource() = default;
65 83
66 void BackToBackBeginFrameSource::AddObserver(BeginFrameObserver* obs) { 84 void BackToBackBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
67 DCHECK(obs); 85 DCHECK(obs);
(...skipping 22 matching lines...) Expand all
90 } 108 }
91 109
92 bool BackToBackBeginFrameSource::IsThrottled() const { 110 bool BackToBackBeginFrameSource::IsThrottled() const {
93 return false; 111 return false;
94 } 112 }
95 113
96 void BackToBackBeginFrameSource::OnTimerTick() { 114 void BackToBackBeginFrameSource::OnTimerTick() {
97 base::TimeTicks frame_time = time_source_->LastTickTime(); 115 base::TimeTicks frame_time = time_source_->LastTickTime();
98 base::TimeDelta default_interval = BeginFrameArgs::DefaultInterval(); 116 base::TimeDelta default_interval = BeginFrameArgs::DefaultInterval();
99 BeginFrameArgs args = BeginFrameArgs::Create( 117 BeginFrameArgs args = BeginFrameArgs::Create(
100 BEGINFRAME_FROM_HERE, frame_time, frame_time + default_interval, 118 BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_, frame_time,
101 default_interval, BeginFrameArgs::NORMAL); 119 frame_time + default_interval, default_interval, BeginFrameArgs::NORMAL);
120 next_sequence_number_++;
102 121
103 // This must happen after getting the LastTickTime() from the time source. 122 // This must happen after getting the LastTickTime() from the time source.
104 time_source_->SetActive(false); 123 time_source_->SetActive(false);
105 124
106 std::unordered_set<BeginFrameObserver*> pending_observers; 125 std::unordered_set<BeginFrameObserver*> pending_observers;
107 pending_observers.swap(pending_begin_frame_observers_); 126 pending_observers.swap(pending_begin_frame_observers_);
108 DCHECK(!pending_observers.empty()); 127 DCHECK(!pending_observers.empty());
109 for (BeginFrameObserver* obs : pending_observers) 128 for (BeginFrameObserver* obs : pending_observers)
110 obs->OnBeginFrame(args); 129 obs->OnBeginFrame(args);
111 } 130 }
112 131
113 // DelayBasedBeginFrameSource --------------------------------------------- 132 // DelayBasedBeginFrameSource ---------------------------------------------
114 DelayBasedBeginFrameSource::DelayBasedBeginFrameSource( 133 DelayBasedBeginFrameSource::DelayBasedBeginFrameSource(
115 std::unique_ptr<DelayBasedTimeSource> time_source) 134 std::unique_ptr<DelayBasedTimeSource> time_source)
116 : time_source_(std::move(time_source)) { 135 : time_source_(std::move(time_source)),
136 next_sequence_number_(BeginFrameArgs::kStartingFrameNumber) {
117 time_source_->SetClient(this); 137 time_source_->SetClient(this);
118 } 138 }
119 139
120 DelayBasedBeginFrameSource::~DelayBasedBeginFrameSource() = default; 140 DelayBasedBeginFrameSource::~DelayBasedBeginFrameSource() = default;
121 141
122 void DelayBasedBeginFrameSource::OnUpdateVSyncParameters( 142 void DelayBasedBeginFrameSource::OnUpdateVSyncParameters(
123 base::TimeTicks timebase, 143 base::TimeTicks timebase,
124 base::TimeDelta interval) { 144 base::TimeDelta interval) {
125 if (!authoritative_interval_.is_zero()) { 145 if (!authoritative_interval_.is_zero()) {
126 interval = authoritative_interval_; 146 interval = authoritative_interval_;
127 } else if (interval.is_zero()) { 147 } else if (interval.is_zero()) {
128 // TODO(brianderson): We should not be receiving 0 intervals. 148 // TODO(brianderson): We should not be receiving 0 intervals.
129 interval = BeginFrameArgs::DefaultInterval(); 149 interval = BeginFrameArgs::DefaultInterval();
130 } 150 }
131 151
132 last_timebase_ = timebase; 152 last_timebase_ = timebase;
133 time_source_->SetTimebaseAndInterval(timebase, interval); 153 time_source_->SetTimebaseAndInterval(timebase, interval);
134 } 154 }
135 155
136 void DelayBasedBeginFrameSource::SetAuthoritativeVSyncInterval( 156 void DelayBasedBeginFrameSource::SetAuthoritativeVSyncInterval(
137 base::TimeDelta interval) { 157 base::TimeDelta interval) {
138 authoritative_interval_ = interval; 158 authoritative_interval_ = interval;
139 OnUpdateVSyncParameters(last_timebase_, interval); 159 OnUpdateVSyncParameters(last_timebase_, interval);
140 } 160 }
141 161
142 BeginFrameArgs DelayBasedBeginFrameSource::CreateBeginFrameArgs( 162 BeginFrameArgs DelayBasedBeginFrameSource::CreateBeginFrameArgs(
143 base::TimeTicks frame_time, 163 base::TimeTicks frame_time,
144 BeginFrameArgs::BeginFrameArgsType type) { 164 BeginFrameArgs::BeginFrameArgsType type) {
145 return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, frame_time, 165 uint64_t sequence_number = next_sequence_number_++;
146 time_source_->NextTickTime(), 166 return BeginFrameArgs::Create(
147 time_source_->Interval(), type); 167 BEGINFRAME_FROM_HERE, source_id(), sequence_number, frame_time,
168 time_source_->NextTickTime(), time_source_->Interval(), type);
148 } 169 }
149 170
150 void DelayBasedBeginFrameSource::AddObserver(BeginFrameObserver* obs) { 171 void DelayBasedBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
151 DCHECK(obs); 172 DCHECK(obs);
152 DCHECK(observers_.find(obs) == observers_.end()); 173 DCHECK(observers_.find(obs) == observers_.end());
153 174
154 observers_.insert(obs); 175 observers_.insert(obs);
155 obs->OnBeginFrameSourcePausedChanged(false); 176 obs->OnBeginFrameSourcePausedChanged(false);
156 time_source_->SetActive(true); 177 time_source_->SetActive(true);
157 BeginFrameArgs args = CreateBeginFrameArgs( 178
158 time_source_->NextTickTime() - time_source_->Interval(), 179 // Missed args should correspond to |current_begin_frame_args_| (particularly,
159 BeginFrameArgs::MISSED); 180 // have the same sequence number) if |current_begin_frame_args_| still
181 // correspond to the last time the time source should have ticked. This may
182 // not be the case if OnTimerTick() has never run yet, the time source was
183 // inactive before AddObserver() was called, or the interval changed. In such
184 // a case, we create new args with a new sequence number.
185 base::TimeTicks last_or_missed_tick_time =
186 time_source_->NextTickTime() - time_source_->Interval();
187 if (current_begin_frame_args_.IsValid() &&
188 current_begin_frame_args_.frame_time == last_or_missed_tick_time &&
189 current_begin_frame_args_.interval == time_source_->Interval()) {
190 // Ensure that the args have the right type.
191 current_begin_frame_args_.type = BeginFrameArgs::MISSED;
192 } else {
193 // The args are not up to date and we need to create new ones with the
194 // missed tick's time and a new sequence number.
195 current_begin_frame_args_ =
196 CreateBeginFrameArgs(last_or_missed_tick_time, BeginFrameArgs::MISSED);
197 }
198
160 BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs(); 199 BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
161 if (!last_args.IsValid() || 200 if (!last_args.IsValid() ||
162 (args.frame_time > 201 (current_begin_frame_args_.frame_time >
163 last_args.frame_time + args.interval / kDoubleTickDivisor)) { 202 last_args.frame_time +
164 obs->OnBeginFrame(args); 203 current_begin_frame_args_.interval / kDoubleTickDivisor)) {
204 obs->OnBeginFrame(current_begin_frame_args_);
165 } 205 }
166 } 206 }
167 207
168 void DelayBasedBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) { 208 void DelayBasedBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) {
169 DCHECK(obs); 209 DCHECK(obs);
170 DCHECK(observers_.find(obs) != observers_.end()); 210 DCHECK(observers_.find(obs) != observers_.end());
171 211
172 observers_.erase(obs); 212 observers_.erase(obs);
173 if (observers_.empty()) 213 if (observers_.empty())
174 time_source_->SetActive(false); 214 time_source_->SetActive(false);
175 } 215 }
176 216
177 bool DelayBasedBeginFrameSource::IsThrottled() const { 217 bool DelayBasedBeginFrameSource::IsThrottled() const {
178 return true; 218 return true;
179 } 219 }
180 220
181 void DelayBasedBeginFrameSource::OnTimerTick() { 221 void DelayBasedBeginFrameSource::OnTimerTick() {
182 BeginFrameArgs args = CreateBeginFrameArgs(time_source_->LastTickTime(), 222 current_begin_frame_args_ = CreateBeginFrameArgs(time_source_->LastTickTime(),
183 BeginFrameArgs::NORMAL); 223 BeginFrameArgs::NORMAL);
184 std::unordered_set<BeginFrameObserver*> observers(observers_); 224 std::unordered_set<BeginFrameObserver*> observers(observers_);
185 for (auto* obs : observers) { 225 for (auto* obs : observers) {
186 BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs(); 226 BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
187 if (!last_args.IsValid() || 227 if (!last_args.IsValid() ||
188 (args.frame_time > 228 (current_begin_frame_args_.frame_time >
189 last_args.frame_time + args.interval / kDoubleTickDivisor)) 229 last_args.frame_time +
190 obs->OnBeginFrame(args); 230 current_begin_frame_args_.interval / kDoubleTickDivisor)) {
231 obs->OnBeginFrame(current_begin_frame_args_);
232 }
191 } 233 }
192 } 234 }
193 235
236 // ExternalBeginFrameSource -----------------------------------------------
194 ExternalBeginFrameSource::ExternalBeginFrameSource( 237 ExternalBeginFrameSource::ExternalBeginFrameSource(
195 ExternalBeginFrameSourceClient* client) 238 ExternalBeginFrameSourceClient* client)
196 : client_(client) { 239 : client_(client) {
197 DCHECK(client_); 240 DCHECK(client_);
198 } 241 }
199 242
200 ExternalBeginFrameSource::~ExternalBeginFrameSource() = default; 243 ExternalBeginFrameSource::~ExternalBeginFrameSource() = default;
201 244
202 void ExternalBeginFrameSource::AddObserver(BeginFrameObserver* obs) { 245 void ExternalBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
203 DCHECK(obs); 246 DCHECK(obs);
204 DCHECK(observers_.find(obs) == observers_.end()); 247 DCHECK(observers_.find(obs) == observers_.end());
205 248
206 bool observers_was_empty = observers_.empty(); 249 bool observers_was_empty = observers_.empty();
207 observers_.insert(obs); 250 observers_.insert(obs);
208 obs->OnBeginFrameSourcePausedChanged(paused_); 251 obs->OnBeginFrameSourcePausedChanged(paused_);
209 if (observers_was_empty) 252 if (observers_was_empty)
210 client_->OnNeedsBeginFrames(true); 253 client_->OnNeedsBeginFrames(true);
211 254
212 // Send a MISSED begin frame if necessary. 255 // Send a MISSED begin frame if necessary.
213 if (missed_begin_frame_args_.IsValid()) { 256 if (missed_begin_frame_args_.IsValid()) {
214 BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs(); 257 BeginFrameArgs last_args = obs->LastUsedBeginFrameArgs();
215 if (!last_args.IsValid() || 258 if (!last_args.IsValid() ||
216 (missed_begin_frame_args_.frame_time > last_args.frame_time)) { 259 (missed_begin_frame_args_.frame_time > last_args.frame_time)) {
260 DCHECK((missed_begin_frame_args_.source_id != last_args.source_id) ||
261 (missed_begin_frame_args_.sequence_number >
262 last_args.sequence_number));
217 obs->OnBeginFrame(missed_begin_frame_args_); 263 obs->OnBeginFrame(missed_begin_frame_args_);
218 } 264 }
219 } 265 }
220 } 266 }
221 267
222 void ExternalBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) { 268 void ExternalBeginFrameSource::RemoveObserver(BeginFrameObserver* obs) {
223 DCHECK(obs); 269 DCHECK(obs);
224 DCHECK(observers_.find(obs) != observers_.end()); 270 DCHECK(observers_.find(obs) != observers_.end());
225 271
226 observers_.erase(obs); 272 observers_.erase(obs);
(...skipping 18 matching lines...) Expand all
245 291
246 void ExternalBeginFrameSource::OnBeginFrame(const BeginFrameArgs& args) { 292 void ExternalBeginFrameSource::OnBeginFrame(const BeginFrameArgs& args) {
247 missed_begin_frame_args_ = args; 293 missed_begin_frame_args_ = args;
248 missed_begin_frame_args_.type = BeginFrameArgs::MISSED; 294 missed_begin_frame_args_.type = BeginFrameArgs::MISSED;
249 std::unordered_set<BeginFrameObserver*> observers(observers_); 295 std::unordered_set<BeginFrameObserver*> observers(observers_);
250 for (auto* obs : observers) 296 for (auto* obs : observers)
251 obs->OnBeginFrame(args); 297 obs->OnBeginFrame(args);
252 } 298 }
253 299
254 } // namespace cc 300 } // 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