OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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/scheduler.h" | 5 #include "cc/scheduler/scheduler.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
11 #include "base/debug/trace_event_argument.h" | 11 #include "base/debug/trace_event_argument.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/single_thread_task_runner.h" | 13 #include "base/single_thread_task_runner.h" |
14 #include "cc/debug/devtools_instrumentation.h" | 14 #include "cc/debug/devtools_instrumentation.h" |
15 #include "cc/debug/traced_value.h" | 15 #include "cc/debug/traced_value.h" |
16 #include "cc/scheduler/delay_based_time_source.h" | 16 #include "cc/scheduler/delay_based_time_source.h" |
17 #include "ui/gfx/frame_time.h" | 17 #include "ui/gfx/frame_time.h" |
18 | 18 |
19 namespace cc { | 19 namespace cc { |
20 | 20 |
21 BeginFrameSource* SchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource( | 21 BeginFrameSource* SchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource( |
22 Scheduler* scheduler) { | 22 Scheduler* scheduler) { |
23 if (!scheduler->settings_.throttle_frame_production) { | 23 if (scheduler->settings_.use_external_begin_frame_source) { |
24 TRACE_EVENT1("cc", | 24 TRACE_EVENT1("cc", |
25 "Scheduler::Scheduler()", | 25 "Scheduler::Scheduler()", |
26 "PrimaryFrameSource", | 26 "PrimaryFrameSource", |
27 "BackToBackBeginFrameSource"); | |
28 DCHECK(!scheduler->primary_frame_source_internal_); | |
29 scheduler->primary_frame_source_internal_ = | |
30 BackToBackBeginFrameSource::Create(scheduler->task_runner_.get()); | |
31 return scheduler->primary_frame_source_internal_.get(); | |
32 } else if (scheduler->settings_.use_external_begin_frame_source) { | |
33 TRACE_EVENT1("cc", | |
34 "Scheduler::Scheduler()", | |
35 "PrimaryFrameSource", | |
36 "ExternalBeginFrameSource"); | 27 "ExternalBeginFrameSource"); |
37 DCHECK(scheduler->primary_frame_source_internal_) | 28 DCHECK(scheduler->primary_frame_source_internal_) |
38 << "Need external BeginFrameSource"; | 29 << "Need external BeginFrameSource"; |
39 return scheduler->primary_frame_source_internal_.get(); | 30 return scheduler->primary_frame_source_internal_.get(); |
40 } else { | 31 } else { |
41 TRACE_EVENT1("cc", | 32 TRACE_EVENT1("cc", |
42 "Scheduler::Scheduler()", | 33 "Scheduler::Scheduler()", |
43 "PrimaryFrameSource", | 34 "PrimaryFrameSource", |
44 "SyntheticBeginFrameSource"); | 35 "SyntheticBeginFrameSource"); |
45 scoped_ptr<SyntheticBeginFrameSource> synthetic_source = | 36 scoped_ptr<SyntheticBeginFrameSource> synthetic_source = |
(...skipping 18 matching lines...) Expand all Loading... |
64 "BackgroundFrameSource", | 55 "BackgroundFrameSource", |
65 "SyntheticBeginFrameSource"); | 56 "SyntheticBeginFrameSource"); |
66 DCHECK(!(scheduler->background_frame_source_internal_)); | 57 DCHECK(!(scheduler->background_frame_source_internal_)); |
67 scheduler->background_frame_source_internal_ = | 58 scheduler->background_frame_source_internal_ = |
68 SyntheticBeginFrameSource::Create( | 59 SyntheticBeginFrameSource::Create( |
69 scheduler->task_runner_.get(), scheduler->Now(), | 60 scheduler->task_runner_.get(), scheduler->Now(), |
70 scheduler->settings_.background_frame_interval); | 61 scheduler->settings_.background_frame_interval); |
71 return scheduler->background_frame_source_internal_.get(); | 62 return scheduler->background_frame_source_internal_.get(); |
72 } | 63 } |
73 | 64 |
| 65 BeginFrameSource* |
| 66 SchedulerFrameSourcesConstructor::ConstructUnthrottledFrameSource( |
| 67 Scheduler* scheduler) { |
| 68 TRACE_EVENT1("cc", "Scheduler::Scheduler()", "UnthrottledFrameSource", |
| 69 "BackToBackBeginFrameSource"); |
| 70 DCHECK(!scheduler->unthrottled_frame_source_internal_); |
| 71 scheduler->unthrottled_frame_source_internal_ = |
| 72 BackToBackBeginFrameSource::Create(scheduler->task_runner_.get()); |
| 73 return scheduler->unthrottled_frame_source_internal_.get(); |
| 74 } |
| 75 |
74 Scheduler::Scheduler( | 76 Scheduler::Scheduler( |
75 SchedulerClient* client, | 77 SchedulerClient* client, |
76 const SchedulerSettings& scheduler_settings, | 78 const SchedulerSettings& scheduler_settings, |
77 int layer_tree_host_id, | 79 int layer_tree_host_id, |
78 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 80 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
79 base::PowerMonitor* power_monitor, | 81 base::PowerMonitor* power_monitor, |
80 scoped_ptr<BeginFrameSource> external_begin_frame_source, | 82 scoped_ptr<BeginFrameSource> external_begin_frame_source, |
81 SchedulerFrameSourcesConstructor* frame_sources_constructor) | 83 SchedulerFrameSourcesConstructor* frame_sources_constructor) |
82 : frame_source_(), | 84 : frame_source_(), |
83 primary_frame_source_(NULL), | 85 primary_frame_source_(NULL), |
84 background_frame_source_(NULL), | 86 background_frame_source_(NULL), |
85 primary_frame_source_internal_(external_begin_frame_source.Pass()), | 87 primary_frame_source_internal_(external_begin_frame_source.Pass()), |
86 background_frame_source_internal_(), | 88 background_frame_source_internal_(), |
87 vsync_observer_(NULL), | 89 vsync_observer_(NULL), |
| 90 throttle_frame_production_(scheduler_settings.throttle_frame_production), |
88 settings_(scheduler_settings), | 91 settings_(scheduler_settings), |
89 client_(client), | 92 client_(client), |
90 layer_tree_host_id_(layer_tree_host_id), | 93 layer_tree_host_id_(layer_tree_host_id), |
91 task_runner_(task_runner), | 94 task_runner_(task_runner), |
92 power_monitor_(power_monitor), | 95 power_monitor_(power_monitor), |
93 begin_retro_frame_posted_(false), | |
94 state_machine_(scheduler_settings), | 96 state_machine_(scheduler_settings), |
95 inside_process_scheduled_actions_(false), | 97 inside_process_scheduled_actions_(false), |
96 inside_action_(SchedulerStateMachine::ACTION_NONE), | 98 inside_action_(SchedulerStateMachine::ACTION_NONE), |
97 weak_factory_(this) { | 99 weak_factory_(this) { |
98 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 100 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
99 "Scheduler::Scheduler", | 101 "Scheduler::Scheduler", |
100 "settings", | 102 "settings", |
101 settings_.AsValue()); | 103 settings_.AsValue()); |
102 DCHECK(client_); | 104 DCHECK(client_); |
103 DCHECK(!state_machine_.BeginFrameNeeded()); | 105 DCHECK(!state_machine_.BeginFrameNeeded()); |
(...skipping 14 matching lines...) Expand all Loading... |
118 primary_frame_source_ = | 120 primary_frame_source_ = |
119 frame_sources_constructor->ConstructPrimaryFrameSource(this); | 121 frame_sources_constructor->ConstructPrimaryFrameSource(this); |
120 frame_source_->AddSource(primary_frame_source_); | 122 frame_source_->AddSource(primary_frame_source_); |
121 primary_frame_source_->SetClientReady(); | 123 primary_frame_source_->SetClientReady(); |
122 | 124 |
123 // Background ticking frame source | 125 // Background ticking frame source |
124 background_frame_source_ = | 126 background_frame_source_ = |
125 frame_sources_constructor->ConstructBackgroundFrameSource(this); | 127 frame_sources_constructor->ConstructBackgroundFrameSource(this); |
126 frame_source_->AddSource(background_frame_source_); | 128 frame_source_->AddSource(background_frame_source_); |
127 | 129 |
| 130 // Unthrottled frame source |
| 131 unthrottled_frame_source_ = |
| 132 frame_sources_constructor->ConstructUnthrottledFrameSource(this); |
| 133 frame_source_->AddSource(unthrottled_frame_source_); |
| 134 |
128 SetupPowerMonitoring(); | 135 SetupPowerMonitoring(); |
129 } | 136 } |
130 | 137 |
131 Scheduler::~Scheduler() { | 138 Scheduler::~Scheduler() { |
132 TeardownPowerMonitoring(); | 139 TeardownPowerMonitoring(); |
133 if (frame_source_->NeedsBeginFrames()) | 140 if (frame_source_->NeedsBeginFrames()) |
134 frame_source_->SetNeedsBeginFrames(false); | 141 frame_source_->SetNeedsBeginFrames(false); |
135 } | 142 } |
136 | 143 |
137 base::TimeTicks Scheduler::Now() const { | 144 base::TimeTicks Scheduler::Now() const { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { | 184 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { |
178 DCHECK_GE(draw_time.ToInternalValue(), 0); | 185 DCHECK_GE(draw_time.ToInternalValue(), 0); |
179 estimated_parent_draw_time_ = draw_time; | 186 estimated_parent_draw_time_ = draw_time; |
180 } | 187 } |
181 | 188 |
182 void Scheduler::SetCanStart() { | 189 void Scheduler::SetCanStart() { |
183 state_machine_.SetCanStart(); | 190 state_machine_.SetCanStart(); |
184 ProcessScheduledActions(); | 191 ProcessScheduledActions(); |
185 } | 192 } |
186 | 193 |
187 void Scheduler::SetVisible(bool visible) { | 194 void Scheduler::UpdateActiveFrameSource() { |
188 state_machine_.SetVisible(visible); | 195 if (state_machine_.visible()) { |
189 if (visible) { | 196 if (throttle_frame_production_) { |
190 frame_source_->SetActiveSource(primary_frame_source_); | 197 frame_source_->SetActiveSource(primary_frame_source_); |
| 198 } else { |
| 199 frame_source_->SetActiveSource(unthrottled_frame_source_); |
| 200 } |
191 } else { | 201 } else { |
192 frame_source_->SetActiveSource(background_frame_source_); | 202 frame_source_->SetActiveSource(background_frame_source_); |
193 } | 203 } |
194 ProcessScheduledActions(); | 204 ProcessScheduledActions(); |
195 } | 205 } |
196 | 206 |
| 207 void Scheduler::SetVisible(bool visible) { |
| 208 state_machine_.SetVisible(visible); |
| 209 UpdateActiveFrameSource(); |
| 210 } |
| 211 |
197 void Scheduler::SetCanDraw(bool can_draw) { | 212 void Scheduler::SetCanDraw(bool can_draw) { |
198 state_machine_.SetCanDraw(can_draw); | 213 state_machine_.SetCanDraw(can_draw); |
199 ProcessScheduledActions(); | 214 ProcessScheduledActions(); |
200 } | 215 } |
201 | 216 |
202 void Scheduler::NotifyReadyToActivate() { | 217 void Scheduler::NotifyReadyToActivate() { |
203 state_machine_.NotifyReadyToActivate(); | 218 state_machine_.NotifyReadyToActivate(); |
204 ProcessScheduledActions(); | 219 ProcessScheduledActions(); |
205 } | 220 } |
206 | 221 |
207 void Scheduler::NotifyReadyToDraw() { | 222 void Scheduler::NotifyReadyToDraw() { |
208 // Empty for now, until we take action based on the notification as part of | 223 // Empty for now, until we take action based on the notification as part of |
209 // crbugs 352894, 383157, 421923. | 224 // crbugs 352894, 383157, 421923. |
210 } | 225 } |
211 | 226 |
| 227 void Scheduler::SetThrottleFrameProduction(bool throttle) { |
| 228 throttle_frame_production_ = throttle; |
| 229 UpdateActiveFrameSource(); |
| 230 } |
| 231 |
212 void Scheduler::SetNeedsCommit() { | 232 void Scheduler::SetNeedsCommit() { |
213 state_machine_.SetNeedsCommit(); | 233 state_machine_.SetNeedsCommit(); |
214 ProcessScheduledActions(); | 234 ProcessScheduledActions(); |
215 } | 235 } |
216 | 236 |
217 void Scheduler::SetNeedsRedraw() { | 237 void Scheduler::SetNeedsRedraw() { |
218 state_machine_.SetNeedsRedraw(); | 238 state_machine_.SetNeedsRedraw(); |
219 ProcessScheduledActions(); | 239 ProcessScheduledActions(); |
220 } | 240 } |
221 | 241 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 state_machine_.BeginMainFrameAborted(reason); | 286 state_machine_.BeginMainFrameAborted(reason); |
267 ProcessScheduledActions(); | 287 ProcessScheduledActions(); |
268 } | 288 } |
269 | 289 |
270 void Scheduler::DidPrepareTiles() { | 290 void Scheduler::DidPrepareTiles() { |
271 state_machine_.DidPrepareTiles(); | 291 state_machine_.DidPrepareTiles(); |
272 } | 292 } |
273 | 293 |
274 void Scheduler::DidLoseOutputSurface() { | 294 void Scheduler::DidLoseOutputSurface() { |
275 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); | 295 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
| 296 begin_retro_frame_args_.clear(); |
| 297 begin_retro_frame_task_.Cancel(); |
276 state_machine_.DidLoseOutputSurface(); | 298 state_machine_.DidLoseOutputSurface(); |
277 if (frame_source_->NeedsBeginFrames()) | |
278 frame_source_->SetNeedsBeginFrames(false); | |
279 begin_retro_frame_args_.clear(); | |
280 ProcessScheduledActions(); | 299 ProcessScheduledActions(); |
281 } | 300 } |
282 | 301 |
283 void Scheduler::DidCreateAndInitializeOutputSurface() { | 302 void Scheduler::DidCreateAndInitializeOutputSurface() { |
284 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); | 303 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
285 DCHECK(!frame_source_->NeedsBeginFrames()); | 304 DCHECK(!frame_source_->NeedsBeginFrames()); |
286 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 305 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
287 state_machine_.DidCreateAndInitializeOutputSurface(); | 306 state_machine_.DidCreateAndInitializeOutputSurface(); |
288 ProcessScheduledActions(); | 307 ProcessScheduledActions(); |
289 } | 308 } |
(...skipping 16 matching lines...) Expand all Loading... |
306 } | 325 } |
307 | 326 |
308 base::TimeTicks Scheduler::LastBeginImplFrameTime() { | 327 base::TimeTicks Scheduler::LastBeginImplFrameTime() { |
309 return begin_impl_frame_args_.frame_time; | 328 return begin_impl_frame_args_.frame_time; |
310 } | 329 } |
311 | 330 |
312 void Scheduler::SetupNextBeginFrameIfNeeded() { | 331 void Scheduler::SetupNextBeginFrameIfNeeded() { |
313 if (!task_runner_.get()) | 332 if (!task_runner_.get()) |
314 return; | 333 return; |
315 | 334 |
316 bool needs_begin_frame = state_machine_.BeginFrameNeeded(); | 335 if (state_machine_.ShouldSetNeedsBeginFrames( |
317 | 336 frame_source_->NeedsBeginFrames())) { |
318 bool at_end_of_deadline = | 337 frame_source_->SetNeedsBeginFrames(state_machine_.BeginFrameNeeded()); |
319 (state_machine_.begin_impl_frame_state() == | |
320 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); | |
321 | |
322 bool should_call_set_needs_begin_frame = | |
323 // Always request the BeginFrame immediately if it wasn't needed before. | |
324 (needs_begin_frame && !frame_source_->NeedsBeginFrames()) || | |
325 // Only stop requesting BeginFrames after a deadline. | |
326 (!needs_begin_frame && frame_source_->NeedsBeginFrames() && | |
327 at_end_of_deadline); | |
328 | |
329 if (should_call_set_needs_begin_frame) { | |
330 frame_source_->SetNeedsBeginFrames(needs_begin_frame); | |
331 } | 338 } |
332 | 339 |
333 if (at_end_of_deadline) { | 340 if (state_machine_.begin_impl_frame_state() == |
| 341 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { |
334 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | 342 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); |
335 } | 343 } |
336 | 344 |
337 PostBeginRetroFrameIfNeeded(); | 345 PostBeginRetroFrameIfNeeded(); |
338 SetupPollingMechanisms(needs_begin_frame); | 346 SetupPollingMechanisms(); |
339 } | 347 } |
340 | 348 |
341 // We may need to poll when we can't rely on BeginFrame to advance certain | 349 // We may need to poll when we can't rely on BeginFrame to advance certain |
342 // state or to avoid deadlock. | 350 // state or to avoid deadlock. |
343 void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) { | 351 void Scheduler::SetupPollingMechanisms() { |
344 bool needs_advance_commit_state_timer = false; | 352 bool needs_advance_commit_state_timer = false; |
345 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but | 353 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but |
346 // aren't expecting any more BeginFrames. This should only be needed by | 354 // aren't expecting any more BeginFrames. This should only be needed by |
347 // the synchronous compositor when BeginFrameNeeded is false. | 355 // the synchronous compositor when BeginFrameNeeded is false. |
348 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { | 356 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { |
349 DCHECK(!state_machine_.SupportsProactiveBeginFrame()); | 357 DCHECK(!state_machine_.SupportsProactiveBeginFrame()); |
350 DCHECK(!needs_begin_frame); | |
351 if (poll_for_draw_triggers_task_.IsCancelled()) { | 358 if (poll_for_draw_triggers_task_.IsCancelled()) { |
352 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); | 359 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); |
353 base::TimeDelta delay = begin_impl_frame_args_.IsValid() | 360 base::TimeDelta delay = begin_impl_frame_args_.IsValid() |
354 ? begin_impl_frame_args_.interval | 361 ? begin_impl_frame_args_.interval |
355 : BeginFrameArgs::DefaultInterval(); | 362 : BeginFrameArgs::DefaultInterval(); |
356 task_runner_->PostDelayedTask( | 363 task_runner_->PostDelayedTask( |
357 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay); | 364 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay); |
358 } | 365 } |
359 } else { | 366 } else { |
360 poll_for_draw_triggers_task_.Cancel(); | 367 poll_for_draw_triggers_task_.Cancel(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 } | 427 } |
421 | 428 |
422 BeginFrameArgs adjusted_args(args); | 429 BeginFrameArgs adjusted_args(args); |
423 adjusted_args.deadline -= EstimatedParentDrawTime(); | 430 adjusted_args.deadline -= EstimatedParentDrawTime(); |
424 | 431 |
425 bool should_defer_begin_frame; | 432 bool should_defer_begin_frame; |
426 if (settings_.using_synchronous_renderer_compositor) { | 433 if (settings_.using_synchronous_renderer_compositor) { |
427 should_defer_begin_frame = false; | 434 should_defer_begin_frame = false; |
428 } else { | 435 } else { |
429 should_defer_begin_frame = | 436 should_defer_begin_frame = |
430 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || | 437 !begin_retro_frame_args_.empty() || |
| 438 !begin_retro_frame_task_.IsCancelled() || |
431 !frame_source_->NeedsBeginFrames() || | 439 !frame_source_->NeedsBeginFrames() || |
432 (state_machine_.begin_impl_frame_state() != | 440 (state_machine_.begin_impl_frame_state() != |
433 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 441 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
434 } | 442 } |
435 | 443 |
436 if (should_defer_begin_frame) { | 444 if (should_defer_begin_frame) { |
437 begin_retro_frame_args_.push_back(adjusted_args); | 445 begin_retro_frame_args_.push_back(adjusted_args); |
438 TRACE_EVENT_INSTANT0( | 446 TRACE_EVENT_INSTANT0( |
439 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); | 447 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); |
440 // Queuing the frame counts as "using it", so we need to return true. | 448 // Queuing the frame counts as "using it", so we need to return true. |
441 } else { | 449 } else { |
442 BeginImplFrame(adjusted_args); | 450 BeginImplFrame(adjusted_args); |
443 } | 451 } |
444 return true; | 452 return true; |
445 } | 453 } |
446 | 454 |
447 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { | 455 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { |
448 DCHECK(settings_.forward_begin_frames_to_children); | 456 DCHECK(settings_.forward_begin_frames_to_children); |
449 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); | 457 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); |
450 ProcessScheduledActions(); | 458 ProcessScheduledActions(); |
451 } | 459 } |
452 | 460 |
453 // BeginRetroFrame is called for BeginFrames that we've deferred because | 461 // BeginRetroFrame is called for BeginFrames that we've deferred because |
454 // the scheduler was in the middle of processing a previous BeginFrame. | 462 // the scheduler was in the middle of processing a previous BeginFrame. |
455 void Scheduler::BeginRetroFrame() { | 463 void Scheduler::BeginRetroFrame() { |
456 TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame"); | 464 TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame"); |
457 DCHECK(!settings_.using_synchronous_renderer_compositor); | 465 DCHECK(!settings_.using_synchronous_renderer_compositor); |
458 DCHECK(begin_retro_frame_posted_); | 466 DCHECK(!begin_retro_frame_args_.empty()); |
| 467 DCHECK(!begin_retro_frame_task_.IsCancelled()); |
459 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 468 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
460 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 469 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
461 begin_retro_frame_posted_ = false; | |
462 | 470 |
463 // If there aren't any retroactive BeginFrames, then we've lost the | 471 begin_retro_frame_task_.Cancel(); |
464 // OutputSurface and should abort. | |
465 if (begin_retro_frame_args_.empty()) | |
466 return; | |
467 | 472 |
468 // Discard expired BeginRetroFrames | 473 // Discard expired BeginRetroFrames |
469 // Today, we should always end up with at most one un-expired BeginRetroFrame | 474 // Today, we should always end up with at most one un-expired BeginRetroFrame |
470 // because deadlines will not be greater than the next frame time. We don't | 475 // because deadlines will not be greater than the next frame time. We don't |
471 // DCHECK though because some systems don't always have monotonic timestamps. | 476 // DCHECK though because some systems don't always have monotonic timestamps. |
472 // TODO(brianderson): In the future, long deadlines could result in us not | 477 // TODO(brianderson): In the future, long deadlines could result in us not |
473 // draining the queue if we don't catch up. If we consistently can't catch | 478 // draining the queue if we don't catch up. If we consistently can't catch |
474 // up, our fallback should be to lower our frame rate. | 479 // up, our fallback should be to lower our frame rate. |
475 base::TimeTicks now = Now(); | 480 base::TimeTicks now = Now(); |
476 | 481 |
(...skipping 26 matching lines...) Expand all Loading... |
503 // will check if there is a pending BeginRetroFrame to ensure we handle | 508 // will check if there is a pending BeginRetroFrame to ensure we handle |
504 // BeginFrames in FIFO order. | 509 // BeginFrames in FIFO order. |
505 void Scheduler::PostBeginRetroFrameIfNeeded() { | 510 void Scheduler::PostBeginRetroFrameIfNeeded() { |
506 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 511 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
507 "Scheduler::PostBeginRetroFrameIfNeeded", | 512 "Scheduler::PostBeginRetroFrameIfNeeded", |
508 "state", | 513 "state", |
509 AsValue()); | 514 AsValue()); |
510 if (!frame_source_->NeedsBeginFrames()) | 515 if (!frame_source_->NeedsBeginFrames()) |
511 return; | 516 return; |
512 | 517 |
513 if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_) | 518 if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled()) |
514 return; | 519 return; |
515 | 520 |
516 // begin_retro_frame_args_ should always be empty for the | 521 // begin_retro_frame_args_ should always be empty for the |
517 // synchronous compositor. | 522 // synchronous compositor. |
518 DCHECK(!settings_.using_synchronous_renderer_compositor); | 523 DCHECK(!settings_.using_synchronous_renderer_compositor); |
519 | 524 |
520 if (state_machine_.begin_impl_frame_state() != | 525 if (state_machine_.begin_impl_frame_state() != |
521 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) | 526 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) |
522 return; | 527 return; |
523 | 528 |
524 begin_retro_frame_posted_ = true; | 529 begin_retro_frame_task_.Reset(begin_retro_frame_closure_); |
525 task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); | 530 |
| 531 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback()); |
526 } | 532 } |
527 | 533 |
528 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 534 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
529 // for a BeginMainFrame+activation to complete before it times out and draws | 535 // for a BeginMainFrame+activation to complete before it times out and draws |
530 // any asynchronous animation and scroll/pinch updates. | 536 // any asynchronous animation and scroll/pinch updates. |
531 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 537 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
532 bool main_thread_is_in_high_latency_mode = | 538 bool main_thread_is_in_high_latency_mode = |
533 state_machine_.MainThreadIsInHighLatencyMode(); | 539 state_machine_.MainThreadIsInHighLatencyMode(); |
534 TRACE_EVENT2("cc", | 540 TRACE_EVENT2("cc", |
535 "Scheduler::BeginImplFrame", | 541 "Scheduler::BeginImplFrame", |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 state->EndDictionary(); | 756 state->EndDictionary(); |
751 } | 757 } |
752 | 758 |
753 state->BeginDictionary("scheduler_state"); | 759 state->BeginDictionary("scheduler_state"); |
754 state->SetDouble("time_until_anticipated_draw_time_ms", | 760 state->SetDouble("time_until_anticipated_draw_time_ms", |
755 (AnticipatedDrawTime() - Now()).InMillisecondsF()); | 761 (AnticipatedDrawTime() - Now()).InMillisecondsF()); |
756 state->SetDouble("estimated_parent_draw_time_ms", | 762 state->SetDouble("estimated_parent_draw_time_ms", |
757 estimated_parent_draw_time_.InMillisecondsF()); | 763 estimated_parent_draw_time_.InMillisecondsF()); |
758 state->SetBoolean("last_set_needs_begin_frame_", | 764 state->SetBoolean("last_set_needs_begin_frame_", |
759 frame_source_->NeedsBeginFrames()); | 765 frame_source_->NeedsBeginFrames()); |
760 state->SetBoolean("begin_retro_frame_posted_", begin_retro_frame_posted_); | |
761 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); | 766 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); |
| 767 state->SetBoolean("begin_retro_frame_task_", |
| 768 !begin_retro_frame_task_.IsCancelled()); |
762 state->SetBoolean("begin_impl_frame_deadline_task_", | 769 state->SetBoolean("begin_impl_frame_deadline_task_", |
763 !begin_impl_frame_deadline_task_.IsCancelled()); | 770 !begin_impl_frame_deadline_task_.IsCancelled()); |
764 state->SetBoolean("poll_for_draw_triggers_task_", | 771 state->SetBoolean("poll_for_draw_triggers_task_", |
765 !poll_for_draw_triggers_task_.IsCancelled()); | 772 !poll_for_draw_triggers_task_.IsCancelled()); |
766 state->SetBoolean("advance_commit_state_task_", | 773 state->SetBoolean("advance_commit_state_task_", |
767 !advance_commit_state_task_.IsCancelled()); | 774 !advance_commit_state_task_.IsCancelled()); |
768 state->BeginDictionary("begin_impl_frame_args"); | 775 state->BeginDictionary("begin_impl_frame_args"); |
769 begin_impl_frame_args_.AsValueInto(state); | 776 begin_impl_frame_args_.AsValueInto(state); |
770 state->EndDictionary(); | 777 state->EndDictionary(); |
771 | 778 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
803 } | 810 } |
804 | 811 |
805 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 812 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
806 return (state_machine_.commit_state() == | 813 return (state_machine_.commit_state() == |
807 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 814 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
808 state_machine_.commit_state() == | 815 state_machine_.commit_state() == |
809 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 816 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
810 } | 817 } |
811 | 818 |
812 } // namespace cc | 819 } // namespace cc |
OLD | NEW |