Chromium Code Reviews| 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 |