OLD | NEW |
---|---|
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 "base/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/location.h" | 8 #include "base/location.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
26 arg2_val); | 26 arg2_val); |
27 #endif | 27 #endif |
28 | 28 |
29 namespace cc { | 29 namespace cc { |
30 | 30 |
31 // BeginFrameObserverMixIn ----------------------------------------------- | 31 // BeginFrameObserverMixIn ----------------------------------------------- |
32 BeginFrameObserverMixIn::BeginFrameObserverMixIn() | 32 BeginFrameObserverMixIn::BeginFrameObserverMixIn() |
33 : last_begin_frame_args_(), dropped_begin_frame_args_(0) { | 33 : last_begin_frame_args_(), dropped_begin_frame_args_(0) { |
34 } | 34 } |
35 | 35 |
36 const BeginFrameArgs BeginFrameObserverMixIn::LastUsedBeginFrameArgs() const { | 36 const BeginFrameArgs BeginFrameObserverMixIn::LastUsedBeginFrameArgs() { |
37 return last_begin_frame_args_; | 37 return last_begin_frame_args_; |
38 } | 38 } |
39 void BeginFrameObserverMixIn::OnBeginFrame(const BeginFrameArgs& args) { | 39 void BeginFrameObserverMixIn::OnBeginFrame(const BeginFrameArgs& args) { |
40 DEBUG_FRAMES("BeginFrameObserverMixIn::OnBeginFrame", | 40 DEBUG_FRAMES("BeginFrameObserverMixIn::OnBeginFrame", |
41 "last args", | 41 "last args", |
42 last_begin_frame_args_.AsValue(), | 42 last_begin_frame_args_.AsValue(), |
43 "new args", | 43 "new args", |
44 args.AsValue()); | 44 args.AsValue()); |
45 DCHECK(args.IsValid()); | 45 DCHECK(args.IsValid()); |
46 DCHECK(args.frame_time >= last_begin_frame_args_.frame_time); | 46 DCHECK(args.frame_time >= last_begin_frame_args_.frame_time); |
47 bool used = OnBeginFrameMixInDelegate(args); | 47 bool used = OnBeginFrameMixInDelegate(args); |
48 if (used) { | 48 if (used) { |
49 last_begin_frame_args_ = args; | 49 last_begin_frame_args_ = args; |
50 } else { | 50 } else { |
51 ++dropped_begin_frame_args_; | 51 ++dropped_begin_frame_args_; |
52 } | 52 } |
53 } | 53 } |
54 | 54 |
55 void BeginFrameObserverMixIn::AsValueInto( | 55 void BeginFrameObserverMixIn::AsValueInto( |
56 base::trace_event::TracedValue* dict) const { | 56 base::trace_event::TracedValue* dict) { |
57 dict->BeginDictionary("last_begin_frame_args_"); | 57 dict->BeginDictionary("last_begin_frame_args_"); |
58 last_begin_frame_args_.AsValueInto(dict); | 58 last_begin_frame_args_.AsValueInto(dict); |
59 dict->EndDictionary(); | 59 dict->EndDictionary(); |
60 dict->SetInteger("dropped_begin_frame_args_", dropped_begin_frame_args_); | 60 dict->SetInteger("dropped_begin_frame_args_", dropped_begin_frame_args_); |
61 } | 61 } |
62 | 62 |
63 // BeginFrameSourceMixIn ------------------------------------------------------ | 63 // BeginFrameSourceMixIn ------------------------------------------------------ |
64 BeginFrameSourceMixIn::BeginFrameSourceMixIn() | 64 BeginFrameSourceMixIn::BeginFrameSourceMixIn() |
65 : observer_(NULL), | 65 : observer_list_(), |
66 needs_begin_frames_(false), | 66 needs_begin_frames_(false), |
67 inside_as_value_into_(false) { | 67 inside_as_value_into_(false) { |
68 DCHECK(!observer_); | |
69 DCHECK_EQ(inside_as_value_into_, false); | 68 DCHECK_EQ(inside_as_value_into_, false); |
70 } | 69 } |
71 | 70 |
71 BeginFrameSourceMixIn::~BeginFrameSourceMixIn() { | |
72 } | |
73 | |
72 bool BeginFrameSourceMixIn::NeedsBeginFrames() const { | 74 bool BeginFrameSourceMixIn::NeedsBeginFrames() const { |
73 return needs_begin_frames_; | 75 return needs_begin_frames_; |
74 } | 76 } |
75 | 77 |
76 void BeginFrameSourceMixIn::SetNeedsBeginFrames(bool needs_begin_frames) { | 78 void BeginFrameSourceMixIn::SetNeedsBeginFrames(bool needs_begin_frames) { |
77 DEBUG_FRAMES("BeginFrameSourceMixIn::SetNeedsBeginFrames", | 79 DEBUG_FRAMES("BeginFrameSourceMixIn::SetNeedsBeginFrames", |
78 "current state", | 80 "current state", |
79 needs_begin_frames_, | 81 needs_begin_frames_, |
80 "new state", | 82 "new state", |
81 needs_begin_frames); | 83 needs_begin_frames); |
82 if (needs_begin_frames_ != needs_begin_frames) { | 84 if (needs_begin_frames_ != needs_begin_frames) { |
83 needs_begin_frames_ = needs_begin_frames; | 85 needs_begin_frames_ = needs_begin_frames; |
84 OnNeedsBeginFramesChange(needs_begin_frames); | 86 OnNeedsBeginFramesChange(needs_begin_frames); |
85 } | 87 } |
86 } | 88 } |
87 | 89 |
88 void BeginFrameSourceMixIn::AddObserver(BeginFrameObserver* obs) { | 90 void BeginFrameSourceMixIn::AddObserver(BeginFrameObserver* obs) { |
89 DEBUG_FRAMES("BeginFrameSourceMixIn::AddObserver", | 91 DEBUG_FRAMES("BeginFrameSourceMixIn::AddObserver", "has observers?", |
90 "current observer", | 92 (observer_list_).might_have_observers(), "to add observer", obs); |
91 observer_, | 93 DCHECK(obs); |
92 "to add observer", | 94 DCHECK(!observer_list_.HasObserver(obs)); |
93 obs); | 95 observer_list_.AddObserver(obs); |
94 DCHECK(!observer_); | |
95 observer_ = obs; | |
96 } | 96 } |
97 | 97 |
98 void BeginFrameSourceMixIn::RemoveObserver(BeginFrameObserver* obs) { | 98 void BeginFrameSourceMixIn::RemoveObserver(BeginFrameObserver* obs) { |
99 DEBUG_FRAMES("BeginFrameSourceMixIn::RemoveObserver", | 99 DEBUG_FRAMES("BeginFrameSourceMixIn::RemoveObserver", "has observers?", |
100 "current observer", | 100 (observer_list_).might_have_observers(), "to remove observer", |
101 observer_, | |
102 "to remove observer", | |
103 obs); | 101 obs); |
104 DCHECK_EQ(observer_, obs); | 102 DCHECK(obs); |
105 observer_ = NULL; | 103 DCHECK(observer_list_.HasObserver(obs)); |
104 observer_list_.RemoveObserver(obs); | |
106 } | 105 } |
107 | 106 |
108 void BeginFrameSourceMixIn::CallOnBeginFrame(const BeginFrameArgs& args) { | 107 void BeginFrameSourceMixIn::CallOnBeginFrame(const BeginFrameArgs& args) { |
109 DEBUG_FRAMES("BeginFrameSourceMixIn::CallOnBeginFrame", | 108 DEBUG_FRAMES("BeginFrameSourceMixIn::CallOnBeginFrame", "has observers?", |
110 "current observer", | 109 observer_list_.might_have_observers(), "args", args.AsValue()); |
111 observer_, | 110 FOR_EACH_OBSERVER(BeginFrameObserver, observer_list_, OnBeginFrame(args)); |
112 "args", | |
113 args.AsValue()); | |
114 if (observer_) { | |
115 return observer_->OnBeginFrame(args); | |
116 } | |
117 } | 111 } |
118 | 112 |
119 // Tracing support | 113 // Tracing support |
120 void BeginFrameSourceMixIn::AsValueInto( | 114 void BeginFrameSourceMixIn::AsValueInto(base::trace_event::TracedValue* dict) { |
121 base::trace_event::TracedValue* dict) const { | |
122 // As the observer might try to trace the source, prevent an infinte loop | 115 // As the observer might try to trace the source, prevent an infinte loop |
123 // from occuring. | 116 // from occuring. |
124 if (inside_as_value_into_) { | 117 if (inside_as_value_into_) { |
125 dict->SetString("observer", "<loop detected>"); | 118 dict->SetString("observer", "<loop detected>"); |
126 return; | 119 return; |
127 } | 120 } |
121 base::AutoReset<bool> prevent_loops(const_cast<bool*>(&inside_as_value_into_), | |
122 true); | |
128 | 123 |
129 if (observer_) { | 124 dict->SetBoolean("needs_begin_frames", NeedsBeginFrames()); |
130 base::AutoReset<bool> prevent_loops( | 125 if (observer_list_.might_have_observers()) { |
131 const_cast<bool*>(&inside_as_value_into_), true); | 126 ObserverList<BeginFrameObserver>::Iterator it(&observer_list_); |
132 dict->BeginDictionary("observer"); | 127 BeginFrameObserver* obs; |
133 observer_->AsValueInto(dict); | 128 dict->BeginArray("observers"); |
134 dict->EndDictionary(); | 129 while ((obs = it.GetNext()) != NULL) { |
135 } else { | 130 dict->BeginDictionary(); |
136 dict->SetString("observer", "NULL"); | 131 obs->AsValueInto(dict); |
132 dict->EndDictionary(); | |
133 } | |
134 dict->EndArray(); | |
137 } | 135 } |
138 dict->SetBoolean("needs_begin_frames", NeedsBeginFrames()); | |
139 } | 136 } |
140 | 137 |
141 // BackToBackBeginFrameSourceMixIn -------------------------------------------- | 138 // BackToBackBeginFrameSourceMixIn -------------------------------------------- |
142 scoped_ptr<BackToBackBeginFrameSource> BackToBackBeginFrameSource::Create( | 139 scoped_ptr<BackToBackBeginFrameSource> BackToBackBeginFrameSource::Create( |
143 base::SingleThreadTaskRunner* task_runner) { | 140 base::SingleThreadTaskRunner* task_runner) { |
144 return make_scoped_ptr(new BackToBackBeginFrameSource(task_runner)); | 141 return make_scoped_ptr(new BackToBackBeginFrameSource(task_runner)); |
145 } | 142 } |
146 | 143 |
147 BackToBackBeginFrameSource::BackToBackBeginFrameSource( | 144 BackToBackBeginFrameSource::BackToBackBeginFrameSource( |
148 base::SingleThreadTaskRunner* task_runner) | 145 base::SingleThreadTaskRunner* task_runner) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 // BeginFrameSource support | 189 // BeginFrameSource support |
193 | 190 |
194 void BackToBackBeginFrameSource::DidFinishFrame(size_t remaining_frames) { | 191 void BackToBackBeginFrameSource::DidFinishFrame(size_t remaining_frames) { |
195 if (remaining_frames == 0) { | 192 if (remaining_frames == 0) { |
196 OnNeedsBeginFramesChange(NeedsBeginFrames()); | 193 OnNeedsBeginFramesChange(NeedsBeginFrames()); |
197 } | 194 } |
198 } | 195 } |
199 | 196 |
200 // Tracing support | 197 // Tracing support |
201 void BackToBackBeginFrameSource::AsValueInto( | 198 void BackToBackBeginFrameSource::AsValueInto( |
202 base::trace_event::TracedValue* dict) const { | 199 base::trace_event::TracedValue* dict) { |
danakj
2015/03/25 18:12:55
What's with all the const changes? AsValueInto can
mithro-old
2015/03/26 00:54:49
The AsValueInto loops over each of the observers.
| |
203 dict->SetString("type", "BackToBackBeginFrameSource"); | 200 dict->SetString("type", "BackToBackBeginFrameSource"); |
204 BeginFrameSourceMixIn::AsValueInto(dict); | 201 BeginFrameSourceMixIn::AsValueInto(dict); |
205 dict->SetBoolean("send_begin_frame_posted_", send_begin_frame_posted_); | 202 dict->SetBoolean("send_begin_frame_posted_", send_begin_frame_posted_); |
206 } | 203 } |
207 | 204 |
208 // SyntheticBeginFrameSource --------------------------------------------- | 205 // SyntheticBeginFrameSource --------------------------------------------- |
209 scoped_ptr<SyntheticBeginFrameSource> SyntheticBeginFrameSource::Create( | 206 scoped_ptr<SyntheticBeginFrameSource> SyntheticBeginFrameSource::Create( |
210 base::SingleThreadTaskRunner* task_runner, | 207 base::SingleThreadTaskRunner* task_runner, |
211 base::TimeTicks initial_vsync_timebase, | 208 base::TimeTicks initial_vsync_timebase, |
212 base::TimeDelta initial_vsync_interval) { | 209 base::TimeDelta initial_vsync_interval) { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
260 base::TimeTicks missed_tick_time = | 257 base::TimeTicks missed_tick_time = |
261 time_source_->SetActive(needs_begin_frames); | 258 time_source_->SetActive(needs_begin_frames); |
262 if (!missed_tick_time.is_null()) { | 259 if (!missed_tick_time.is_null()) { |
263 CallOnBeginFrame( | 260 CallOnBeginFrame( |
264 CreateBeginFrameArgs(missed_tick_time, BeginFrameArgs::MISSED)); | 261 CreateBeginFrameArgs(missed_tick_time, BeginFrameArgs::MISSED)); |
265 } | 262 } |
266 } | 263 } |
267 | 264 |
268 // Tracing support | 265 // Tracing support |
269 void SyntheticBeginFrameSource::AsValueInto( | 266 void SyntheticBeginFrameSource::AsValueInto( |
270 base::trace_event::TracedValue* dict) const { | 267 base::trace_event::TracedValue* dict) { |
271 dict->SetString("type", "SyntheticBeginFrameSource"); | 268 dict->SetString("type", "SyntheticBeginFrameSource"); |
272 BeginFrameSourceMixIn::AsValueInto(dict); | 269 BeginFrameSourceMixIn::AsValueInto(dict); |
273 | 270 |
274 dict->BeginDictionary("time_source"); | 271 dict->BeginDictionary("time_source"); |
275 time_source_->AsValueInto(dict); | 272 time_source_->AsValueInto(dict); |
276 dict->EndDictionary(); | 273 dict->EndDictionary(); |
277 } | 274 } |
278 | 275 |
279 // BeginFrameSourceMultiplexer ------------------------------------------- | 276 // BeginFrameSourceMultiplexer ------------------------------------------- |
280 scoped_ptr<BeginFrameSourceMultiplexer> BeginFrameSourceMultiplexer::Create() { | 277 scoped_ptr<BeginFrameSourceMultiplexer> BeginFrameSourceMultiplexer::Create() { |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
387 return; | 384 return; |
388 } | 385 } |
389 DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnBeginFrame", | 386 DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnBeginFrame", |
390 "action", | 387 "action", |
391 "using", | 388 "using", |
392 "new args", | 389 "new args", |
393 args.AsValue()); | 390 args.AsValue()); |
394 CallOnBeginFrame(args); | 391 CallOnBeginFrame(args); |
395 } | 392 } |
396 | 393 |
397 const BeginFrameArgs BeginFrameSourceMultiplexer::LastUsedBeginFrameArgs() | 394 const BeginFrameArgs BeginFrameSourceMultiplexer::LastUsedBeginFrameArgs() { |
398 const { | 395 BeginFrameArgs last; |
399 if (observer_) | 396 |
400 return observer_->LastUsedBeginFrameArgs(); | 397 if ((observer_list_).might_have_observers()) { |
401 else | 398 ObserverList<BeginFrameObserver>::Iterator it(&observer_list_); |
402 return BeginFrameArgs(); | 399 BeginFrameObserver* obs; |
400 while ((obs = it.GetNext()) != NULL) { | |
401 BeginFrameArgs obs_last = obs->LastUsedBeginFrameArgs(); | |
402 if (obs_last.frame_time > last.frame_time) | |
403 last = obs_last; | |
404 } | |
405 } | |
406 return last; | |
403 } | 407 } |
404 | 408 |
405 // BeginFrameSource support | 409 // BeginFrameSource support |
406 void BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange( | 410 void BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange( |
407 bool needs_begin_frames) { | 411 bool needs_begin_frames) { |
408 DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange", | 412 DEBUG_FRAMES("BeginFrameSourceMultiplexer::OnNeedsBeginFramesChange", |
409 "active_source", active_source_, "needs_begin_frames", | 413 "active_source", active_source_, "needs_begin_frames", |
410 needs_begin_frames); | 414 needs_begin_frames); |
411 if (active_source_) { | 415 if (active_source_) { |
412 active_source_->SetNeedsBeginFrames(needs_begin_frames); | 416 active_source_->SetNeedsBeginFrames(needs_begin_frames); |
413 } else { | 417 } else { |
414 DCHECK(!needs_begin_frames); | 418 DCHECK(!needs_begin_frames); |
415 } | 419 } |
416 } | 420 } |
417 | 421 |
418 void BeginFrameSourceMultiplexer::DidFinishFrame(size_t remaining_frames) { | 422 void BeginFrameSourceMultiplexer::DidFinishFrame(size_t remaining_frames) { |
419 DEBUG_FRAMES("BeginFrameSourceMultiplexer::DidFinishFrame", | 423 DEBUG_FRAMES("BeginFrameSourceMultiplexer::DidFinishFrame", |
420 "active_source", | 424 "active_source", |
421 active_source_, | 425 active_source_, |
422 "remaining_frames", | 426 "remaining_frames", |
423 remaining_frames); | 427 remaining_frames); |
424 if (active_source_) { | 428 if (active_source_) { |
425 active_source_->DidFinishFrame(remaining_frames); | 429 active_source_->DidFinishFrame(remaining_frames); |
426 } | 430 } |
427 } | 431 } |
428 | 432 |
429 // Tracing support | 433 // Tracing support |
430 void BeginFrameSourceMultiplexer::AsValueInto( | 434 void BeginFrameSourceMultiplexer::AsValueInto( |
431 base::trace_event::TracedValue* dict) const { | 435 base::trace_event::TracedValue* dict) { |
432 dict->SetString("type", "BeginFrameSourceMultiplexer"); | 436 dict->SetString("type", "BeginFrameSourceMultiplexer"); |
437 BeginFrameSourceMixIn::AsValueInto(dict); | |
433 | 438 |
434 dict->SetInteger("minimum_interval_us", minimum_interval_.InMicroseconds()); | 439 dict->SetInteger("minimum_interval_us", minimum_interval_.InMicroseconds()); |
435 if (observer_) { | |
436 dict->BeginDictionary("last_begin_frame_args"); | |
437 observer_->LastUsedBeginFrameArgs().AsValueInto(dict); | |
438 dict->EndDictionary(); | |
439 } | |
440 | |
441 if (active_source_) { | 440 if (active_source_) { |
442 dict->BeginDictionary("active_source"); | 441 dict->BeginDictionary("active_source"); |
443 active_source_->AsValueInto(dict); | 442 active_source_->AsValueInto(dict); |
444 dict->EndDictionary(); | 443 dict->EndDictionary(); |
445 } else { | 444 } else { |
446 dict->SetString("active_source", "NULL"); | 445 dict->SetString("active_source", "NULL"); |
447 } | 446 } |
448 | 447 |
449 dict->BeginArray("sources"); | 448 dict->BeginArray("sources"); |
450 for (std::set<BeginFrameSource*>::const_iterator it = source_list_.begin(); | 449 for (std::set<BeginFrameSource*>::const_iterator it = source_list_.begin(); |
451 it != source_list_.end(); | 450 it != source_list_.end(); |
452 ++it) { | 451 ++it) { |
453 dict->BeginDictionary(); | 452 dict->BeginDictionary(); |
454 (*it)->AsValueInto(dict); | 453 (*it)->AsValueInto(dict); |
455 dict->EndDictionary(); | 454 dict->EndDictionary(); |
456 } | 455 } |
457 dict->EndArray(); | 456 dict->EndArray(); |
458 } | 457 } |
459 | 458 |
460 // protected methods | 459 // protected methods |
461 bool BeginFrameSourceMultiplexer::HasSource(BeginFrameSource* source) { | 460 bool BeginFrameSourceMultiplexer::HasSource(BeginFrameSource* source) { |
462 return (source_list_.find(source) != source_list_.end()); | 461 return (source_list_.find(source) != source_list_.end()); |
463 } | 462 } |
464 | 463 |
465 bool BeginFrameSourceMultiplexer::IsIncreasing(const BeginFrameArgs& args) { | 464 bool BeginFrameSourceMultiplexer::IsIncreasing(const BeginFrameArgs& args) { |
466 DCHECK(args.IsValid()); | 465 DCHECK(args.IsValid()); |
467 if (!observer_) | |
468 return false; | |
469 | 466 |
470 // If the last begin frame is invalid, then any new begin frame is valid. | 467 // If the last begin frame is invalid, then any new begin frame is valid. |
471 if (!observer_->LastUsedBeginFrameArgs().IsValid()) | 468 if (!LastUsedBeginFrameArgs().IsValid()) |
472 return true; | 469 return true; |
473 | 470 |
474 // Only allow new args have a *strictly bigger* frame_time value and statisfy | 471 // Only allow new args have a *strictly bigger* frame_time value and statisfy |
475 // minimum interval requirement. | 472 // minimum interval requirement. |
476 return (args.frame_time >= | 473 return (args.frame_time >= |
477 observer_->LastUsedBeginFrameArgs().frame_time + minimum_interval_); | 474 LastUsedBeginFrameArgs().frame_time + minimum_interval_); |
478 } | 475 } |
479 | 476 |
480 } // namespace cc | 477 } // namespace cc |
OLD | NEW |