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

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

Issue 134623005: Make SingleThreadProxy a SchedulerClient (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add scoped_abort_remaining_swap_promises.h Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/test/fake_layer_tree_host_client.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 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 #include "base/auto_reset.h" 8 #include "base/auto_reset.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/debug/trace_event_argument.h" 10 #include "base/debug/trace_event_argument.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 base::TimeTicks frame_time) { 72 base::TimeTicks frame_time) {
73 base::TimeTicks deadline = time_source_->NextTickTime(); 73 base::TimeTicks deadline = time_source_->NextTickTime();
74 return BeginFrameArgs::Create( 74 return BeginFrameArgs::Create(
75 frame_time, deadline, scheduler_->VSyncInterval()); 75 frame_time, deadline, scheduler_->VSyncInterval());
76 } 76 }
77 77
78 Scheduler::Scheduler( 78 Scheduler::Scheduler(
79 SchedulerClient* client, 79 SchedulerClient* client,
80 const SchedulerSettings& scheduler_settings, 80 const SchedulerSettings& scheduler_settings,
81 int layer_tree_host_id, 81 int layer_tree_host_id,
82 const scoped_refptr<base::SingleThreadTaskRunner>& impl_task_runner) 82 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
83 : settings_(scheduler_settings), 83 : settings_(scheduler_settings),
84 client_(client), 84 client_(client),
85 layer_tree_host_id_(layer_tree_host_id), 85 layer_tree_host_id_(layer_tree_host_id),
86 impl_task_runner_(impl_task_runner), 86 task_runner_(task_runner),
87 vsync_interval_(BeginFrameArgs::DefaultInterval()), 87 vsync_interval_(BeginFrameArgs::DefaultInterval()),
88 last_set_needs_begin_frame_(false), 88 last_set_needs_begin_frame_(false),
89 begin_unthrottled_frame_posted_(false), 89 begin_unthrottled_frame_posted_(false),
90 begin_retro_frame_posted_(false), 90 begin_retro_frame_posted_(false),
91 state_machine_(scheduler_settings), 91 state_machine_(scheduler_settings),
92 inside_process_scheduled_actions_(false), 92 inside_process_scheduled_actions_(false),
93 inside_action_(SchedulerStateMachine::ACTION_NONE), 93 inside_action_(SchedulerStateMachine::ACTION_NONE),
94 weak_factory_(this) { 94 weak_factory_(this) {
95 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 95 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
96 "Scheduler::Scheduler", 96 "Scheduler::Scheduler",
(...skipping 24 matching lines...) Expand all
121 Scheduler::~Scheduler() { 121 Scheduler::~Scheduler() {
122 if (synthetic_begin_frame_source_) { 122 if (synthetic_begin_frame_source_) {
123 synthetic_begin_frame_source_->SetNeedsBeginFrame(false, 123 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
124 &begin_retro_frame_args_); 124 &begin_retro_frame_args_);
125 } 125 }
126 } 126 }
127 127
128 void Scheduler::SetupSyntheticBeginFrames() { 128 void Scheduler::SetupSyntheticBeginFrames() {
129 DCHECK(!synthetic_begin_frame_source_); 129 DCHECK(!synthetic_begin_frame_source_);
130 synthetic_begin_frame_source_.reset( 130 synthetic_begin_frame_source_.reset(
131 new SyntheticBeginFrameSource(this, impl_task_runner_.get())); 131 new SyntheticBeginFrameSource(this, task_runner_.get()));
132 } 132 }
133 133
134 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, 134 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
135 base::TimeDelta interval) { 135 base::TimeDelta interval) {
136 // TODO(brianderson): We should not be receiving 0 intervals. 136 // TODO(brianderson): We should not be receiving 0 intervals.
137 if (interval == base::TimeDelta()) 137 if (interval == base::TimeDelta())
138 interval = BeginFrameArgs::DefaultInterval(); 138 interval = BeginFrameArgs::DefaultInterval();
139 vsync_interval_ = interval; 139 vsync_interval_ = interval;
140 if (!settings_.begin_frame_scheduling_enabled) 140 if (!settings_.begin_frame_scheduling_enabled)
141 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); 141 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 begin_impl_frame_args_.deadline); 267 begin_impl_frame_args_.deadline);
268 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval); 268 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
269 return timebase + (begin_impl_frame_args_.interval * intervals); 269 return timebase + (begin_impl_frame_args_.interval * intervals);
270 } 270 }
271 271
272 base::TimeTicks Scheduler::LastBeginImplFrameTime() { 272 base::TimeTicks Scheduler::LastBeginImplFrameTime() {
273 return begin_impl_frame_args_.frame_time; 273 return begin_impl_frame_args_.frame_time;
274 } 274 }
275 275
276 void Scheduler::SetupNextBeginFrameIfNeeded() { 276 void Scheduler::SetupNextBeginFrameIfNeeded() {
277 if (!task_runner_)
278 return;
279
277 bool needs_begin_frame = state_machine_.BeginFrameNeeded(); 280 bool needs_begin_frame = state_machine_.BeginFrameNeeded();
278 281
279 if (settings_.throttle_frame_production) { 282 if (settings_.throttle_frame_production) {
280 SetupNextBeginFrameWhenVSyncThrottlingEnabled(needs_begin_frame); 283 SetupNextBeginFrameWhenVSyncThrottlingEnabled(needs_begin_frame);
281 } else { 284 } else {
282 SetupNextBeginFrameWhenVSyncThrottlingDisabled(needs_begin_frame); 285 SetupNextBeginFrameWhenVSyncThrottlingDisabled(needs_begin_frame);
283 } 286 }
284 SetupPollingMechanisms(needs_begin_frame); 287 SetupPollingMechanisms(needs_begin_frame);
285 } 288 }
286 289
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 return; 324 return;
322 325
323 if (state_machine_.begin_impl_frame_state() != 326 if (state_machine_.begin_impl_frame_state() !=
324 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE && 327 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE &&
325 state_machine_.begin_impl_frame_state() != 328 state_machine_.begin_impl_frame_state() !=
326 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { 329 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
327 return; 330 return;
328 } 331 }
329 332
330 begin_unthrottled_frame_posted_ = true; 333 begin_unthrottled_frame_posted_ = true;
331 impl_task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_); 334 task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_);
332 } 335 }
333 336
334 // BeginUnthrottledFrame is used when we aren't throttling frame production. 337 // BeginUnthrottledFrame is used when we aren't throttling frame production.
335 // This will usually be because VSync is disabled. 338 // This will usually be because VSync is disabled.
336 void Scheduler::BeginUnthrottledFrame() { 339 void Scheduler::BeginUnthrottledFrame() {
337 DCHECK(!settings_.throttle_frame_production); 340 DCHECK(!settings_.throttle_frame_production);
338 DCHECK(begin_retro_frame_args_.empty()); 341 DCHECK(begin_retro_frame_args_.empty());
339 342
340 base::TimeTicks now = gfx::FrameTime::Now(); 343 base::TimeTicks now = gfx::FrameTime::Now();
341 base::TimeTicks deadline = now + vsync_interval_; 344 base::TimeTicks deadline = now + vsync_interval_;
(...skipping 13 matching lines...) Expand all
355 // aren't expecting any more BeginFrames. This should only be needed by 358 // aren't expecting any more BeginFrames. This should only be needed by
356 // the synchronous compositor when BeginFrameNeeded is false. 359 // the synchronous compositor when BeginFrameNeeded is false.
357 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { 360 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
358 DCHECK(!state_machine_.SupportsProactiveBeginFrame()); 361 DCHECK(!state_machine_.SupportsProactiveBeginFrame());
359 DCHECK(!needs_begin_frame); 362 DCHECK(!needs_begin_frame);
360 if (poll_for_draw_triggers_task_.IsCancelled()) { 363 if (poll_for_draw_triggers_task_.IsCancelled()) {
361 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); 364 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_);
362 base::TimeDelta delay = begin_impl_frame_args_.IsValid() 365 base::TimeDelta delay = begin_impl_frame_args_.IsValid()
363 ? begin_impl_frame_args_.interval 366 ? begin_impl_frame_args_.interval
364 : BeginFrameArgs::DefaultInterval(); 367 : BeginFrameArgs::DefaultInterval();
365 impl_task_runner_->PostDelayedTask( 368 task_runner_->PostDelayedTask(
366 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay); 369 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
367 } 370 }
368 } else { 371 } else {
369 poll_for_draw_triggers_task_.Cancel(); 372 poll_for_draw_triggers_task_.Cancel();
370 373
371 // At this point we'd prefer to advance through the commit flow by 374 // At this point we'd prefer to advance through the commit flow by
372 // drawing a frame, however it's possible that the frame rate controller 375 // drawing a frame, however it's possible that the frame rate controller
373 // will not give us a BeginFrame until the commit completes. See 376 // will not give us a BeginFrame until the commit completes. See
374 // crbug.com/317430 for an example of a swap ack being held on commit. Thus 377 // crbug.com/317430 for an example of a swap ack being held on commit. Thus
375 // we set a repeating timer to poll on ProcessScheduledActions until we 378 // we set a repeating timer to poll on ProcessScheduledActions until we
376 // successfully reach BeginFrame. Synchronous compositor does not use 379 // successfully reach BeginFrame. Synchronous compositor does not use
377 // frame rate controller or have the circular wait in the bug. 380 // frame rate controller or have the circular wait in the bug.
378 if (IsBeginMainFrameSentOrStarted() && 381 if (IsBeginMainFrameSentOrStarted() &&
379 !settings_.using_synchronous_renderer_compositor) { 382 !settings_.using_synchronous_renderer_compositor) {
380 needs_advance_commit_state_timer = true; 383 needs_advance_commit_state_timer = true;
381 } 384 }
382 } 385 }
383 386
384 if (needs_advance_commit_state_timer) { 387 if (needs_advance_commit_state_timer) {
385 if (advance_commit_state_task_.IsCancelled() && 388 if (advance_commit_state_task_.IsCancelled() &&
386 begin_impl_frame_args_.IsValid()) { 389 begin_impl_frame_args_.IsValid()) {
387 // Since we'd rather get a BeginImplFrame by the normal mechanism, we 390 // Since we'd rather get a BeginImplFrame by the normal mechanism, we
388 // set the interval to twice the interval from the previous frame. 391 // set the interval to twice the interval from the previous frame.
389 advance_commit_state_task_.Reset(advance_commit_state_closure_); 392 advance_commit_state_task_.Reset(advance_commit_state_closure_);
390 impl_task_runner_->PostDelayedTask(FROM_HERE, 393 task_runner_->PostDelayedTask(FROM_HERE,
391 advance_commit_state_task_.callback(), 394 advance_commit_state_task_.callback(),
392 begin_impl_frame_args_.interval * 2); 395 begin_impl_frame_args_.interval * 2);
393 } 396 }
394 } else { 397 } else {
395 advance_commit_state_task_.Cancel(); 398 advance_commit_state_task_.Cancel();
396 } 399 }
397 } 400 }
398 401
399 // BeginFrame is the mechanism that tells us that now is a good time to start 402 // BeginFrame is the mechanism that tells us that now is a good time to start
400 // making a frame. Usually this means that user input for the frame is complete. 403 // making a frame. Usually this means that user input for the frame is complete.
401 // If the scheduler is busy, we queue the BeginFrame to be handled later as 404 // If the scheduler is busy, we queue the BeginFrame to be handled later as
402 // a BeginRetroFrame. 405 // a BeginRetroFrame.
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 487
485 // begin_retro_frame_args_ should always be empty for the 488 // begin_retro_frame_args_ should always be empty for the
486 // synchronous compositor. 489 // synchronous compositor.
487 DCHECK(!settings_.using_synchronous_renderer_compositor); 490 DCHECK(!settings_.using_synchronous_renderer_compositor);
488 491
489 if (state_machine_.begin_impl_frame_state() != 492 if (state_machine_.begin_impl_frame_state() !=
490 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) 493 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
491 return; 494 return;
492 495
493 begin_retro_frame_posted_ = true; 496 begin_retro_frame_posted_ = true;
494 impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_); 497 task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_);
495 } 498 }
496 499
497 // BeginImplFrame starts a compositor frame that will wait up until a deadline 500 // BeginImplFrame starts a compositor frame that will wait up until a deadline
498 // for a BeginMainFrame+activation to complete before it times out and draws 501 // for a BeginMainFrame+activation to complete before it times out and draws
499 // any asynchronous animation and scroll/pinch updates. 502 // any asynchronous animation and scroll/pinch updates.
500 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 503 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
501 TRACE_EVENT1("cc", "Scheduler::BeginImplFrame", "args", args.AsValue()); 504 TRACE_EVENT1("cc", "Scheduler::BeginImplFrame", "args", args.AsValue());
502 DCHECK(state_machine_.begin_impl_frame_state() == 505 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
503 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 506 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
504 DCHECK(state_machine_.HasInitializedOutputSurface()); 507 DCHECK(state_machine_.HasInitializedOutputSurface());
505 508
506 advance_commit_state_task_.Cancel(); 509 advance_commit_state_task_.Cancel();
507 510
508 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); 511 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
509 begin_impl_frame_args_ = args; 512 begin_impl_frame_args_ = args;
510 begin_impl_frame_args_.deadline -= draw_duration_estimate; 513 begin_impl_frame_args_.deadline -= draw_duration_estimate;
511 514
512 if (!state_machine_.smoothness_takes_priority() && 515 if (!state_machine_.smoothness_takes_priority() &&
513 state_machine_.MainThreadIsInHighLatencyMode() && 516 state_machine_.MainThreadIsInHighLatencyMode() &&
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 // up the BeginImplFrame and deadline as well. 563 // up the BeginImplFrame and deadline as well.
561 OnBeginImplFrameDeadline(); 564 OnBeginImplFrameDeadline();
562 return; 565 return;
563 } 566 }
564 begin_impl_frame_deadline_task_.Cancel(); 567 begin_impl_frame_deadline_task_.Cancel();
565 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_); 568 begin_impl_frame_deadline_task_.Reset(begin_impl_frame_deadline_closure_);
566 569
567 base::TimeDelta delta = deadline - gfx::FrameTime::Now(); 570 base::TimeDelta delta = deadline - gfx::FrameTime::Now();
568 if (delta <= base::TimeDelta()) 571 if (delta <= base::TimeDelta())
569 delta = base::TimeDelta(); 572 delta = base::TimeDelta();
570 impl_task_runner_->PostDelayedTask( 573 task_runner_->PostDelayedTask(
571 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta); 574 FROM_HERE, begin_impl_frame_deadline_task_.callback(), delta);
572 } 575 }
573 576
574 void Scheduler::OnBeginImplFrameDeadline() { 577 void Scheduler::OnBeginImplFrameDeadline() {
575 TRACE_EVENT0("cc", "Scheduler::OnBeginImplFrameDeadline"); 578 TRACE_EVENT0("cc", "Scheduler::OnBeginImplFrameDeadline");
576 begin_impl_frame_deadline_task_.Cancel(); 579 begin_impl_frame_deadline_task_.Cancel();
577 580
578 // We split the deadline actions up into two phases so the state machine 581 // We split the deadline actions up into two phases so the state machine
579 // has a chance to trigger actions that should occur durring and after 582 // has a chance to trigger actions that should occur durring and after
580 // the deadline separately. For example: 583 // the deadline separately. For example:
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
752 } 755 }
753 756
754 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 757 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
755 return (state_machine_.commit_state() == 758 return (state_machine_.commit_state() ==
756 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 759 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
757 state_machine_.commit_state() == 760 state_machine_.commit_state() ==
758 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 761 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
759 } 762 }
760 763
761 } // namespace cc 764 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/test/fake_layer_tree_host_client.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698