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/logging.h" | 10 #include "base/logging.h" |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
100 "Scheduler::Scheduler", | 100 "Scheduler::Scheduler", |
101 "settings", | 101 "settings", |
102 settings_.AsValue()); | 102 settings_.AsValue()); |
103 DCHECK(client_); | 103 DCHECK(client_); |
104 DCHECK(!state_machine_.BeginFrameNeeded()); | 104 DCHECK(!state_machine_.BeginFrameNeeded()); |
105 | 105 |
106 begin_retro_frame_closure_ = | 106 begin_retro_frame_closure_ = |
107 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); | 107 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); |
108 begin_impl_frame_deadline_closure_ = base::Bind( | 108 begin_impl_frame_deadline_closure_ = base::Bind( |
109 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); | 109 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); |
110 poll_for_draw_triggers_closure_ = base::Bind( | |
111 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); | |
112 advance_commit_state_closure_ = base::Bind( | 110 advance_commit_state_closure_ = base::Bind( |
113 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); | 111 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); |
114 | 112 |
115 frame_source_ = BeginFrameSourceMultiplexer::Create(); | 113 frame_source_ = BeginFrameSourceMultiplexer::Create(); |
116 frame_source_->AddObserver(this); | 114 frame_source_->AddObserver(this); |
117 | 115 |
118 // Primary frame source | 116 // Primary frame source |
119 primary_frame_source_ = | 117 primary_frame_source_ = |
120 frame_sources_constructor->ConstructPrimaryFrameSource(this); | 118 frame_sources_constructor->ConstructPrimaryFrameSource(this); |
121 frame_source_->AddSource(primary_frame_source_); | 119 frame_source_->AddSource(primary_frame_source_); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 client_->SendBeginMainFrameNotExpectedSoon(); | 315 client_->SendBeginMainFrameNotExpectedSoon(); |
318 } | 316 } |
319 } | 317 } |
320 | 318 |
321 PostBeginRetroFrameIfNeeded(); | 319 PostBeginRetroFrameIfNeeded(); |
322 } | 320 } |
323 | 321 |
324 // We may need to poll when we can't rely on BeginFrame to advance certain | 322 // We may need to poll when we can't rely on BeginFrame to advance certain |
325 // state or to avoid deadlock. | 323 // state or to avoid deadlock. |
326 void Scheduler::SetupPollingMechanisms() { | 324 void Scheduler::SetupPollingMechanisms() { |
327 bool needs_advance_commit_state_timer = false; | 325 // At this point we'd prefer to advance through the commit flow by |
328 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but | 326 // drawing a frame, however it's possible that the frame rate controller |
329 // aren't expecting any more BeginFrames. This should only be needed by | 327 // will not give us a BeginFrame until the commit completes. See |
330 // the synchronous compositor when BeginFrameNeeded is false. | 328 // crbug.com/317430 for an example of a swap ack being held on commit. Thus |
331 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { | 329 // we set a repeating timer to poll on ProcessScheduledActions until we |
332 DCHECK(!state_machine_.SupportsProactiveBeginFrame()); | 330 // successfully reach BeginFrame. Synchronous compositor does not use |
333 if (poll_for_draw_triggers_task_.IsCancelled()) { | 331 // frame rate controller or have the circular wait in the bug. |
334 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); | 332 if (IsBeginMainFrameSentOrStarted() && |
335 base::TimeDelta delay = begin_impl_frame_args_.IsValid() | 333 !settings_.using_synchronous_renderer_compositor) { |
336 ? begin_impl_frame_args_.interval | |
337 : BeginFrameArgs::DefaultInterval(); | |
338 task_runner_->PostDelayedTask( | |
339 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay); | |
340 } | |
341 } else { | |
342 poll_for_draw_triggers_task_.Cancel(); | |
343 | |
344 // At this point we'd prefer to advance through the commit flow by | |
345 // drawing a frame, however it's possible that the frame rate controller | |
346 // will not give us a BeginFrame until the commit completes. See | |
347 // crbug.com/317430 for an example of a swap ack being held on commit. Thus | |
348 // we set a repeating timer to poll on ProcessScheduledActions until we | |
349 // successfully reach BeginFrame. Synchronous compositor does not use | |
350 // frame rate controller or have the circular wait in the bug. | |
351 if (IsBeginMainFrameSentOrStarted() && | |
352 !settings_.using_synchronous_renderer_compositor) { | |
353 needs_advance_commit_state_timer = true; | |
354 } | |
355 } | |
356 | |
357 if (needs_advance_commit_state_timer) { | |
358 if (advance_commit_state_task_.IsCancelled() && | 334 if (advance_commit_state_task_.IsCancelled() && |
359 begin_impl_frame_args_.IsValid()) { | 335 begin_impl_frame_args_.IsValid()) { |
360 // Since we'd rather get a BeginImplFrame by the normal mechanism, we | 336 // Since we'd rather get a BeginImplFrame by the normal mechanism, we |
361 // set the interval to twice the interval from the previous frame. | 337 // set the interval to twice the interval from the previous frame. |
362 advance_commit_state_task_.Reset(advance_commit_state_closure_); | 338 advance_commit_state_task_.Reset(advance_commit_state_closure_); |
363 task_runner_->PostDelayedTask(FROM_HERE, | 339 task_runner_->PostDelayedTask(FROM_HERE, |
364 advance_commit_state_task_.callback(), | 340 advance_commit_state_task_.callback(), |
365 begin_impl_frame_args_.interval * 2); | 341 begin_impl_frame_args_.interval * 2); |
366 } | 342 } |
367 } else { | 343 } else { |
(...skipping 18 matching lines...) Expand all Loading... |
386 adjusted_args_for_children.deadline -= | 362 adjusted_args_for_children.deadline -= |
387 (client_->BeginMainFrameToCommitDurationEstimate() + | 363 (client_->BeginMainFrameToCommitDurationEstimate() + |
388 client_->CommitToActivateDurationEstimate() + | 364 client_->CommitToActivateDurationEstimate() + |
389 client_->DrawDurationEstimate() + EstimatedParentDrawTime()); | 365 client_->DrawDurationEstimate() + EstimatedParentDrawTime()); |
390 client_->SendBeginFramesToChildren(adjusted_args_for_children); | 366 client_->SendBeginFramesToChildren(adjusted_args_for_children); |
391 } | 367 } |
392 | 368 |
393 BeginFrameArgs adjusted_args(args); | 369 BeginFrameArgs adjusted_args(args); |
394 adjusted_args.deadline -= EstimatedParentDrawTime(); | 370 adjusted_args.deadline -= EstimatedParentDrawTime(); |
395 | 371 |
| 372 if (settings_.using_synchronous_renderer_compositor) { |
| 373 BeginImplFrameSynchronous(adjusted_args); |
| 374 return true; |
| 375 } |
| 376 |
396 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has | 377 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has |
397 // sent us the last BeginFrame we have missed. As we might not be able to | 378 // sent us the last BeginFrame we have missed. As we might not be able to |
398 // actually make rendering for this call, handle it like a "retro frame". | 379 // actually make rendering for this call, handle it like a "retro frame". |
399 // TODO(brainderson): Add a test for this functionality ASAP! | 380 // TODO(brainderson): Add a test for this functionality ASAP! |
400 if (adjusted_args.type == BeginFrameArgs::MISSED) { | 381 if (adjusted_args.type == BeginFrameArgs::MISSED) { |
401 begin_retro_frame_args_.push_back(adjusted_args); | 382 begin_retro_frame_args_.push_back(adjusted_args); |
402 PostBeginRetroFrameIfNeeded(); | 383 PostBeginRetroFrameIfNeeded(); |
403 return true; | 384 return true; |
404 } | 385 } |
405 | 386 |
406 bool should_defer_begin_frame; | 387 bool should_defer_begin_frame = |
407 if (settings_.using_synchronous_renderer_compositor) { | 388 !begin_retro_frame_args_.empty() || |
408 should_defer_begin_frame = false; | 389 !begin_retro_frame_task_.IsCancelled() || |
409 } else { | 390 !frame_source_->NeedsBeginFrames() || |
410 should_defer_begin_frame = | 391 (state_machine_.begin_impl_frame_state() != |
411 !begin_retro_frame_args_.empty() || | 392 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
412 !begin_retro_frame_task_.IsCancelled() || | |
413 !frame_source_->NeedsBeginFrames() || | |
414 (state_machine_.begin_impl_frame_state() != | |
415 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
416 } | |
417 | 393 |
418 if (should_defer_begin_frame) { | 394 if (should_defer_begin_frame) { |
419 begin_retro_frame_args_.push_back(adjusted_args); | 395 begin_retro_frame_args_.push_back(adjusted_args); |
420 TRACE_EVENT_INSTANT0( | 396 TRACE_EVENT_INSTANT0( |
421 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); | 397 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); |
422 // Queuing the frame counts as "using it", so we need to return true. | 398 // Queuing the frame counts as "using it", so we need to return true. |
423 } else { | 399 } else { |
424 BeginImplFrame(adjusted_args); | 400 BeginImplFrameWithDeadline(adjusted_args); |
425 } | 401 } |
426 return true; | 402 return true; |
427 } | 403 } |
428 | 404 |
429 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { | 405 void Scheduler::SetChildrenNeedBeginFrames(bool children_need_begin_frames) { |
430 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); | 406 state_machine_.SetChildrenNeedBeginFrames(children_need_begin_frames); |
431 ProcessScheduledActions(); | 407 ProcessScheduledActions(); |
432 } | 408 } |
433 | 409 |
| 410 void Scheduler::OnDrawForOutputSurface() { |
| 411 DCHECK(settings_.using_synchronous_renderer_compositor); |
| 412 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
| 413 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 414 DCHECK(!BeginImplFrameDeadlinePending()); |
| 415 |
| 416 state_machine_.OnBeginImplFrameDeadline(); |
| 417 ProcessScheduledActions(); |
| 418 |
| 419 state_machine_.OnBeginImplFrameIdle(); |
| 420 ProcessScheduledActions(); |
| 421 } |
| 422 |
434 // BeginRetroFrame is called for BeginFrames that we've deferred because | 423 // BeginRetroFrame is called for BeginFrames that we've deferred because |
435 // the scheduler was in the middle of processing a previous BeginFrame. | 424 // the scheduler was in the middle of processing a previous BeginFrame. |
436 void Scheduler::BeginRetroFrame() { | 425 void Scheduler::BeginRetroFrame() { |
437 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame"); | 426 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame"); |
438 DCHECK(!settings_.using_synchronous_renderer_compositor); | 427 DCHECK(!settings_.using_synchronous_renderer_compositor); |
439 DCHECK(!begin_retro_frame_args_.empty()); | 428 DCHECK(!begin_retro_frame_args_.empty()); |
440 DCHECK(!begin_retro_frame_task_.IsCancelled()); | 429 DCHECK(!begin_retro_frame_task_.IsCancelled()); |
441 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 430 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
442 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 431 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
443 | 432 |
(...skipping 21 matching lines...) Expand all Loading... |
465 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | 454 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); |
466 } | 455 } |
467 | 456 |
468 if (begin_retro_frame_args_.empty()) { | 457 if (begin_retro_frame_args_.empty()) { |
469 TRACE_EVENT_INSTANT0("cc", | 458 TRACE_EVENT_INSTANT0("cc", |
470 "Scheduler::BeginRetroFrames all expired", | 459 "Scheduler::BeginRetroFrames all expired", |
471 TRACE_EVENT_SCOPE_THREAD); | 460 TRACE_EVENT_SCOPE_THREAD); |
472 } else { | 461 } else { |
473 BeginFrameArgs front = begin_retro_frame_args_.front(); | 462 BeginFrameArgs front = begin_retro_frame_args_.front(); |
474 begin_retro_frame_args_.pop_front(); | 463 begin_retro_frame_args_.pop_front(); |
475 BeginImplFrame(front); | 464 BeginImplFrameWithDeadline(front); |
476 } | 465 } |
477 } | 466 } |
478 | 467 |
479 // There could be a race between the posted BeginRetroFrame and a new | 468 // There could be a race between the posted BeginRetroFrame and a new |
480 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame | 469 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame |
481 // will check if there is a pending BeginRetroFrame to ensure we handle | 470 // will check if there is a pending BeginRetroFrame to ensure we handle |
482 // BeginFrames in FIFO order. | 471 // BeginFrames in FIFO order. |
483 void Scheduler::PostBeginRetroFrameIfNeeded() { | 472 void Scheduler::PostBeginRetroFrameIfNeeded() { |
484 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 473 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
485 "Scheduler::PostBeginRetroFrameIfNeeded", | 474 "Scheduler::PostBeginRetroFrameIfNeeded", |
(...skipping 11 matching lines...) Expand all Loading... |
497 | 486 |
498 if (state_machine_.begin_impl_frame_state() != | 487 if (state_machine_.begin_impl_frame_state() != |
499 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) | 488 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) |
500 return; | 489 return; |
501 | 490 |
502 begin_retro_frame_task_.Reset(begin_retro_frame_closure_); | 491 begin_retro_frame_task_.Reset(begin_retro_frame_closure_); |
503 | 492 |
504 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback()); | 493 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback()); |
505 } | 494 } |
506 | 495 |
| 496 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { |
| 497 BeginImplFrame(args); |
| 498 |
| 499 // The deadline will be scheduled in ProcessScheduledActions. |
| 500 state_machine_.OnBeginImplFrameDeadlinePending(); |
| 501 ProcessScheduledActions(); |
| 502 } |
| 503 |
| 504 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
| 505 BeginImplFrame(args); |
| 506 FinishImplFrame(); |
| 507 } |
| 508 |
| 509 void Scheduler::FinishImplFrame() { |
| 510 state_machine_.OnBeginImplFrameIdle(); |
| 511 ProcessScheduledActions(); |
| 512 |
| 513 client_->DidBeginImplFrameDeadline(); |
| 514 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); |
| 515 } |
| 516 |
507 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 517 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
508 // for a BeginMainFrame+activation to complete before it times out and draws | 518 // for a BeginMainFrame+activation to complete before it times out and draws |
509 // any asynchronous animation and scroll/pinch updates. | 519 // any asynchronous animation and scroll/pinch updates. |
510 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 520 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
511 bool main_thread_is_in_high_latency_mode = | 521 bool main_thread_is_in_high_latency_mode = |
512 state_machine_.MainThreadIsInHighLatencyMode(); | 522 state_machine_.MainThreadIsInHighLatencyMode(); |
513 TRACE_EVENT2("cc,benchmark", | 523 TRACE_EVENT2("cc,benchmark", |
514 "Scheduler::BeginImplFrame", | 524 "Scheduler::BeginImplFrame", |
515 "args", | 525 "args", |
516 args.AsValue(), | 526 args.AsValue(), |
517 "main_thread_is_high_latency", | 527 "main_thread_is_high_latency", |
518 main_thread_is_in_high_latency_mode); | 528 main_thread_is_in_high_latency_mode); |
519 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 529 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
520 "MainThreadLatency", | 530 "MainThreadLatency", |
521 main_thread_is_in_high_latency_mode); | 531 main_thread_is_in_high_latency_mode); |
522 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 532 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
523 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 533 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 534 DCHECK(!BeginImplFrameDeadlinePending()); |
524 DCHECK(state_machine_.HasInitializedOutputSurface()); | 535 DCHECK(state_machine_.HasInitializedOutputSurface()); |
525 | 536 |
526 advance_commit_state_task_.Cancel(); | 537 advance_commit_state_task_.Cancel(); |
527 | 538 |
528 begin_impl_frame_args_ = args; | 539 begin_impl_frame_args_ = args; |
529 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); | 540 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); |
530 | 541 |
531 if (!state_machine_.impl_latency_takes_priority() && | 542 if (!state_machine_.impl_latency_takes_priority() && |
532 main_thread_is_in_high_latency_mode && | 543 main_thread_is_in_high_latency_mode && |
533 CanCommitAndActivateBeforeDeadline()) { | 544 CanCommitAndActivateBeforeDeadline()) { |
534 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 545 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
535 } | 546 } |
536 | 547 |
537 state_machine_.OnBeginImplFrame(); | 548 state_machine_.OnBeginImplFrame(); |
538 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); | 549 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); |
539 client_->WillBeginImplFrame(begin_impl_frame_args_); | 550 client_->WillBeginImplFrame(begin_impl_frame_args_); |
540 | 551 |
541 ProcessScheduledActions(); | 552 ProcessScheduledActions(); |
542 | |
543 state_machine_.OnBeginImplFrameDeadlinePending(); | |
544 | |
545 if (settings_.using_synchronous_renderer_compositor) { | |
546 // The synchronous renderer compositor has to make its GL calls | |
547 // within this call. | |
548 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks | |
549 // so the synchronous renderer compositor can take advantage of splitting | |
550 // up the BeginImplFrame and deadline as well. | |
551 OnBeginImplFrameDeadline(); | |
552 } else { | |
553 ScheduleBeginImplFrameDeadline(); | |
554 } | |
555 } | 553 } |
556 | 554 |
557 void Scheduler::ScheduleBeginImplFrameDeadline() { | 555 void Scheduler::ScheduleBeginImplFrameDeadline() { |
558 // The synchronous compositor does not post a deadline task. | 556 // The synchronous compositor does not post a deadline task. |
559 DCHECK(!settings_.using_synchronous_renderer_compositor); | 557 DCHECK(!settings_.using_synchronous_renderer_compositor); |
560 | 558 |
561 begin_impl_frame_deadline_task_.Cancel(); | 559 begin_impl_frame_deadline_task_.Cancel(); |
562 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); | 560 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); |
563 | 561 |
564 begin_impl_frame_deadline_mode_ = | 562 begin_impl_frame_deadline_mode_ = |
565 state_machine_.CurrentBeginImplFrameDeadlineMode(); | 563 state_machine_.CurrentBeginImplFrameDeadlineMode(); |
566 | 564 |
567 base::TimeTicks deadline; | 565 base::TimeTicks deadline; |
568 switch (begin_impl_frame_deadline_mode_) { | 566 switch (begin_impl_frame_deadline_mode_) { |
| 567 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE: |
| 568 // No deadline. |
| 569 return; |
569 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: | 570 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE: |
570 // We are ready to draw a new active tree immediately. | 571 // We are ready to draw a new active tree immediately. |
571 // We don't use Now() here because it's somewhat expensive to call. | 572 // We don't use Now() here because it's somewhat expensive to call. |
572 deadline = base::TimeTicks(); | 573 deadline = base::TimeTicks(); |
573 break; | 574 break; |
574 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR: | 575 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR: |
575 // We are animating on the impl thread but we can wait for some time. | 576 // We are animating on the impl thread but we can wait for some time. |
576 deadline = begin_impl_frame_args_.deadline; | 577 deadline = begin_impl_frame_args_.deadline; |
577 break; | 578 break; |
578 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: | 579 case SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: |
579 // We are blocked for one reason or another and we should wait. | 580 // We are blocked for one reason or another and we should wait. |
580 // TODO(brianderson): Handle long deadlines (that are past the next | 581 // TODO(brianderson): Handle long deadlines (that are past the next |
581 // frame's frame time) properly instead of using this hack. | 582 // frame's frame time) properly instead of using this hack. |
582 deadline = | 583 deadline = |
583 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval; | 584 begin_impl_frame_args_.frame_time + begin_impl_frame_args_.interval; |
584 break; | 585 break; |
585 } | 586 } |
586 | 587 |
587 TRACE_EVENT1( | 588 TRACE_EVENT2("cc", "Scheduler::ScheduleBeginImplFrameDeadline", "mode", |
588 "cc", "Scheduler::ScheduleBeginImplFrameDeadline", "deadline", deadline); | 589 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( |
| 590 begin_impl_frame_deadline_mode_), |
| 591 "deadline", deadline); |
589 | 592 |
590 base::TimeDelta delta = deadline - Now(); | 593 base::TimeDelta delta = std::max(deadline - Now(), base::TimeDelta()); |
591 if (delta <= base::TimeDelta()) | |
592 delta = base::TimeDelta(); | |
593 task_runner_->PostDelayedTask( | 594 task_runner_->PostDelayedTask( |
594 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta); | 595 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta); |
595 } | 596 } |
596 | 597 |
597 void Scheduler::RescheduleBeginImplFrameDeadlineIfNeeded() { | 598 void Scheduler::ScheduleBeginImplFrameDeadlineIfNeeded() { |
598 if (settings_.using_synchronous_renderer_compositor) | |
599 return; | |
600 | |
601 if (state_machine_.begin_impl_frame_state() != | 599 if (state_machine_.begin_impl_frame_state() != |
602 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) | 600 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) |
603 return; | 601 return; |
604 | 602 |
605 if (begin_impl_frame_deadline_mode_ != | 603 if (begin_impl_frame_deadline_mode_ == |
606 state_machine_.CurrentBeginImplFrameDeadlineMode()) | 604 state_machine_.CurrentBeginImplFrameDeadlineMode() && |
607 ScheduleBeginImplFrameDeadline(); | 605 BeginImplFrameDeadlinePending()) |
| 606 return; |
| 607 |
| 608 ScheduleBeginImplFrameDeadline(); |
608 } | 609 } |
609 | 610 |
610 void Scheduler::OnBeginImplFrameDeadline() { | 611 void Scheduler::OnBeginImplFrameDeadline() { |
611 TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline"); | 612 TRACE_EVENT0("cc,benchmark", "Scheduler::OnBeginImplFrameDeadline"); |
612 begin_impl_frame_deadline_task_.Cancel(); | 613 begin_impl_frame_deadline_task_.Cancel(); |
613 // We split the deadline actions up into two phases so the state machine | 614 // We split the deadline actions up into two phases so the state machine |
614 // has a chance to trigger actions that should occur durring and after | 615 // has a chance to trigger actions that should occur durring and after |
615 // the deadline separately. For example: | 616 // the deadline separately. For example: |
616 // * Sending the BeginMainFrame will not occur after the deadline in | 617 // * Sending the BeginMainFrame will not occur after the deadline in |
617 // order to wait for more user-input before starting the next commit. | 618 // order to wait for more user-input before starting the next commit. |
618 // * Creating a new OuputSurface will not occur during the deadline in | 619 // * Creating a new OuputSurface will not occur during the deadline in |
619 // order to allow the state machine to "settle" first. | 620 // order to allow the state machine to "settle" first. |
620 | 621 |
621 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. | 622 // TODO(robliao): Remove ScopedTracker below once crbug.com/461509 is fixed. |
622 tracked_objects::ScopedTracker tracking_profile1( | 623 tracked_objects::ScopedTracker tracking_profile1( |
623 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 624 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
624 "461509 Scheduler::OnBeginImplFrameDeadline1")); | 625 "461509 Scheduler::OnBeginImplFrameDeadline1")); |
625 state_machine_.OnBeginImplFrameDeadline(); | 626 state_machine_.OnBeginImplFrameDeadline(); |
626 ProcessScheduledActions(); | 627 ProcessScheduledActions(); |
627 state_machine_.OnBeginImplFrameIdle(); | 628 FinishImplFrame(); |
628 ProcessScheduledActions(); | |
629 | |
630 client_->DidBeginImplFrameDeadline(); | |
631 frame_source_->DidFinishFrame(begin_retro_frame_args_.size()); | |
632 } | 629 } |
633 | 630 |
634 void Scheduler::PollForAnticipatedDrawTriggers() { | |
635 TRACE_EVENT0("cc", "Scheduler::PollForAnticipatedDrawTriggers"); | |
636 poll_for_draw_triggers_task_.Cancel(); | |
637 state_machine_.DidEnterPollForAnticipatedDrawTriggers(); | |
638 ProcessScheduledActions(); | |
639 state_machine_.DidLeavePollForAnticipatedDrawTriggers(); | |
640 } | |
641 | 631 |
642 void Scheduler::PollToAdvanceCommitState() { | 632 void Scheduler::PollToAdvanceCommitState() { |
643 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); | 633 TRACE_EVENT0("cc", "Scheduler::PollToAdvanceCommitState"); |
644 advance_commit_state_task_.Cancel(); | 634 advance_commit_state_task_.Cancel(); |
645 ProcessScheduledActions(); | 635 ProcessScheduledActions(); |
646 } | 636 } |
647 | 637 |
648 void Scheduler::DrawAndSwapIfPossible() { | 638 void Scheduler::DrawAndSwapIfPossible() { |
649 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); | 639 DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); |
650 state_machine_.DidDrawIfPossibleCompleted(result); | 640 state_machine_.DidDrawIfPossibleCompleted(result); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: | 705 case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: |
716 // No action is actually performed, but this allows the state machine to | 706 // No action is actually performed, but this allows the state machine to |
717 // advance out of its waiting to draw state without actually drawing. | 707 // advance out of its waiting to draw state without actually drawing. |
718 break; | 708 break; |
719 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | 709 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: |
720 client_->ScheduledActionBeginOutputSurfaceCreation(); | 710 client_->ScheduledActionBeginOutputSurfaceCreation(); |
721 break; | 711 break; |
722 case SchedulerStateMachine::ACTION_PREPARE_TILES: | 712 case SchedulerStateMachine::ACTION_PREPARE_TILES: |
723 client_->ScheduledActionPrepareTiles(); | 713 client_->ScheduledActionPrepareTiles(); |
724 break; | 714 break; |
| 715 case SchedulerStateMachine::ACTION_INVALIDATE_OUTPUT_SURFACE: { |
| 716 client_->ScheduledActionInvalidateOutputSurface(); |
| 717 break; |
| 718 } |
725 } | 719 } |
726 } while (action != SchedulerStateMachine::ACTION_NONE); | 720 } while (action != SchedulerStateMachine::ACTION_NONE); |
727 | 721 |
728 SetupPollingMechanisms(); | 722 SetupPollingMechanisms(); |
729 | 723 |
730 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); | 724 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); |
731 | 725 |
732 RescheduleBeginImplFrameDeadlineIfNeeded(); | 726 ScheduleBeginImplFrameDeadlineIfNeeded(); |
733 | 727 |
734 SetupNextBeginFrameIfNeeded(); | 728 SetupNextBeginFrameIfNeeded(); |
735 } | 729 } |
736 | 730 |
737 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue() | 731 scoped_refptr<base::trace_event::ConvertableToTraceFormat> Scheduler::AsValue() |
738 const { | 732 const { |
739 scoped_refptr<base::trace_event::TracedValue> state = | 733 scoped_refptr<base::trace_event::TracedValue> state = |
740 new base::trace_event::TracedValue(); | 734 new base::trace_event::TracedValue(); |
741 AsValueInto(state.get()); | 735 AsValueInto(state.get()); |
742 return state; | 736 return state; |
(...skipping 20 matching lines...) Expand all Loading... |
763 (AnticipatedDrawTime() - Now()).InMillisecondsF()); | 757 (AnticipatedDrawTime() - Now()).InMillisecondsF()); |
764 state->SetDouble("estimated_parent_draw_time_ms", | 758 state->SetDouble("estimated_parent_draw_time_ms", |
765 estimated_parent_draw_time_.InMillisecondsF()); | 759 estimated_parent_draw_time_.InMillisecondsF()); |
766 state->SetBoolean("last_set_needs_begin_frame_", | 760 state->SetBoolean("last_set_needs_begin_frame_", |
767 frame_source_->NeedsBeginFrames()); | 761 frame_source_->NeedsBeginFrames()); |
768 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); | 762 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); |
769 state->SetBoolean("begin_retro_frame_task_", | 763 state->SetBoolean("begin_retro_frame_task_", |
770 !begin_retro_frame_task_.IsCancelled()); | 764 !begin_retro_frame_task_.IsCancelled()); |
771 state->SetBoolean("begin_impl_frame_deadline_task_", | 765 state->SetBoolean("begin_impl_frame_deadline_task_", |
772 !begin_impl_frame_deadline_task_.IsCancelled()); | 766 !begin_impl_frame_deadline_task_.IsCancelled()); |
773 state->SetBoolean("poll_for_draw_triggers_task_", | |
774 !poll_for_draw_triggers_task_.IsCancelled()); | |
775 state->SetBoolean("advance_commit_state_task_", | 767 state->SetBoolean("advance_commit_state_task_", |
776 !advance_commit_state_task_.IsCancelled()); | 768 !advance_commit_state_task_.IsCancelled()); |
777 state->BeginDictionary("begin_impl_frame_args"); | 769 state->BeginDictionary("begin_impl_frame_args"); |
778 begin_impl_frame_args_.AsValueInto(state); | 770 begin_impl_frame_args_.AsValueInto(state); |
779 state->EndDictionary(); | 771 state->EndDictionary(); |
780 | 772 |
781 base::TimeTicks now = Now(); | 773 base::TimeTicks now = Now(); |
782 base::TimeTicks frame_time = begin_impl_frame_args_.frame_time; | 774 base::TimeTicks frame_time = begin_impl_frame_args_.frame_time; |
783 base::TimeTicks deadline = begin_impl_frame_args_.deadline; | 775 base::TimeTicks deadline = begin_impl_frame_args_.deadline; |
784 base::TimeDelta interval = begin_impl_frame_args_.interval; | 776 base::TimeDelta interval = begin_impl_frame_args_.interval; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 } | 821 } |
830 | 822 |
831 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 823 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
832 return (state_machine_.commit_state() == | 824 return (state_machine_.commit_state() == |
833 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 825 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
834 state_machine_.commit_state() == | 826 state_machine_.commit_state() == |
835 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 827 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
836 } | 828 } |
837 | 829 |
838 } // namespace cc | 830 } // namespace cc |
OLD | NEW |