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

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

Issue 2632563003: [cc] Calculate the correct latest_confirmed_sequence_number in cc::Scheduler. (Closed)
Patch Set: add todo for impl-side invalidations. Created 3 years, 10 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
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.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 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 // BeginFrame is the mechanism that tells us that now is a good time to start 259 // BeginFrame is the mechanism that tells us that now is a good time to start
260 // making a frame. Usually this means that user input for the frame is complete. 260 // making a frame. Usually this means that user input for the frame is complete.
261 // If the scheduler is busy, we queue the BeginFrame to be handled later as 261 // If the scheduler is busy, we queue the BeginFrame to be handled later as
262 // a BeginRetroFrame. 262 // a BeginRetroFrame.
263 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { 263 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
264 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); 264 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
265 265
266 if (!state_machine_.BeginFrameNeeded()) { 266 if (!state_machine_.BeginFrameNeeded()) {
267 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped", 267 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped",
268 TRACE_EVENT_SCOPE_THREAD); 268 TRACE_EVENT_SCOPE_THREAD);
269 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. 269 // Since we don't use the BeginFrame, we may later receive the same
270 BeginFrameAck ack(args.source_id, args.sequence_number, 270 // BeginFrame again. Thus, we can't confirm it at this point, even though we
271 args.sequence_number, 0, false); 271 // don't have any updates right now.
272 begin_frame_source_->DidFinishFrame(this, ack); 272 SendBeginFrameAck(args, kBeginFrameSkipped);
273 return false; 273 return false;
274 } 274 }
275 275
276 // Trace this begin frame time through the Chrome stack 276 // Trace this begin frame time through the Chrome stack
277 TRACE_EVENT_FLOW_BEGIN0( 277 TRACE_EVENT_FLOW_BEGIN0(
278 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", 278 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
279 args.frame_time.ToInternalValue()); 279 args.frame_time.ToInternalValue());
280 280
281 if (settings_.using_synchronous_renderer_compositor) { 281 if (settings_.using_synchronous_renderer_compositor) {
282 BeginImplFrameSynchronous(args); 282 BeginImplFrameSynchronous(args);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 BeginFrameArgs adjusted_args = args; 324 BeginFrameArgs adjusted_args = args;
325 // Cancel the missed begin frame task in case the BFS sends a begin frame 325 // Cancel the missed begin frame task in case the BFS sends a begin frame
326 // before the missed frame task runs. 326 // before the missed frame task runs.
327 missed_begin_frame_task_.Cancel(); 327 missed_begin_frame_task_.Cancel();
328 328
329 base::TimeTicks now = Now(); 329 base::TimeTicks now = Now();
330 330
331 // Discard missed begin frames if they are too late. 331 // Discard missed begin frames if they are too late.
332 if (adjusted_args.type == BeginFrameArgs::MISSED && 332 if (adjusted_args.type == BeginFrameArgs::MISSED &&
333 now > adjusted_args.deadline) { 333 now > adjusted_args.deadline) {
334 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. 334 SendBeginFrameAck(adjusted_args, kBeginFrameSkipped);
335 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number,
336 adjusted_args.sequence_number, 0, false);
337 begin_frame_source_->DidFinishFrame(this, ack);
338 return; 335 return;
339 } 336 }
340 337
341 // Run the previous deadline if any. 338 // Run the previous deadline if any.
342 if (state_machine_.begin_impl_frame_state() == 339 if (state_machine_.begin_impl_frame_state() ==
343 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) { 340 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) {
344 OnBeginImplFrameDeadline(); 341 OnBeginImplFrameDeadline();
345 // We may not need begin frames any longer. 342 // We may not need begin frames any longer.
346 if (!observing_begin_frame_source_) { 343 if (!observing_begin_frame_source_) {
347 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. 344 // We need to confirm the ignored BeginFrame, since we don't have updates.
348 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number, 345 // To persist the confirmation for future BeginFrameAcks, we let the state
349 adjusted_args.sequence_number, 0, false); 346 // machine know about the BeginFrame.
350 begin_frame_source_->DidFinishFrame(this, ack); 347 state_machine_.OnBeginFrameDroppedNotObserving(args.source_id,
348 args.sequence_number);
349 SendBeginFrameAck(adjusted_args, kBeginFrameSkipped);
351 return; 350 return;
352 } 351 }
353 } 352 }
354 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 353 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
355 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 354 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
356 355
357 bool main_thread_is_in_high_latency_mode = 356 bool main_thread_is_in_high_latency_mode =
358 state_machine_.main_thread_missed_last_deadline(); 357 state_machine_.main_thread_missed_last_deadline();
359 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", 358 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args",
360 adjusted_args.AsValue(), "main_thread_missed_last_deadline", 359 adjusted_args.AsValue(), "main_thread_missed_last_deadline",
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
399 bmf_to_activate_estimate, now); 398 bmf_to_activate_estimate, now);
400 399
401 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { 400 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) {
402 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", 401 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency",
403 TRACE_EVENT_SCOPE_THREAD); 402 TRACE_EVENT_SCOPE_THREAD);
404 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 403 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
405 } else if (ShouldRecoverImplLatency(adjusted_args, 404 } else if (ShouldRecoverImplLatency(adjusted_args,
406 can_activate_before_deadline)) { 405 can_activate_before_deadline)) {
407 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", 406 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency",
408 TRACE_EVENT_SCOPE_THREAD); 407 TRACE_EVENT_SCOPE_THREAD);
409 if (begin_frame_source_) { 408 SendBeginFrameAck(begin_main_frame_args_, kBeginFrameSkipped);
410 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|.
411 BeginFrameAck ack(adjusted_args.source_id, adjusted_args.sequence_number,
412 adjusted_args.sequence_number, 0, false);
413 begin_frame_source_->DidFinishFrame(this, ack);
414 }
415 return; 409 return;
416 } 410 }
417 411
418 BeginImplFrame(adjusted_args); 412 BeginImplFrame(adjusted_args);
419 } 413 }
420 414
421 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { 415 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
422 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", 416 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args",
423 args.AsValue()); 417 args.AsValue());
424 418
425 // The main thread currently can't commit before we draw with the 419 // The main thread currently can't commit before we draw with the
426 // synchronous compositor, so never consider the BeginMainFrame fast. 420 // synchronous compositor, so never consider the BeginMainFrame fast.
427 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); 421 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false);
428 begin_main_frame_args_ = args; 422 begin_main_frame_args_ = args;
429 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); 423 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority();
430 424
431 BeginImplFrame(args); 425 BeginImplFrame(args);
432 compositor_timing_history_->WillFinishImplFrame( 426 compositor_timing_history_->WillFinishImplFrame(
433 state_machine_.needs_redraw()); 427 state_machine_.needs_redraw());
434 FinishImplFrame(); 428 FinishImplFrame();
435 } 429 }
436 430
437 void Scheduler::FinishImplFrame() { 431 void Scheduler::FinishImplFrame() {
438 state_machine_.OnBeginImplFrameIdle(); 432 state_machine_.OnBeginImplFrameIdle();
439 ProcessScheduledActions(); 433 ProcessScheduledActions();
440 434
441 client_->DidFinishImplFrame(); 435 client_->DidFinishImplFrame();
442 if (begin_frame_source_) { 436 SendBeginFrameAck(begin_main_frame_args_, kBeginFrameFinished);
443 // TODO(eseckler): Determine and set correct |ack.latest_confirmed_frame|. 437 begin_impl_frame_tracker_.Finish();
444 BeginFrameAck ack(begin_main_frame_args_.source_id, 438 }
445 begin_main_frame_args_.sequence_number, 439
446 begin_main_frame_args_.sequence_number, 0, 440 void Scheduler::SendBeginFrameAck(const BeginFrameArgs& args,
447 state_machine_.did_submit_in_last_frame()); 441 BeginFrameResult result) {
448 begin_frame_source_->DidFinishFrame(this, ack); 442 if (!begin_frame_source_)
443 return;
444
445 uint64_t latest_confirmed_sequence_number =
446 BeginFrameArgs::kInvalidFrameNumber;
447 if (args.source_id == state_machine_.begin_frame_source_id()) {
448 latest_confirmed_sequence_number =
449 state_machine_
450 .last_begin_frame_sequence_number_compositor_frame_was_fresh();
449 } 451 }
450 begin_impl_frame_tracker_.Finish(); 452
453 bool did_submit = false;
454 if (result == kBeginFrameFinished) {
455 did_submit = state_machine_.did_submit_in_last_frame();
456 }
457
458 BeginFrameAck ack(args.source_id, args.sequence_number,
459 latest_confirmed_sequence_number, 0, did_submit);
460 begin_frame_source_->DidFinishFrame(this, ack);
451 } 461 }
452 462
453 // BeginImplFrame starts a compositor frame that will wait up until a deadline 463 // BeginImplFrame starts a compositor frame that will wait up until a deadline
454 // for a BeginMainFrame+activation to complete before it times out and draws 464 // for a BeginMainFrame+activation to complete before it times out and draws
455 // any asynchronous animation and scroll/pinch updates. 465 // any asynchronous animation and scroll/pinch updates.
456 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 466 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
457 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 467 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
458 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 468 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
459 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 469 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
460 DCHECK(state_machine_.HasInitializedCompositorFrameSink()); 470 DCHECK(state_machine_.HasInitializedCompositorFrameSink());
461 471
462 begin_impl_frame_tracker_.Start(args); 472 begin_impl_frame_tracker_.Start(args);
463 state_machine_.OnBeginImplFrame(); 473 state_machine_.OnBeginImplFrame(args.source_id, args.sequence_number);
464 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); 474 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
465 compositor_timing_history_->WillBeginImplFrame( 475 compositor_timing_history_->WillBeginImplFrame(
466 state_machine_.NewActiveTreeLikely()); 476 state_machine_.NewActiveTreeLikely());
467 client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current()); 477 client_->WillBeginImplFrame(begin_impl_frame_tracker_.Current());
468 478
469 ProcessScheduledActions(); 479 ProcessScheduledActions();
470 } 480 }
471 481
472 void Scheduler::ScheduleBeginImplFrameDeadline() { 482 void Scheduler::ScheduleBeginImplFrameDeadline() {
473 // The synchronous compositor does not post a deadline task. 483 // The synchronous compositor does not post a deadline task.
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 } 792 }
783 793
784 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 794 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
785 return (state_machine_.begin_main_frame_state() == 795 return (state_machine_.begin_main_frame_state() ==
786 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || 796 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT ||
787 state_machine_.begin_main_frame_state() == 797 state_machine_.begin_main_frame_state() ==
788 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); 798 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED);
789 } 799 }
790 800
791 } // namespace cc 801 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698