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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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()); | |
69 begin_impl_frame_deadline_closure_ = base::Bind( | 67 begin_impl_frame_deadline_closure_ = base::Bind( |
70 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); | 68 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); |
71 | 69 |
72 SetBeginFrameSource(begin_frame_source); | 70 SetBeginFrameSource(begin_frame_source); |
73 ProcessScheduledActions(); | 71 ProcessScheduledActions(); |
74 } | 72 } |
75 | 73 |
76 Scheduler::~Scheduler() { | 74 Scheduler::~Scheduler() { |
77 SetBeginFrameSource(nullptr); | 75 SetBeginFrameSource(nullptr); |
78 } | 76 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
193 compositor_timing_history_->WillPrepareTiles(); | 191 compositor_timing_history_->WillPrepareTiles(); |
194 } | 192 } |
195 | 193 |
196 void Scheduler::DidPrepareTiles() { | 194 void Scheduler::DidPrepareTiles() { |
197 compositor_timing_history_->DidPrepareTiles(); | 195 compositor_timing_history_->DidPrepareTiles(); |
198 state_machine_.DidPrepareTiles(); | 196 state_machine_.DidPrepareTiles(); |
199 } | 197 } |
200 | 198 |
201 void Scheduler::DidLoseOutputSurface() { | 199 void Scheduler::DidLoseOutputSurface() { |
202 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); | 200 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
203 begin_retro_frame_args_.clear(); | |
204 begin_retro_frame_task_.Cancel(); | |
205 state_machine_.DidLoseOutputSurface(); | 201 state_machine_.DidLoseOutputSurface(); |
206 UpdateCompositorTimingHistoryRecordingEnabled(); | 202 UpdateCompositorTimingHistoryRecordingEnabled(); |
207 ProcessScheduledActions(); | 203 ProcessScheduledActions(); |
208 } | 204 } |
209 | 205 |
210 void Scheduler::DidCreateAndInitializeOutputSurface() { | 206 void Scheduler::DidCreateAndInitializeOutputSurface() { |
211 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); | 207 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
212 DCHECK(!observing_begin_frame_source_); | 208 DCHECK(!observing_begin_frame_source_); |
213 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 209 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
214 state_machine_.DidCreateAndInitializeOutputSurface(); | 210 state_machine_.DidCreateAndInitializeOutputSurface(); |
(...skipping 16 matching lines...) Expand all Loading... | |
231 void Scheduler::BeginImplFrameNotExpectedSoon() { | 227 void Scheduler::BeginImplFrameNotExpectedSoon() { |
232 compositor_timing_history_->BeginImplFrameNotExpectedSoon(); | 228 compositor_timing_history_->BeginImplFrameNotExpectedSoon(); |
233 | 229 |
234 // Tying this to SendBeginMainFrameNotExpectedSoon will have some | 230 // Tying this to SendBeginMainFrameNotExpectedSoon will have some |
235 // false negatives, but we want to avoid running long idle tasks when | 231 // false negatives, but we want to avoid running long idle tasks when |
236 // we are actually active. | 232 // we are actually active. |
237 client_->SendBeginMainFrameNotExpectedSoon(); | 233 client_->SendBeginMainFrameNotExpectedSoon(); |
238 } | 234 } |
239 | 235 |
240 void Scheduler::SetupNextBeginFrameIfNeeded() { | 236 void Scheduler::SetupNextBeginFrameIfNeeded() { |
241 // Never call SetNeedsBeginFrames if the frame source already has the right | 237 if (state_machine_.begin_impl_frame_state() != |
242 // value. | 238 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { |
243 if (observing_begin_frame_source_ != state_machine_.BeginFrameNeeded()) { | 239 return; |
244 if (state_machine_.BeginFrameNeeded()) { | |
245 // Call AddObserver as soon as possible. | |
246 observing_begin_frame_source_ = true; | |
247 if (begin_frame_source_) | |
248 begin_frame_source_->AddObserver(this); | |
249 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, | |
250 true); | |
251 } else if (state_machine_.begin_impl_frame_state() == | |
252 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { | |
253 // Call RemoveObserver in between frames only. | |
254 observing_begin_frame_source_ = false; | |
255 if (begin_frame_source_) | |
256 begin_frame_source_->RemoveObserver(this); | |
257 BeginImplFrameNotExpectedSoon(); | |
258 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, | |
259 false); | |
260 } | |
261 } | 240 } |
262 | 241 |
263 PostBeginRetroFrameIfNeeded(); | 242 bool needs_begin_frames = state_machine_.BeginFrameNeeded(); |
243 if (needs_begin_frames && !observing_begin_frame_source_) { | |
244 observing_begin_frame_source_ = true; | |
245 if (begin_frame_source_) | |
246 begin_frame_source_->AddObserver(this); | |
247 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, true); | |
248 } else if (!needs_begin_frames && observing_begin_frame_source_) { | |
249 observing_begin_frame_source_ = false; | |
250 if (begin_frame_source_) | |
251 begin_frame_source_->RemoveObserver(this); | |
252 missed_begin_frame_task_.Cancel(); | |
253 BeginImplFrameNotExpectedSoon(); | |
254 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, | |
255 false); | |
256 } | |
264 } | 257 } |
265 | 258 |
266 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { | 259 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { |
267 if (state_machine_.begin_frame_source_paused() == paused) | 260 if (state_machine_.begin_frame_source_paused() == paused) |
268 return; | 261 return; |
269 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", | 262 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", |
270 TRACE_EVENT_SCOPE_THREAD, "paused", paused); | 263 TRACE_EVENT_SCOPE_THREAD, "paused", paused); |
271 state_machine_.SetBeginFrameSourcePaused(paused); | 264 state_machine_.SetBeginFrameSourcePaused(paused); |
272 ProcessScheduledActions(); | 265 ProcessScheduledActions(); |
273 } | 266 } |
274 | 267 |
275 // BeginFrame is the mechanism that tells us that now is a good time to start | 268 // BeginFrame is the mechanism that tells us that now is a good time to start |
276 // making a frame. Usually this means that user input for the frame is complete. | 269 // making a frame. Usually this means that user input for the frame is complete. |
277 // If the scheduler is busy, we queue the BeginFrame to be handled later as | 270 // If the scheduler is busy, we queue the BeginFrame to be handled later as |
278 // a BeginRetroFrame. | 271 // a BeginRetroFrame. |
279 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { | 272 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { |
280 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); | 273 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); |
281 | 274 |
275 if (!state_machine_.BeginFrameNeeded()) { | |
brianderson
2016/09/19 22:56:44
This block of code may cause us to skip frames in
sunnyps
2016/09/19 23:59:04
This is handled by missed begin frames which are s
| |
276 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped", | |
277 TRACE_EVENT_SCOPE_THREAD); | |
278 return false; | |
279 } | |
280 | |
282 // Trace this begin frame time through the Chrome stack | 281 // Trace this begin frame time through the Chrome stack |
283 TRACE_EVENT_FLOW_BEGIN0( | 282 TRACE_EVENT_FLOW_BEGIN0( |
284 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", | 283 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", |
285 args.frame_time.ToInternalValue()); | 284 args.frame_time.ToInternalValue()); |
286 | 285 |
287 // TODO(brianderson): Adjust deadline in the DisplayScheduler. | 286 // TODO(brianderson): Adjust deadline in the DisplayScheduler. |
288 BeginFrameArgs adjusted_args(args); | 287 BeginFrameArgs adjusted_args(args); |
289 adjusted_args.deadline -= EstimatedParentDrawTime(); | 288 adjusted_args.deadline -= EstimatedParentDrawTime(); |
290 | 289 |
291 if (settings_.using_synchronous_renderer_compositor) { | 290 if (settings_.using_synchronous_renderer_compositor) { |
292 BeginImplFrameSynchronous(adjusted_args); | 291 BeginImplFrameSynchronous(adjusted_args); |
293 return true; | 292 return true; |
294 } | 293 } |
295 | 294 |
296 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has | 295 if (inside_process_scheduled_actions_) { |
297 // sent us the last BeginFrame we have missed. As we might not be able to | 296 // The BFS can send a missed begin frame inside AddObserver. We can't handle |
298 // actually make rendering for this call, handle it like a "retro frame". | 297 // a begin frame inside ProcessScheduledActions so post a task. |
299 // TODO(brainderson): Add a test for this functionality ASAP! | 298 DCHECK_EQ(adjusted_args.type, BeginFrameArgs::MISSED); |
300 if (adjusted_args.type == BeginFrameArgs::MISSED) { | 299 DCHECK(missed_begin_frame_task_.IsCancelled()); |
301 begin_retro_frame_args_.push_back(adjusted_args); | 300 missed_begin_frame_task_.Reset( |
302 PostBeginRetroFrameIfNeeded(); | 301 base::Bind(&Scheduler::BeginImplFrameWithDeadline, |
302 base::Unretained(this), adjusted_args)); | |
303 task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback()); | |
303 return true; | 304 return true; |
304 } | 305 } |
305 | 306 |
306 bool should_defer_begin_frame = | 307 BeginImplFrameWithDeadline(adjusted_args); |
307 !begin_retro_frame_args_.empty() || | |
308 !begin_retro_frame_task_.IsCancelled() || | |
309 !observing_begin_frame_source_ || | |
310 (state_machine_.begin_impl_frame_state() != | |
311 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
312 | |
313 if (should_defer_begin_frame) { | |
314 begin_retro_frame_args_.push_back(adjusted_args); | |
315 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrame deferred", | |
316 TRACE_EVENT_SCOPE_THREAD); | |
317 // Queuing the frame counts as "using it", so we need to return true. | |
318 } else { | |
319 BeginImplFrameWithDeadline(adjusted_args); | |
320 } | |
321 return true; | 308 return true; |
322 } | 309 } |
323 | 310 |
324 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { | 311 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { |
325 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); | 312 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); |
326 ProcessScheduledActions(); | 313 ProcessScheduledActions(); |
327 } | 314 } |
328 | 315 |
329 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) { | 316 void Scheduler::OnDrawForOutputSurface(bool resourceless_software_draw) { |
330 DCHECK(settings_.using_synchronous_renderer_compositor); | 317 DCHECK(settings_.using_synchronous_renderer_compositor); |
331 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 318 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
332 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 319 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
333 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 320 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
334 | 321 |
335 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw); | 322 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw); |
336 state_machine_.OnBeginImplFrameDeadline(); | 323 state_machine_.OnBeginImplFrameDeadline(); |
337 ProcessScheduledActions(); | 324 ProcessScheduledActions(); |
338 | 325 |
339 state_machine_.OnBeginImplFrameIdle(); | 326 state_machine_.OnBeginImplFrameIdle(); |
340 ProcessScheduledActions(); | 327 ProcessScheduledActions(); |
341 state_machine_.SetResourcelessSoftwareDraw(false); | 328 state_machine_.SetResourcelessSoftwareDraw(false); |
342 } | 329 } |
343 | 330 |
344 // BeginRetroFrame is called for BeginFrames that we've deferred because | 331 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { |
345 // the scheduler was in the middle of processing a previous BeginFrame. | 332 // The storage for |args| is owned by the missed begin frame task. Therefore |
346 void Scheduler::BeginRetroFrame() { | 333 // save |args| before cancelling the task either here or in the deadline. |
347 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame"); | 334 BeginFrameArgs adjusted_args = args; |
348 DCHECK(!settings_.using_synchronous_renderer_compositor); | 335 // Cancel the missed begin frame task in case the BFS sends a begin frame |
349 DCHECK(!begin_retro_frame_args_.empty()); | 336 // before the missed frame task runs. |
350 DCHECK(!begin_retro_frame_task_.IsCancelled()); | 337 missed_begin_frame_task_.Cancel(); |
338 | |
339 // Discard missed begin frames in renderer scheduler if they are too late. | |
brianderson
2016/09/19 22:56:44
Can you add a comment explaining why there's a dif
sunnyps
2016/09/19 23:59:04
Actually I removed the exception for the browser.
| |
340 if (!settings_.commit_to_active_tree && | |
341 adjusted_args.type == BeginFrameArgs::MISSED && | |
342 Now() > adjusted_args.deadline) { | |
343 begin_frame_source_->DidFinishFrame(this, 0); | |
344 return; | |
345 } | |
346 | |
347 // Run the previous deadline if any. | |
348 if (state_machine_.begin_impl_frame_state() == | |
349 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) { | |
350 OnBeginImplFrameDeadline(); | |
351 // We may not need begin frames any longer. | |
352 if (!observing_begin_frame_source_) { | |
353 begin_frame_source_->DidFinishFrame(this, 0); | |
354 return; | |
355 } | |
356 } | |
351 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 357 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
352 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 358 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
353 | 359 |
354 begin_retro_frame_task_.Cancel(); | |
355 | |
356 // Discard expired BeginRetroFrames | |
357 // Today, we should always end up with at most one un-expired BeginRetroFrame | |
358 // because deadlines will not be greater than the next frame time. We don't | |
359 // DCHECK though because some systems don't always have monotonic timestamps. | |
360 // TODO(brianderson): In the future, long deadlines could result in us not | |
361 // draining the queue if we don't catch up. If we consistently can't catch | |
362 // up, our fallback should be to lower our frame rate. | |
363 base::TimeTicks now = Now(); | |
364 | |
365 while (!begin_retro_frame_args_.empty()) { | |
366 const BeginFrameArgs& args = begin_retro_frame_args_.front(); | |
367 base::TimeTicks expiration_time = args.deadline; | |
368 if (now <= expiration_time) | |
369 break; | |
370 TRACE_EVENT_INSTANT2( | |
371 "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD, | |
372 "expiration_time - now", (expiration_time - now).InMillisecondsF(), | |
373 "BeginFrameArgs", begin_retro_frame_args_.front().AsValue()); | |
374 begin_retro_frame_args_.pop_front(); | |
375 if (begin_frame_source_) | |
376 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); | |
377 } | |
378 | |
379 if (begin_retro_frame_args_.empty()) { | |
380 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginRetroFrames all expired", | |
381 TRACE_EVENT_SCOPE_THREAD); | |
382 } else { | |
383 BeginFrameArgs front = begin_retro_frame_args_.front(); | |
384 begin_retro_frame_args_.pop_front(); | |
385 BeginImplFrameWithDeadline(front); | |
386 } | |
387 } | |
388 | |
389 // There could be a race between the posted BeginRetroFrame and a new | |
390 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame | |
391 // will check if there is a pending BeginRetroFrame to ensure we handle | |
392 // BeginFrames in FIFO order. | |
393 void Scheduler::PostBeginRetroFrameIfNeeded() { | |
394 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | |
395 "Scheduler::PostBeginRetroFrameIfNeeded", "state", AsValue()); | |
396 if (!observing_begin_frame_source_) | |
397 return; | |
398 | |
399 if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled()) | |
400 return; | |
401 | |
402 // begin_retro_frame_args_ should always be empty for the | |
403 // synchronous compositor. | |
404 DCHECK(!settings_.using_synchronous_renderer_compositor); | |
405 | |
406 if (state_machine_.begin_impl_frame_state() != | |
407 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) | |
408 return; | |
409 | |
410 begin_retro_frame_task_.Reset(begin_retro_frame_closure_); | |
411 | |
412 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback()); | |
413 } | |
414 | |
415 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { | |
416 bool main_thread_is_in_high_latency_mode = | 360 bool main_thread_is_in_high_latency_mode = |
417 state_machine_.main_thread_missed_last_deadline(); | 361 state_machine_.main_thread_missed_last_deadline(); |
418 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 362 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
419 args.AsValue(), "main_thread_missed_last_deadline", | 363 adjusted_args.AsValue(), "main_thread_missed_last_deadline", |
420 main_thread_is_in_high_latency_mode); | 364 main_thread_is_in_high_latency_mode); |
421 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 365 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
422 "MainThreadLatency", main_thread_is_in_high_latency_mode); | 366 "MainThreadLatency", main_thread_is_in_high_latency_mode); |
423 | 367 |
424 BeginFrameArgs adjusted_args = args; | 368 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
369 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | |
370 | |
425 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); | 371 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); |
426 adjusted_args.deadline -= kDeadlineFudgeFactor; | 372 adjusted_args.deadline -= kDeadlineFudgeFactor; |
427 | 373 |
428 base::TimeDelta bmf_start_to_activate = | 374 base::TimeDelta bmf_start_to_activate = |
429 compositor_timing_history_ | 375 compositor_timing_history_ |
430 ->BeginMainFrameStartToCommitDurationEstimate() + | 376 ->BeginMainFrameStartToCommitDurationEstimate() + |
431 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + | 377 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + |
432 compositor_timing_history_->ActivateDurationEstimate(); | 378 compositor_timing_history_->ActivateDurationEstimate(); |
433 | 379 |
434 base::TimeDelta bmf_to_activate_estimate_critical = | 380 base::TimeDelta bmf_to_activate_estimate_critical = |
435 bmf_start_to_activate + | 381 bmf_start_to_activate + |
436 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); | 382 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); |
437 | 383 |
438 state_machine_.SetCriticalBeginMainFrameToActivateIsFast( | 384 state_machine_.SetCriticalBeginMainFrameToActivateIsFast( |
439 bmf_to_activate_estimate_critical < args.interval); | 385 bmf_to_activate_estimate_critical < adjusted_args.interval); |
440 | 386 |
441 // Update the BeginMainFrame args now that we know whether the main | 387 // Update the BeginMainFrame args now that we know whether the main |
442 // thread will be on the critical path or not. | 388 // thread will be on the critical path or not. |
443 begin_main_frame_args_ = adjusted_args; | 389 begin_main_frame_args_ = adjusted_args; |
444 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); | 390 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); |
445 | 391 |
446 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical; | 392 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical; |
447 if (!begin_main_frame_args_.on_critical_path) { | 393 if (!begin_main_frame_args_.on_critical_path) { |
448 bmf_to_activate_estimate = | 394 bmf_to_activate_estimate = |
449 bmf_start_to_activate + | 395 bmf_start_to_activate + |
450 compositor_timing_history_ | 396 compositor_timing_history_ |
451 ->BeginMainFrameQueueDurationNotCriticalEstimate(); | 397 ->BeginMainFrameQueueDurationNotCriticalEstimate(); |
452 } | 398 } |
453 | 399 |
454 bool can_activate_before_deadline = | 400 bool can_activate_before_deadline = |
455 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args, | 401 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args, |
456 bmf_to_activate_estimate); | 402 bmf_to_activate_estimate); |
457 | 403 |
458 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { | 404 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { |
459 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", | 405 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", |
460 TRACE_EVENT_SCOPE_THREAD); | 406 TRACE_EVENT_SCOPE_THREAD); |
461 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 407 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
462 } else if (ShouldRecoverImplLatency(adjusted_args, | 408 } else if (ShouldRecoverImplLatency(adjusted_args, |
463 can_activate_before_deadline)) { | 409 can_activate_before_deadline)) { |
464 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", | 410 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", |
465 TRACE_EVENT_SCOPE_THREAD); | 411 TRACE_EVENT_SCOPE_THREAD); |
466 if (begin_frame_source_) | 412 if (begin_frame_source_) |
467 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); | 413 begin_frame_source_->DidFinishFrame(this, 0); |
468 return; | 414 return; |
469 } | 415 } |
470 | 416 |
471 BeginImplFrame(adjusted_args); | 417 BeginImplFrame(adjusted_args); |
472 } | 418 } |
473 | 419 |
474 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { | 420 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { |
475 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", | 421 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", |
476 args.AsValue()); | 422 args.AsValue()); |
477 | 423 |
478 // The main thread currently can't commit before we draw with the | 424 // The main thread currently can't commit before we draw with the |
479 // synchronous compositor, so never consider the BeginMainFrame fast. | 425 // synchronous compositor, so never consider the BeginMainFrame fast. |
480 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); | 426 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); |
481 begin_main_frame_args_ = args; | 427 begin_main_frame_args_ = args; |
482 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); | 428 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); |
483 | 429 |
484 BeginImplFrame(args); | 430 BeginImplFrame(args); |
485 compositor_timing_history_->WillFinishImplFrame( | 431 compositor_timing_history_->WillFinishImplFrame( |
486 state_machine_.needs_redraw()); | 432 state_machine_.needs_redraw()); |
487 FinishImplFrame(); | 433 FinishImplFrame(); |
488 } | 434 } |
489 | 435 |
490 void Scheduler::FinishImplFrame() { | 436 void Scheduler::FinishImplFrame() { |
491 state_machine_.OnBeginImplFrameIdle(); | 437 state_machine_.OnBeginImplFrameIdle(); |
492 ProcessScheduledActions(); | 438 ProcessScheduledActions(); |
493 | 439 |
494 client_->DidFinishImplFrame(); | 440 client_->DidFinishImplFrame(); |
495 if (begin_frame_source_) | 441 if (begin_frame_source_) |
496 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); | 442 begin_frame_source_->DidFinishFrame(this, 0); |
497 begin_impl_frame_tracker_.Finish(); | 443 begin_impl_frame_tracker_.Finish(); |
498 } | 444 } |
499 | 445 |
500 // BeginImplFrame starts a compositor frame that will wait up until a deadline | 446 // BeginImplFrame starts a compositor frame that will wait up until a deadline |
501 // for a BeginMainFrame+activation to complete before it times out and draws | 447 // for a BeginMainFrame+activation to complete before it times out and draws |
502 // any asynchronous animation and scroll/pinch updates. | 448 // any asynchronous animation and scroll/pinch updates. |
503 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 449 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
504 DCHECK_EQ(state_machine_.begin_impl_frame_state(), | 450 DCHECK_EQ(state_machine_.begin_impl_frame_state(), |
505 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 451 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
506 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 452 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
715 state_machine_.AsValueInto(state.get()); | 661 state_machine_.AsValueInto(state.get()); |
716 state->EndDictionary(); | 662 state->EndDictionary(); |
717 | 663 |
718 state->BeginDictionary("scheduler_state"); | 664 state->BeginDictionary("scheduler_state"); |
719 state->SetBoolean("throttle_frame_production_", | 665 state->SetBoolean("throttle_frame_production_", |
720 settings_.throttle_frame_production); | 666 settings_.throttle_frame_production); |
721 state->SetDouble("estimated_parent_draw_time_ms", | 667 state->SetDouble("estimated_parent_draw_time_ms", |
722 estimated_parent_draw_time_.InMillisecondsF()); | 668 estimated_parent_draw_time_.InMillisecondsF()); |
723 state->SetBoolean("observing_begin_frame_source", | 669 state->SetBoolean("observing_begin_frame_source", |
724 observing_begin_frame_source_); | 670 observing_begin_frame_source_); |
725 state->SetInteger("begin_retro_frame_args", | |
726 static_cast<int>(begin_retro_frame_args_.size())); | |
727 state->SetBoolean("begin_retro_frame_task", | |
728 !begin_retro_frame_task_.IsCancelled()); | |
729 state->SetBoolean("begin_impl_frame_deadline_task", | 671 state->SetBoolean("begin_impl_frame_deadline_task", |
730 !begin_impl_frame_deadline_task_.IsCancelled()); | 672 !begin_impl_frame_deadline_task_.IsCancelled()); |
673 state->SetBoolean("missed_begin_frame_task", | |
674 !missed_begin_frame_task_.IsCancelled()); | |
731 state->SetString("inside_action", | 675 state->SetString("inside_action", |
732 SchedulerStateMachine::ActionToString(inside_action_)); | 676 SchedulerStateMachine::ActionToString(inside_action_)); |
733 | 677 |
734 state->BeginDictionary("begin_impl_frame_args"); | 678 state->BeginDictionary("begin_impl_frame_args"); |
735 begin_impl_frame_tracker_.AsValueInto(now, state.get()); | 679 begin_impl_frame_tracker_.AsValueInto(now, state.get()); |
736 state->EndDictionary(); | 680 state->EndDictionary(); |
737 | 681 |
738 state->SetString("begin_impl_frame_deadline_mode_", | 682 state->SetString("begin_impl_frame_deadline_mode_", |
739 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( | 683 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( |
740 begin_impl_frame_deadline_mode_)); | 684 begin_impl_frame_deadline_mode_)); |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
818 } | 762 } |
819 | 763 |
820 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 764 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
821 return (state_machine_.begin_main_frame_state() == | 765 return (state_machine_.begin_main_frame_state() == |
822 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || | 766 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || |
823 state_machine_.begin_main_frame_state() == | 767 state_machine_.begin_main_frame_state() == |
824 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); | 768 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); |
825 } | 769 } |
826 | 770 |
827 } // namespace cc | 771 } // namespace cc |
OLD | NEW |