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

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

Issue 2379343003: Revert of cc: Remove frame queuing from the scheduler. (Closed)
Patch Set: Created 4 years, 2 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE), 57 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE),
58 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), 58 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
59 state_machine_(settings), 59 state_machine_(settings),
60 inside_process_scheduled_actions_(false), 60 inside_process_scheduled_actions_(false),
61 inside_action_(SchedulerStateMachine::ACTION_NONE), 61 inside_action_(SchedulerStateMachine::ACTION_NONE),
62 weak_factory_(this) { 62 weak_factory_(this) {
63 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue()); 63 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue());
64 DCHECK(client_); 64 DCHECK(client_);
65 DCHECK(!state_machine_.BeginFrameNeeded()); 65 DCHECK(!state_machine_.BeginFrameNeeded());
66 66
67 begin_retro_frame_closure_ =
68 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
67 begin_impl_frame_deadline_closure_ = base::Bind( 69 begin_impl_frame_deadline_closure_ = base::Bind(
68 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 70 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
69 71
70 SetBeginFrameSource(begin_frame_source); 72 SetBeginFrameSource(begin_frame_source);
71 ProcessScheduledActions(); 73 ProcessScheduledActions();
72 } 74 }
73 75
74 Scheduler::~Scheduler() { 76 Scheduler::~Scheduler() {
75 SetBeginFrameSource(nullptr); 77 SetBeginFrameSource(nullptr);
76 } 78 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 compositor_timing_history_->WillPrepareTiles(); 188 compositor_timing_history_->WillPrepareTiles();
187 } 189 }
188 190
189 void Scheduler::DidPrepareTiles() { 191 void Scheduler::DidPrepareTiles() {
190 compositor_timing_history_->DidPrepareTiles(); 192 compositor_timing_history_->DidPrepareTiles();
191 state_machine_.DidPrepareTiles(); 193 state_machine_.DidPrepareTiles();
192 } 194 }
193 195
194 void Scheduler::DidLoseCompositorFrameSink() { 196 void Scheduler::DidLoseCompositorFrameSink() {
195 TRACE_EVENT0("cc", "Scheduler::DidLoseCompositorFrameSink"); 197 TRACE_EVENT0("cc", "Scheduler::DidLoseCompositorFrameSink");
198 begin_retro_frame_args_.clear();
199 begin_retro_frame_task_.Cancel();
196 state_machine_.DidLoseCompositorFrameSink(); 200 state_machine_.DidLoseCompositorFrameSink();
197 UpdateCompositorTimingHistoryRecordingEnabled(); 201 UpdateCompositorTimingHistoryRecordingEnabled();
198 ProcessScheduledActions(); 202 ProcessScheduledActions();
199 } 203 }
200 204
201 void Scheduler::DidCreateAndInitializeCompositorFrameSink() { 205 void Scheduler::DidCreateAndInitializeCompositorFrameSink() {
202 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeCompositorFrameSink"); 206 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeCompositorFrameSink");
203 DCHECK(!observing_begin_frame_source_); 207 DCHECK(!observing_begin_frame_source_);
204 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 208 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
205 state_machine_.DidCreateAndInitializeCompositorFrameSink(); 209 state_machine_.DidCreateAndInitializeCompositorFrameSink();
(...skipping 16 matching lines...) Expand all
222 void Scheduler::BeginImplFrameNotExpectedSoon() { 226 void Scheduler::BeginImplFrameNotExpectedSoon() {
223 compositor_timing_history_->BeginImplFrameNotExpectedSoon(); 227 compositor_timing_history_->BeginImplFrameNotExpectedSoon();
224 228
225 // Tying this to SendBeginMainFrameNotExpectedSoon will have some 229 // Tying this to SendBeginMainFrameNotExpectedSoon will have some
226 // false negatives, but we want to avoid running long idle tasks when 230 // false negatives, but we want to avoid running long idle tasks when
227 // we are actually active. 231 // we are actually active.
228 client_->SendBeginMainFrameNotExpectedSoon(); 232 client_->SendBeginMainFrameNotExpectedSoon();
229 } 233 }
230 234
231 void Scheduler::SetupNextBeginFrameIfNeeded() { 235 void Scheduler::SetupNextBeginFrameIfNeeded() {
232 if (state_machine_.begin_impl_frame_state() != 236 // Never call SetNeedsBeginFrames if the frame source already has the right
233 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { 237 // value.
234 return; 238 if (observing_begin_frame_source_ != state_machine_.BeginFrameNeeded()) {
239 if (state_machine_.BeginFrameNeeded()) {
240 // Call AddObserver as soon as possible.
241 observing_begin_frame_source_ = true;
242 if (begin_frame_source_)
243 begin_frame_source_->AddObserver(this);
244 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
245 true);
246 } else if (state_machine_.begin_impl_frame_state() ==
247 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
248 // Call RemoveObserver in between frames only.
249 observing_begin_frame_source_ = false;
250 if (begin_frame_source_)
251 begin_frame_source_->RemoveObserver(this);
252 BeginImplFrameNotExpectedSoon();
253 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
254 false);
255 }
235 } 256 }
236 257
237 bool needs_begin_frames = state_machine_.BeginFrameNeeded(); 258 PostBeginRetroFrameIfNeeded();
238 if (needs_begin_frames && !observing_begin_frame_source_) {
239 observing_begin_frame_source_ = true;
240 if (begin_frame_source_)
241 begin_frame_source_->AddObserver(this);
242 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, true);
243 } else if (!needs_begin_frames && observing_begin_frame_source_) {
244 observing_begin_frame_source_ = false;
245 if (begin_frame_source_)
246 begin_frame_source_->RemoveObserver(this);
247 missed_begin_frame_task_.Cancel();
248 BeginImplFrameNotExpectedSoon();
249 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
250 false);
251 }
252 } 259 }
253 260
254 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { 261 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) {
255 if (state_machine_.begin_frame_source_paused() == paused) 262 if (state_machine_.begin_frame_source_paused() == paused)
256 return; 263 return;
257 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", 264 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused",
258 TRACE_EVENT_SCOPE_THREAD, "paused", paused); 265 TRACE_EVENT_SCOPE_THREAD, "paused", paused);
259 state_machine_.SetBeginFrameSourcePaused(paused); 266 state_machine_.SetBeginFrameSourcePaused(paused);
260 ProcessScheduledActions(); 267 ProcessScheduledActions();
261 } 268 }
262 269
263 // BeginFrame is the mechanism that tells us that now is a good time to start 270 // BeginFrame is the mechanism that tells us that now is a good time to start
264 // making a frame. Usually this means that user input for the frame is complete. 271 // making a frame. Usually this means that user input for the frame is complete.
265 // If the scheduler is busy, we queue the BeginFrame to be handled later as 272 // If the scheduler is busy, we queue the BeginFrame to be handled later as
266 // a BeginRetroFrame. 273 // a BeginRetroFrame.
267 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { 274 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
268 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); 275 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
269 276
270 if (!state_machine_.BeginFrameNeeded()) {
271 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped",
272 TRACE_EVENT_SCOPE_THREAD);
273 return false;
274 }
275
276 // Trace this begin frame time through the Chrome stack 277 // Trace this begin frame time through the Chrome stack
277 TRACE_EVENT_FLOW_BEGIN0( 278 TRACE_EVENT_FLOW_BEGIN0(
278 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", 279 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
279 args.frame_time.ToInternalValue()); 280 args.frame_time.ToInternalValue());
280 281
281 if (settings_.using_synchronous_renderer_compositor) { 282 if (settings_.using_synchronous_renderer_compositor) {
282 BeginImplFrameSynchronous(args); 283 BeginImplFrameSynchronous(args);
283 return true; 284 return true;
284 } 285 }
285 286
286 if (inside_process_scheduled_actions_) { 287 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has
287 // The BFS can send a missed begin frame inside AddObserver. We can't handle 288 // sent us the last BeginFrame we have missed. As we might not be able to
288 // a begin frame inside ProcessScheduledActions so post a task. 289 // actually make rendering for this call, handle it like a "retro frame".
289 DCHECK_EQ(args.type, BeginFrameArgs::MISSED); 290 // TODO(brainderson): Add a test for this functionality ASAP!
290 DCHECK(missed_begin_frame_task_.IsCancelled()); 291 if (args.type == BeginFrameArgs::MISSED) {
291 missed_begin_frame_task_.Reset(base::Bind( 292 begin_retro_frame_args_.push_back(args);
292 &Scheduler::BeginImplFrameWithDeadline, base::Unretained(this), args)); 293 PostBeginRetroFrameIfNeeded();
293 task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
294 return true; 294 return true;
295 } 295 }
296 296
297 BeginImplFrameWithDeadline(args); 297 bool should_defer_begin_frame =
298 !begin_retro_frame_args_.empty() ||
299 !begin_retro_frame_task_.IsCancelled() ||
300 !observing_begin_frame_source_ ||
301 (state_machine_.begin_impl_frame_state() !=
302 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
303
304 if (should_defer_begin_frame) {
305 begin_retro_frame_args_.push_back(args);
306 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrame deferred",
307 TRACE_EVENT_SCOPE_THREAD);
308 // Queuing the frame counts as "using it", so we need to return true.
309 } else {
310 BeginImplFrameWithDeadline(args);
311 }
298 return true; 312 return true;
299 } 313 }
300 314
301 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { 315 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) {
302 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); 316 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames);
303 ProcessScheduledActions(); 317 ProcessScheduledActions();
304 } 318 }
305 319
306 void Scheduler::OnDrawForCompositorFrameSink(bool resourceless_software_draw) { 320 void Scheduler::OnDrawForCompositorFrameSink(bool resourceless_software_draw) {
307 DCHECK(settings_.using_synchronous_renderer_compositor); 321 DCHECK(settings_.using_synchronous_renderer_compositor);
308 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 322 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
309 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 323 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
310 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 324 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
311 325
312 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw); 326 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw);
313 state_machine_.OnBeginImplFrameDeadline(); 327 state_machine_.OnBeginImplFrameDeadline();
314 ProcessScheduledActions(); 328 ProcessScheduledActions();
315 329
316 state_machine_.OnBeginImplFrameIdle(); 330 state_machine_.OnBeginImplFrameIdle();
317 ProcessScheduledActions(); 331 ProcessScheduledActions();
318 state_machine_.SetResourcelessSoftwareDraw(false); 332 state_machine_.SetResourcelessSoftwareDraw(false);
319 } 333 }
320 334
321 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { 335 // BeginRetroFrame is called for BeginFrames that we've deferred because
322 // The storage for |args| is owned by the missed begin frame task. Therefore 336 // the scheduler was in the middle of processing a previous BeginFrame.
323 // save |args| before cancelling the task either here or in the deadline. 337 void Scheduler::BeginRetroFrame() {
324 BeginFrameArgs adjusted_args = args; 338 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame");
325 // Cancel the missed begin frame task in case the BFS sends a begin frame 339 DCHECK(!settings_.using_synchronous_renderer_compositor);
326 // before the missed frame task runs. 340 DCHECK(!begin_retro_frame_args_.empty());
327 missed_begin_frame_task_.Cancel(); 341 DCHECK(!begin_retro_frame_task_.IsCancelled());
328
329 // Discard missed begin frames if they are too late.
330 if (adjusted_args.type == BeginFrameArgs::MISSED &&
331 Now() > adjusted_args.deadline) {
332 begin_frame_source_->DidFinishFrame(this, 0);
333 return;
334 }
335
336 // Run the previous deadline if any.
337 if (state_machine_.begin_impl_frame_state() ==
338 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) {
339 OnBeginImplFrameDeadline();
340 // We may not need begin frames any longer.
341 if (!observing_begin_frame_source_) {
342 begin_frame_source_->DidFinishFrame(this, 0);
343 return;
344 }
345 }
346 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 342 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
347 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 343 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
348 344
345 begin_retro_frame_task_.Cancel();
346
347 // Discard expired BeginRetroFrames
348 // Today, we should always end up with at most one un-expired BeginRetroFrame
349 // because deadlines will not be greater than the next frame time. We don't
350 // DCHECK though because some systems don't always have monotonic timestamps.
351 // TODO(brianderson): In the future, long deadlines could result in us not
352 // draining the queue if we don't catch up. If we consistently can't catch
353 // up, our fallback should be to lower our frame rate.
354 base::TimeTicks now = Now();
355
356 while (!begin_retro_frame_args_.empty()) {
357 const BeginFrameArgs& args = begin_retro_frame_args_.front();
358 base::TimeTicks expiration_time = args.deadline;
359 if (now <= expiration_time)
360 break;
361 TRACE_EVENT_INSTANT2(
362 "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD,
363 "expiration_time - now", (expiration_time - now).InMillisecondsF(),
364 "BeginFrameArgs", begin_retro_frame_args_.front().AsValue());
365 begin_retro_frame_args_.pop_front();
366 if (begin_frame_source_)
367 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size());
368 }
369
370 if (begin_retro_frame_args_.empty()) {
371 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginRetroFrames all expired",
372 TRACE_EVENT_SCOPE_THREAD);
373 } else {
374 BeginFrameArgs front = begin_retro_frame_args_.front();
375 begin_retro_frame_args_.pop_front();
376 BeginImplFrameWithDeadline(front);
377 }
378 }
379
380 // There could be a race between the posted BeginRetroFrame and a new
381 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
382 // will check if there is a pending BeginRetroFrame to ensure we handle
383 // BeginFrames in FIFO order.
384 void Scheduler::PostBeginRetroFrameIfNeeded() {
385 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
386 "Scheduler::PostBeginRetroFrameIfNeeded", "state", AsValue());
387 if (!observing_begin_frame_source_)
388 return;
389
390 if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled())
391 return;
392
393 // begin_retro_frame_args_ should always be empty for the
394 // synchronous compositor.
395 DCHECK(!settings_.using_synchronous_renderer_compositor);
396
397 if (state_machine_.begin_impl_frame_state() !=
398 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
399 return;
400
401 begin_retro_frame_task_.Reset(begin_retro_frame_closure_);
402
403 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback());
404 }
405
406 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
349 bool main_thread_is_in_high_latency_mode = 407 bool main_thread_is_in_high_latency_mode =
350 state_machine_.main_thread_missed_last_deadline(); 408 state_machine_.main_thread_missed_last_deadline();
351 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", 409 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args",
352 adjusted_args.AsValue(), "main_thread_missed_last_deadline", 410 args.AsValue(), "main_thread_missed_last_deadline",
353 main_thread_is_in_high_latency_mode); 411 main_thread_is_in_high_latency_mode);
354 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 412 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
355 "MainThreadLatency", main_thread_is_in_high_latency_mode); 413 "MainThreadLatency", main_thread_is_in_high_latency_mode);
356 414
357 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 415 BeginFrameArgs adjusted_args = args;
358 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
359
360 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); 416 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate();
361 adjusted_args.deadline -= kDeadlineFudgeFactor; 417 adjusted_args.deadline -= kDeadlineFudgeFactor;
362 418
363 base::TimeDelta bmf_start_to_activate = 419 base::TimeDelta bmf_start_to_activate =
364 compositor_timing_history_ 420 compositor_timing_history_
365 ->BeginMainFrameStartToCommitDurationEstimate() + 421 ->BeginMainFrameStartToCommitDurationEstimate() +
366 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + 422 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() +
367 compositor_timing_history_->ActivateDurationEstimate(); 423 compositor_timing_history_->ActivateDurationEstimate();
368 424
369 base::TimeDelta bmf_to_activate_estimate_critical = 425 base::TimeDelta bmf_to_activate_estimate_critical =
370 bmf_start_to_activate + 426 bmf_start_to_activate +
371 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); 427 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate();
372 428
373 state_machine_.SetCriticalBeginMainFrameToActivateIsFast( 429 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(
374 bmf_to_activate_estimate_critical < adjusted_args.interval); 430 bmf_to_activate_estimate_critical < args.interval);
375 431
376 // Update the BeginMainFrame args now that we know whether the main 432 // Update the BeginMainFrame args now that we know whether the main
377 // thread will be on the critical path or not. 433 // thread will be on the critical path or not.
378 begin_main_frame_args_ = adjusted_args; 434 begin_main_frame_args_ = adjusted_args;
379 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); 435 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority();
380 436
381 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical; 437 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical;
382 if (!begin_main_frame_args_.on_critical_path) { 438 if (!begin_main_frame_args_.on_critical_path) {
383 bmf_to_activate_estimate = 439 bmf_to_activate_estimate =
384 bmf_start_to_activate + 440 bmf_start_to_activate +
385 compositor_timing_history_ 441 compositor_timing_history_
386 ->BeginMainFrameQueueDurationNotCriticalEstimate(); 442 ->BeginMainFrameQueueDurationNotCriticalEstimate();
387 } 443 }
388 444
389 bool can_activate_before_deadline = 445 bool can_activate_before_deadline =
390 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args, 446 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args,
391 bmf_to_activate_estimate); 447 bmf_to_activate_estimate);
392 448
393 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { 449 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) {
394 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", 450 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency",
395 TRACE_EVENT_SCOPE_THREAD); 451 TRACE_EVENT_SCOPE_THREAD);
396 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 452 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
397 } else if (ShouldRecoverImplLatency(adjusted_args, 453 } else if (ShouldRecoverImplLatency(adjusted_args,
398 can_activate_before_deadline)) { 454 can_activate_before_deadline)) {
399 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", 455 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency",
400 TRACE_EVENT_SCOPE_THREAD); 456 TRACE_EVENT_SCOPE_THREAD);
401 if (begin_frame_source_) 457 if (begin_frame_source_)
402 begin_frame_source_->DidFinishFrame(this, 0); 458 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size());
403 return; 459 return;
404 } 460 }
405 461
406 BeginImplFrame(adjusted_args); 462 BeginImplFrame(adjusted_args);
407 } 463 }
408 464
409 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { 465 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
410 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", 466 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args",
411 args.AsValue()); 467 args.AsValue());
412 468
413 // The main thread currently can't commit before we draw with the 469 // The main thread currently can't commit before we draw with the
414 // synchronous compositor, so never consider the BeginMainFrame fast. 470 // synchronous compositor, so never consider the BeginMainFrame fast.
415 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); 471 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false);
416 begin_main_frame_args_ = args; 472 begin_main_frame_args_ = args;
417 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); 473 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority();
418 474
419 BeginImplFrame(args); 475 BeginImplFrame(args);
420 compositor_timing_history_->WillFinishImplFrame( 476 compositor_timing_history_->WillFinishImplFrame(
421 state_machine_.needs_redraw()); 477 state_machine_.needs_redraw());
422 FinishImplFrame(); 478 FinishImplFrame();
423 } 479 }
424 480
425 void Scheduler::FinishImplFrame() { 481 void Scheduler::FinishImplFrame() {
426 state_machine_.OnBeginImplFrameIdle(); 482 state_machine_.OnBeginImplFrameIdle();
427 ProcessScheduledActions(); 483 ProcessScheduledActions();
428 484
429 client_->DidFinishImplFrame(); 485 client_->DidFinishImplFrame();
430 if (begin_frame_source_) 486 if (begin_frame_source_)
431 begin_frame_source_->DidFinishFrame(this, 0); 487 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size());
432 begin_impl_frame_tracker_.Finish(); 488 begin_impl_frame_tracker_.Finish();
433 } 489 }
434 490
435 // BeginImplFrame starts a compositor frame that will wait up until a deadline 491 // BeginImplFrame starts a compositor frame that will wait up until a deadline
436 // for a BeginMainFrame+activation to complete before it times out and draws 492 // for a BeginMainFrame+activation to complete before it times out and draws
437 // any asynchronous animation and scroll/pinch updates. 493 // any asynchronous animation and scroll/pinch updates.
438 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 494 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
439 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 495 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
440 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 496 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
441 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 497 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 new base::trace_event::TracedValue()); 702 new base::trace_event::TracedValue());
647 base::TimeTicks now = Now(); 703 base::TimeTicks now = Now();
648 704
649 state->BeginDictionary("state_machine"); 705 state->BeginDictionary("state_machine");
650 state_machine_.AsValueInto(state.get()); 706 state_machine_.AsValueInto(state.get());
651 state->EndDictionary(); 707 state->EndDictionary();
652 708
653 state->BeginDictionary("scheduler_state"); 709 state->BeginDictionary("scheduler_state");
654 state->SetBoolean("observing_begin_frame_source", 710 state->SetBoolean("observing_begin_frame_source",
655 observing_begin_frame_source_); 711 observing_begin_frame_source_);
712 state->SetInteger("begin_retro_frame_args",
713 static_cast<int>(begin_retro_frame_args_.size()));
714 state->SetBoolean("begin_retro_frame_task",
715 !begin_retro_frame_task_.IsCancelled());
656 state->SetBoolean("begin_impl_frame_deadline_task", 716 state->SetBoolean("begin_impl_frame_deadline_task",
657 !begin_impl_frame_deadline_task_.IsCancelled()); 717 !begin_impl_frame_deadline_task_.IsCancelled());
658 state->SetBoolean("missed_begin_frame_task",
659 !missed_begin_frame_task_.IsCancelled());
660 state->SetString("inside_action", 718 state->SetString("inside_action",
661 SchedulerStateMachine::ActionToString(inside_action_)); 719 SchedulerStateMachine::ActionToString(inside_action_));
662 720
663 state->BeginDictionary("begin_impl_frame_args"); 721 state->BeginDictionary("begin_impl_frame_args");
664 begin_impl_frame_tracker_.AsValueInto(now, state.get()); 722 begin_impl_frame_tracker_.AsValueInto(now, state.get());
665 state->EndDictionary(); 723 state->EndDictionary();
666 724
667 state->SetString("begin_impl_frame_deadline_mode_", 725 state->SetString("begin_impl_frame_deadline_mode_",
668 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( 726 SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
669 begin_impl_frame_deadline_mode_)); 727 begin_impl_frame_deadline_mode_));
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 } 812 }
755 813
756 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 814 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
757 return (state_machine_.begin_main_frame_state() == 815 return (state_machine_.begin_main_frame_state() ==
758 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || 816 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT ||
759 state_machine_.begin_main_frame_state() == 817 state_machine_.begin_main_frame_state() ==
760 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); 818 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED);
761 } 819 }
762 820
763 } // namespace cc 821 } // 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