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

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

Issue 2386183003: Revert of cc: Remove frame queuing from the scheduler. (patchset #14 id:400001 of https://coderevie… (Closed)
Patch Set: fix revert 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE), 44 SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE),
45 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), 45 begin_impl_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE),
46 state_machine_(settings), 46 state_machine_(settings),
47 inside_process_scheduled_actions_(false), 47 inside_process_scheduled_actions_(false),
48 inside_action_(SchedulerStateMachine::ACTION_NONE), 48 inside_action_(SchedulerStateMachine::ACTION_NONE),
49 weak_factory_(this) { 49 weak_factory_(this) {
50 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue()); 50 TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue());
51 DCHECK(client_); 51 DCHECK(client_);
52 DCHECK(!state_machine_.BeginFrameNeeded()); 52 DCHECK(!state_machine_.BeginFrameNeeded());
53 53
54 begin_retro_frame_closure_ =
55 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
54 begin_impl_frame_deadline_closure_ = base::Bind( 56 begin_impl_frame_deadline_closure_ = base::Bind(
55 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 57 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
56 58
57 ProcessScheduledActions(); 59 ProcessScheduledActions();
58 } 60 }
59 61
60 Scheduler::~Scheduler() { 62 Scheduler::~Scheduler() {
61 SetBeginFrameSource(nullptr); 63 SetBeginFrameSource(nullptr);
62 } 64 }
63 65
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 compositor_timing_history_->WillPrepareTiles(); 174 compositor_timing_history_->WillPrepareTiles();
173 } 175 }
174 176
175 void Scheduler::DidPrepareTiles() { 177 void Scheduler::DidPrepareTiles() {
176 compositor_timing_history_->DidPrepareTiles(); 178 compositor_timing_history_->DidPrepareTiles();
177 state_machine_.DidPrepareTiles(); 179 state_machine_.DidPrepareTiles();
178 } 180 }
179 181
180 void Scheduler::DidLoseCompositorFrameSink() { 182 void Scheduler::DidLoseCompositorFrameSink() {
181 TRACE_EVENT0("cc", "Scheduler::DidLoseCompositorFrameSink"); 183 TRACE_EVENT0("cc", "Scheduler::DidLoseCompositorFrameSink");
184 begin_retro_frame_args_.clear();
185 begin_retro_frame_task_.Cancel();
182 state_machine_.DidLoseCompositorFrameSink(); 186 state_machine_.DidLoseCompositorFrameSink();
183 UpdateCompositorTimingHistoryRecordingEnabled(); 187 UpdateCompositorTimingHistoryRecordingEnabled();
184 ProcessScheduledActions(); 188 ProcessScheduledActions();
185 } 189 }
186 190
187 void Scheduler::DidCreateAndInitializeCompositorFrameSink() { 191 void Scheduler::DidCreateAndInitializeCompositorFrameSink() {
188 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeCompositorFrameSink"); 192 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeCompositorFrameSink");
189 DCHECK(!observing_begin_frame_source_); 193 DCHECK(!observing_begin_frame_source_);
190 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 194 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
191 state_machine_.DidCreateAndInitializeCompositorFrameSink(); 195 state_machine_.DidCreateAndInitializeCompositorFrameSink();
(...skipping 16 matching lines...) Expand all
208 void Scheduler::BeginImplFrameNotExpectedSoon() { 212 void Scheduler::BeginImplFrameNotExpectedSoon() {
209 compositor_timing_history_->BeginImplFrameNotExpectedSoon(); 213 compositor_timing_history_->BeginImplFrameNotExpectedSoon();
210 214
211 // Tying this to SendBeginMainFrameNotExpectedSoon will have some 215 // Tying this to SendBeginMainFrameNotExpectedSoon will have some
212 // false negatives, but we want to avoid running long idle tasks when 216 // false negatives, but we want to avoid running long idle tasks when
213 // we are actually active. 217 // we are actually active.
214 client_->SendBeginMainFrameNotExpectedSoon(); 218 client_->SendBeginMainFrameNotExpectedSoon();
215 } 219 }
216 220
217 void Scheduler::SetupNextBeginFrameIfNeeded() { 221 void Scheduler::SetupNextBeginFrameIfNeeded() {
218 if (state_machine_.begin_impl_frame_state() != 222 // Never call SetNeedsBeginFrames if the frame source already has the right
219 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { 223 // value.
220 return; 224 if (observing_begin_frame_source_ != state_machine_.BeginFrameNeeded()) {
225 if (state_machine_.BeginFrameNeeded()) {
226 // Call AddObserver as soon as possible.
227 observing_begin_frame_source_ = true;
228 if (begin_frame_source_)
229 begin_frame_source_->AddObserver(this);
230 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
231 true);
232 } else if (state_machine_.begin_impl_frame_state() ==
233 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) {
234 // Call RemoveObserver in between frames only.
235 observing_begin_frame_source_ = false;
236 if (begin_frame_source_)
237 begin_frame_source_->RemoveObserver(this);
238 BeginImplFrameNotExpectedSoon();
239 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
240 false);
241 }
221 } 242 }
222 243
223 bool needs_begin_frames = state_machine_.BeginFrameNeeded(); 244 PostBeginRetroFrameIfNeeded();
224 if (needs_begin_frames && !observing_begin_frame_source_) {
225 observing_begin_frame_source_ = true;
226 if (begin_frame_source_)
227 begin_frame_source_->AddObserver(this);
228 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, true);
229 } else if (!needs_begin_frames && observing_begin_frame_source_) {
230 observing_begin_frame_source_ = false;
231 if (begin_frame_source_)
232 begin_frame_source_->RemoveObserver(this);
233 missed_begin_frame_task_.Cancel();
234 BeginImplFrameNotExpectedSoon();
235 devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_,
236 false);
237 }
238 } 245 }
239 246
240 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { 247 void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) {
241 if (state_machine_.begin_frame_source_paused() == paused) 248 if (state_machine_.begin_frame_source_paused() == paused)
242 return; 249 return;
243 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused", 250 TRACE_EVENT_INSTANT1("cc", "Scheduler::SetBeginFrameSourcePaused",
244 TRACE_EVENT_SCOPE_THREAD, "paused", paused); 251 TRACE_EVENT_SCOPE_THREAD, "paused", paused);
245 state_machine_.SetBeginFrameSourcePaused(paused); 252 state_machine_.SetBeginFrameSourcePaused(paused);
246 ProcessScheduledActions(); 253 ProcessScheduledActions();
247 } 254 }
248 255
249 // BeginFrame is the mechanism that tells us that now is a good time to start 256 // BeginFrame is the mechanism that tells us that now is a good time to start
250 // making a frame. Usually this means that user input for the frame is complete. 257 // making a frame. Usually this means that user input for the frame is complete.
251 // If the scheduler is busy, we queue the BeginFrame to be handled later as 258 // If the scheduler is busy, we queue the BeginFrame to be handled later as
252 // a BeginRetroFrame. 259 // a BeginRetroFrame.
253 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { 260 bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
254 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); 261 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue());
255 262
256 if (!state_machine_.BeginFrameNeeded()) {
257 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped",
258 TRACE_EVENT_SCOPE_THREAD);
259 return false;
260 }
261
262 // Trace this begin frame time through the Chrome stack 263 // Trace this begin frame time through the Chrome stack
263 TRACE_EVENT_FLOW_BEGIN0( 264 TRACE_EVENT_FLOW_BEGIN0(
264 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", 265 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs",
265 args.frame_time.ToInternalValue()); 266 args.frame_time.ToInternalValue());
266 267
267 if (settings_.using_synchronous_renderer_compositor) { 268 if (settings_.using_synchronous_renderer_compositor) {
268 BeginImplFrameSynchronous(args); 269 BeginImplFrameSynchronous(args);
269 return true; 270 return true;
270 } 271 }
271 272
272 if (inside_process_scheduled_actions_) { 273 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has
273 // The BFS can send a missed begin frame inside AddObserver. We can't handle 274 // sent us the last BeginFrame we have missed. As we might not be able to
274 // a begin frame inside ProcessScheduledActions so post a task. 275 // actually make rendering for this call, handle it like a "retro frame".
275 DCHECK_EQ(args.type, BeginFrameArgs::MISSED); 276 // TODO(brainderson): Add a test for this functionality ASAP!
276 DCHECK(missed_begin_frame_task_.IsCancelled()); 277 if (args.type == BeginFrameArgs::MISSED) {
277 missed_begin_frame_task_.Reset(base::Bind( 278 begin_retro_frame_args_.push_back(args);
278 &Scheduler::BeginImplFrameWithDeadline, base::Unretained(this), args)); 279 PostBeginRetroFrameIfNeeded();
279 task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
280 return true; 280 return true;
281 } 281 }
282 282
283 BeginImplFrameWithDeadline(args); 283 bool should_defer_begin_frame =
284 !begin_retro_frame_args_.empty() ||
285 !begin_retro_frame_task_.IsCancelled() ||
286 !observing_begin_frame_source_ ||
287 (state_machine_.begin_impl_frame_state() !=
288 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
289
290 if (should_defer_begin_frame) {
291 begin_retro_frame_args_.push_back(args);
292 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrame deferred",
293 TRACE_EVENT_SCOPE_THREAD);
294 // Queuing the frame counts as "using it", so we need to return true.
295 } else {
296 BeginImplFrameWithDeadline(args);
297 }
284 return true; 298 return true;
285 } 299 }
286 300
287 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) { 301 void Scheduler::SetVideoNeedsBeginFrames(bool video_needs_begin_frames) {
288 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames); 302 state_machine_.SetVideoNeedsBeginFrames(video_needs_begin_frames);
289 ProcessScheduledActions(); 303 ProcessScheduledActions();
290 } 304 }
291 305
292 void Scheduler::OnDrawForCompositorFrameSink(bool resourceless_software_draw) { 306 void Scheduler::OnDrawForCompositorFrameSink(bool resourceless_software_draw) {
293 DCHECK(settings_.using_synchronous_renderer_compositor); 307 DCHECK(settings_.using_synchronous_renderer_compositor);
294 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 308 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
295 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 309 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
296 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 310 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
297 311
298 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw); 312 state_machine_.SetResourcelessSoftwareDraw(resourceless_software_draw);
299 state_machine_.OnBeginImplFrameDeadline(); 313 state_machine_.OnBeginImplFrameDeadline();
300 ProcessScheduledActions(); 314 ProcessScheduledActions();
301 315
302 state_machine_.OnBeginImplFrameIdle(); 316 state_machine_.OnBeginImplFrameIdle();
303 ProcessScheduledActions(); 317 ProcessScheduledActions();
304 state_machine_.SetResourcelessSoftwareDraw(false); 318 state_machine_.SetResourcelessSoftwareDraw(false);
305 } 319 }
306 320
307 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { 321 // BeginRetroFrame is called for BeginFrames that we've deferred because
308 // The storage for |args| is owned by the missed begin frame task. Therefore 322 // the scheduler was in the middle of processing a previous BeginFrame.
309 // save |args| before cancelling the task either here or in the deadline. 323 void Scheduler::BeginRetroFrame() {
310 BeginFrameArgs adjusted_args = args; 324 TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame");
311 // Cancel the missed begin frame task in case the BFS sends a begin frame 325 DCHECK(!settings_.using_synchronous_renderer_compositor);
312 // before the missed frame task runs. 326 DCHECK(!begin_retro_frame_args_.empty());
313 missed_begin_frame_task_.Cancel(); 327 DCHECK(!begin_retro_frame_task_.IsCancelled());
314
315 // Discard missed begin frames if they are too late.
316 if (adjusted_args.type == BeginFrameArgs::MISSED &&
317 Now() > adjusted_args.deadline) {
318 begin_frame_source_->DidFinishFrame(this, 0);
319 return;
320 }
321
322 // Run the previous deadline if any.
323 if (state_machine_.begin_impl_frame_state() ==
324 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) {
325 OnBeginImplFrameDeadline();
326 // We may not need begin frames any longer.
327 if (!observing_begin_frame_source_) {
328 begin_frame_source_->DidFinishFrame(this, 0);
329 return;
330 }
331 }
332 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 328 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
333 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 329 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
334 330
331 begin_retro_frame_task_.Cancel();
332
333 // Discard expired BeginRetroFrames
334 // Today, we should always end up with at most one un-expired BeginRetroFrame
335 // because deadlines will not be greater than the next frame time. We don't
336 // DCHECK though because some systems don't always have monotonic timestamps.
337 // TODO(brianderson): In the future, long deadlines could result in us not
338 // draining the queue if we don't catch up. If we consistently can't catch
339 // up, our fallback should be to lower our frame rate.
340 base::TimeTicks now = Now();
341
342 while (!begin_retro_frame_args_.empty()) {
343 const BeginFrameArgs& args = begin_retro_frame_args_.front();
344 base::TimeTicks expiration_time = args.deadline;
345 if (now <= expiration_time)
346 break;
347 TRACE_EVENT_INSTANT2(
348 "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD,
349 "expiration_time - now", (expiration_time - now).InMillisecondsF(),
350 "BeginFrameArgs", begin_retro_frame_args_.front().AsValue());
351 begin_retro_frame_args_.pop_front();
352 if (begin_frame_source_)
353 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size());
354 }
355
356 if (begin_retro_frame_args_.empty()) {
357 TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginRetroFrames all expired",
358 TRACE_EVENT_SCOPE_THREAD);
359 } else {
360 BeginFrameArgs front = begin_retro_frame_args_.front();
361 begin_retro_frame_args_.pop_front();
362 BeginImplFrameWithDeadline(front);
363 }
364 }
365
366 // There could be a race between the posted BeginRetroFrame and a new
367 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
368 // will check if there is a pending BeginRetroFrame to ensure we handle
369 // BeginFrames in FIFO order.
370 void Scheduler::PostBeginRetroFrameIfNeeded() {
371 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
372 "Scheduler::PostBeginRetroFrameIfNeeded", "state", AsValue());
373 if (!observing_begin_frame_source_)
374 return;
375
376 if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled())
377 return;
378
379 // begin_retro_frame_args_ should always be empty for the
380 // synchronous compositor.
381 DCHECK(!settings_.using_synchronous_renderer_compositor);
382
383 if (state_machine_.begin_impl_frame_state() !=
384 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
385 return;
386
387 begin_retro_frame_task_.Reset(begin_retro_frame_closure_);
388
389 task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback());
390 }
391
392 void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) {
335 bool main_thread_is_in_high_latency_mode = 393 bool main_thread_is_in_high_latency_mode =
336 state_machine_.main_thread_missed_last_deadline(); 394 state_machine_.main_thread_missed_last_deadline();
337 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", 395 TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args",
338 adjusted_args.AsValue(), "main_thread_missed_last_deadline", 396 args.AsValue(), "main_thread_missed_last_deadline",
339 main_thread_is_in_high_latency_mode); 397 main_thread_is_in_high_latency_mode);
340 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 398 TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
341 "MainThreadLatency", main_thread_is_in_high_latency_mode); 399 "MainThreadLatency", main_thread_is_in_high_latency_mode);
342 400
343 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 401 BeginFrameArgs adjusted_args = args;
344 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
345
346 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); 402 adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate();
347 adjusted_args.deadline -= kDeadlineFudgeFactor; 403 adjusted_args.deadline -= kDeadlineFudgeFactor;
348 404
349 base::TimeDelta bmf_start_to_activate = 405 base::TimeDelta bmf_start_to_activate =
350 compositor_timing_history_ 406 compositor_timing_history_
351 ->BeginMainFrameStartToCommitDurationEstimate() + 407 ->BeginMainFrameStartToCommitDurationEstimate() +
352 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + 408 compositor_timing_history_->CommitToReadyToActivateDurationEstimate() +
353 compositor_timing_history_->ActivateDurationEstimate(); 409 compositor_timing_history_->ActivateDurationEstimate();
354 410
355 base::TimeDelta bmf_to_activate_estimate_critical = 411 base::TimeDelta bmf_to_activate_estimate_critical =
356 bmf_start_to_activate + 412 bmf_start_to_activate +
357 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); 413 compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate();
358 414
359 state_machine_.SetCriticalBeginMainFrameToActivateIsFast( 415 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(
360 bmf_to_activate_estimate_critical < adjusted_args.interval); 416 bmf_to_activate_estimate_critical < args.interval);
361 417
362 // Update the BeginMainFrame args now that we know whether the main 418 // Update the BeginMainFrame args now that we know whether the main
363 // thread will be on the critical path or not. 419 // thread will be on the critical path or not.
364 begin_main_frame_args_ = adjusted_args; 420 begin_main_frame_args_ = adjusted_args;
365 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); 421 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority();
366 422
367 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical; 423 base::TimeDelta bmf_to_activate_estimate = bmf_to_activate_estimate_critical;
368 if (!begin_main_frame_args_.on_critical_path) { 424 if (!begin_main_frame_args_.on_critical_path) {
369 bmf_to_activate_estimate = 425 bmf_to_activate_estimate =
370 bmf_start_to_activate + 426 bmf_start_to_activate +
371 compositor_timing_history_ 427 compositor_timing_history_
372 ->BeginMainFrameQueueDurationNotCriticalEstimate(); 428 ->BeginMainFrameQueueDurationNotCriticalEstimate();
373 } 429 }
374 430
375 bool can_activate_before_deadline = 431 bool can_activate_before_deadline =
376 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args, 432 CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args,
377 bmf_to_activate_estimate); 433 bmf_to_activate_estimate);
378 434
379 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { 435 if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) {
380 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", 436 TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency",
381 TRACE_EVENT_SCOPE_THREAD); 437 TRACE_EVENT_SCOPE_THREAD);
382 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 438 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
383 } else if (ShouldRecoverImplLatency(adjusted_args, 439 } else if (ShouldRecoverImplLatency(adjusted_args,
384 can_activate_before_deadline)) { 440 can_activate_before_deadline)) {
385 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", 441 TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency",
386 TRACE_EVENT_SCOPE_THREAD); 442 TRACE_EVENT_SCOPE_THREAD);
387 if (begin_frame_source_) 443 if (begin_frame_source_)
388 begin_frame_source_->DidFinishFrame(this, 0); 444 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size());
389 return; 445 return;
390 } 446 }
391 447
392 BeginImplFrame(adjusted_args); 448 BeginImplFrame(adjusted_args);
393 } 449 }
394 450
395 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) { 451 void Scheduler::BeginImplFrameSynchronous(const BeginFrameArgs& args) {
396 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args", 452 TRACE_EVENT1("cc,benchmark", "Scheduler::BeginImplFrame", "args",
397 args.AsValue()); 453 args.AsValue());
398 454
399 // The main thread currently can't commit before we draw with the 455 // The main thread currently can't commit before we draw with the
400 // synchronous compositor, so never consider the BeginMainFrame fast. 456 // synchronous compositor, so never consider the BeginMainFrame fast.
401 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false); 457 state_machine_.SetCriticalBeginMainFrameToActivateIsFast(false);
402 begin_main_frame_args_ = args; 458 begin_main_frame_args_ = args;
403 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority(); 459 begin_main_frame_args_.on_critical_path = !ImplLatencyTakesPriority();
404 460
405 BeginImplFrame(args); 461 BeginImplFrame(args);
406 compositor_timing_history_->WillFinishImplFrame( 462 compositor_timing_history_->WillFinishImplFrame(
407 state_machine_.needs_redraw()); 463 state_machine_.needs_redraw());
408 FinishImplFrame(); 464 FinishImplFrame();
409 } 465 }
410 466
411 void Scheduler::FinishImplFrame() { 467 void Scheduler::FinishImplFrame() {
412 state_machine_.OnBeginImplFrameIdle(); 468 state_machine_.OnBeginImplFrameIdle();
413 ProcessScheduledActions(); 469 ProcessScheduledActions();
414 470
415 client_->DidFinishImplFrame(); 471 client_->DidFinishImplFrame();
416 if (begin_frame_source_) 472 if (begin_frame_source_)
417 begin_frame_source_->DidFinishFrame(this, 0); 473 begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size());
418 begin_impl_frame_tracker_.Finish(); 474 begin_impl_frame_tracker_.Finish();
419 } 475 }
420 476
421 // BeginImplFrame starts a compositor frame that will wait up until a deadline 477 // BeginImplFrame starts a compositor frame that will wait up until a deadline
422 // for a BeginMainFrame+activation to complete before it times out and draws 478 // for a BeginMainFrame+activation to complete before it times out and draws
423 // any asynchronous animation and scroll/pinch updates. 479 // any asynchronous animation and scroll/pinch updates.
424 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 480 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
425 DCHECK_EQ(state_machine_.begin_impl_frame_state(), 481 DCHECK_EQ(state_machine_.begin_impl_frame_state(),
426 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 482 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
427 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 483 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 new base::trace_event::TracedValue()); 688 new base::trace_event::TracedValue());
633 base::TimeTicks now = Now(); 689 base::TimeTicks now = Now();
634 690
635 state->BeginDictionary("state_machine"); 691 state->BeginDictionary("state_machine");
636 state_machine_.AsValueInto(state.get()); 692 state_machine_.AsValueInto(state.get());
637 state->EndDictionary(); 693 state->EndDictionary();
638 694
639 state->BeginDictionary("scheduler_state"); 695 state->BeginDictionary("scheduler_state");
640 state->SetBoolean("observing_begin_frame_source", 696 state->SetBoolean("observing_begin_frame_source",
641 observing_begin_frame_source_); 697 observing_begin_frame_source_);
698 state->SetInteger("begin_retro_frame_args",
699 static_cast<int>(begin_retro_frame_args_.size()));
700 state->SetBoolean("begin_retro_frame_task",
701 !begin_retro_frame_task_.IsCancelled());
642 state->SetBoolean("begin_impl_frame_deadline_task", 702 state->SetBoolean("begin_impl_frame_deadline_task",
643 !begin_impl_frame_deadline_task_.IsCancelled()); 703 !begin_impl_frame_deadline_task_.IsCancelled());
644 state->SetBoolean("missed_begin_frame_task",
645 !missed_begin_frame_task_.IsCancelled());
646 state->SetString("inside_action", 704 state->SetString("inside_action",
647 SchedulerStateMachine::ActionToString(inside_action_)); 705 SchedulerStateMachine::ActionToString(inside_action_));
648 706
649 state->BeginDictionary("begin_impl_frame_args"); 707 state->BeginDictionary("begin_impl_frame_args");
650 begin_impl_frame_tracker_.AsValueInto(now, state.get()); 708 begin_impl_frame_tracker_.AsValueInto(now, state.get());
651 state->EndDictionary(); 709 state->EndDictionary();
652 710
653 state->SetString("begin_impl_frame_deadline_mode_", 711 state->SetString("begin_impl_frame_deadline_mode_",
654 SchedulerStateMachine::BeginImplFrameDeadlineModeToString( 712 SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
655 begin_impl_frame_deadline_mode_)); 713 begin_impl_frame_deadline_mode_));
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 } 798 }
741 799
742 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 800 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
743 return (state_machine_.begin_main_frame_state() == 801 return (state_machine_.begin_main_frame_state() ==
744 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT || 802 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT ||
745 state_machine_.begin_main_frame_state() == 803 state_machine_.begin_main_frame_state() ==
746 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED); 804 SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED);
747 } 805 }
748 806
749 } // namespace cc 807 } // 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