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

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

Issue 267783004: Refactoring the way begin frame sources inside scheduler work. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Major rewrite based on Brian's comments. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/scheduler/scheduler.h" 5 #include "cc/scheduler/scheduler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include "base/auto_reset.h" 8 #include "base/auto_reset.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/debug/trace_event_argument.h" 10 #include "base/debug/trace_event_argument.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/single_thread_task_runner.h" 12 #include "base/single_thread_task_runner.h"
13 #include "cc/debug/devtools_instrumentation.h" 13 #include "cc/debug/devtools_instrumentation.h"
14 #include "cc/debug/traced_value.h" 14 #include "cc/debug/traced_value.h"
15 #include "cc/scheduler/delay_based_time_source.h" 15 #include "cc/scheduler/delay_based_time_source.h"
16 #include "ui/gfx/frame_time.h" 16 #include "ui/gfx/frame_time.h"
17 17
18 namespace cc { 18 namespace cc {
19 19
20 Scheduler::SyntheticBeginFrameSource::SyntheticBeginFrameSource(
21 Scheduler* scheduler,
22 scoped_refptr<DelayBasedTimeSource> time_source)
23 : scheduler_(scheduler), time_source_(time_source) {
24 time_source_->SetClient(this);
25 }
26
27 Scheduler::SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {
28 }
29
30 void Scheduler::SyntheticBeginFrameSource::CommitVSyncParameters(
31 base::TimeTicks timebase,
32 base::TimeDelta interval) {
33 time_source_->SetTimebaseAndInterval(timebase, interval);
34 }
35
36 void Scheduler::SyntheticBeginFrameSource::SetNeedsBeginFrame(
37 bool needs_begin_frame,
38 std::deque<BeginFrameArgs>* begin_retro_frame_args) {
39 DCHECK(begin_retro_frame_args);
40 base::TimeTicks missed_tick_time =
41 time_source_->SetActive(needs_begin_frame);
42 if (!missed_tick_time.is_null()) {
43 begin_retro_frame_args->push_back(
44 CreateSyntheticBeginFrameArgs(missed_tick_time));
45 }
46 }
47
48 bool Scheduler::SyntheticBeginFrameSource::IsActive() const {
49 return time_source_->Active();
50 }
51
52 void Scheduler::SyntheticBeginFrameSource::OnTimerTick() {
53 BeginFrameArgs begin_frame_args(
54 CreateSyntheticBeginFrameArgs(time_source_->LastTickTime()));
55 scheduler_->BeginFrame(begin_frame_args);
56 }
57
58 void Scheduler::SyntheticBeginFrameSource::AsValueInto(
59 base::debug::TracedValue* state) const {
60 time_source_->AsValueInto(state);
61 }
62
63 BeginFrameArgs
64 Scheduler::SyntheticBeginFrameSource::CreateSyntheticBeginFrameArgs(
65 base::TimeTicks frame_time) {
66 base::TimeTicks deadline = time_source_->NextTickTime();
67 return BeginFrameArgs::Create(
68 frame_time, deadline, scheduler_->VSyncInterval());
69 }
70
71 Scheduler::Scheduler( 20 Scheduler::Scheduler(
72 SchedulerClient* client, 21 SchedulerClient* client,
73 const SchedulerSettings& scheduler_settings, 22 const SchedulerSettings& scheduler_settings,
74 int layer_tree_host_id, 23 int layer_tree_host_id,
75 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) 24 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
76 : settings_(scheduler_settings), 25 : settings_(scheduler_settings),
77 client_(client), 26 client_(client),
78 layer_tree_host_id_(layer_tree_host_id), 27 layer_tree_host_id_(layer_tree_host_id),
79 task_runner_(task_runner), 28 task_runner_(task_runner),
80 vsync_interval_(BeginFrameArgs::DefaultInterval()),
81 last_set_needs_begin_frame_(false),
82 begin_unthrottled_frame_posted_(false),
83 begin_retro_frame_posted_(false), 29 begin_retro_frame_posted_(false),
84 state_machine_(scheduler_settings), 30 state_machine_(scheduler_settings),
85 inside_process_scheduled_actions_(false), 31 inside_process_scheduled_actions_(false),
86 inside_action_(SchedulerStateMachine::ACTION_NONE), 32 inside_action_(SchedulerStateMachine::ACTION_NONE),
87 weak_factory_(this) { 33 weak_factory_(this) {
88 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 34 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
89 "Scheduler::Scheduler", 35 "Scheduler::Scheduler",
90 "settings", 36 "settings",
91 settings_.AsValue()); 37 settings_.AsValue());
92 DCHECK(client_); 38 DCHECK(client_);
93 DCHECK(!state_machine_.BeginFrameNeeded()); 39 DCHECK(!state_machine_.BeginFrameNeeded());
94 if (settings_.main_frame_before_activation_enabled) { 40 if (settings_.main_frame_before_activation_enabled) {
95 DCHECK(settings_.main_frame_before_draw_enabled); 41 DCHECK(settings_.main_frame_before_draw_enabled);
96 } 42 }
97 43
98 begin_retro_frame_closure_ = 44 begin_retro_frame_closure_ =
99 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); 45 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
100 begin_unthrottled_frame_closure_ =
101 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr());
102 begin_impl_frame_deadline_closure_ = base::Bind( 46 begin_impl_frame_deadline_closure_ = base::Bind(
103 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 47 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
104 poll_for_draw_triggers_closure_ = base::Bind( 48 poll_for_draw_triggers_closure_ = base::Bind(
105 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); 49 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
106 advance_commit_state_closure_ = base::Bind( 50 advance_commit_state_closure_ = base::Bind(
107 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 51 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
108 52
109 if (!settings_.begin_frame_scheduling_enabled) { 53 frame_source_ = BeginFrameSourceMultiplexer::Create();
110 SetupSyntheticBeginFrames(); 54 frame_source_->AddObserver(this);
55
56 // Background ticking frame source
57 SetUpBackgroundFrameSource();
58 frame_source_->AddSource(background_frame_source_store_.get());
59
60 // Primary frame source
61 SetUpPrimaryFrameSource();
62 frame_source_->AddSource(primary_frame_source_);
63 }
64
65 void Scheduler::SetUpBackgroundFrameSource() {
66 background_frame_source_store_ = SyntheticBeginFrameSource::Create(
67 task_runner_.get(), base::TimeDelta::FromSeconds(1));
68 }
69
70 void Scheduler::SetUpPrimaryFrameSource() {
71 if (!settings_.throttle_frame_production) {
72 TRACE_EVENT0("cc", "Scheduler::Scheduler() BackToBackBeginFrameSource");
73 primary_frame_source_store_ =
74 BackToBackBeginFrameSource::Create(task_runner_.get());
75 primary_frame_source_ = primary_frame_source_store_.get();
76 } else if (settings_.begin_frame_scheduling_enabled) {
77 TRACE_EVENT0("cc",
78 "Scheduler::Scheduler() SchedulerClient BeginFrameSource");
79 primary_frame_source_ = client_->GetBeginFrameSource();
80 } else {
81 TRACE_EVENT0("cc", "Scheduler::Scheduler() SyntheticBeginFrameSource");
82 scoped_ptr<SyntheticBeginFrameSource> synthetic_source =
83 SyntheticBeginFrameSource::Create(task_runner_.get(),
84 BeginFrameArgs::DefaultInterval());
85 vsync_observer_ = synthetic_source.get();
86 primary_frame_source_store_ = synthetic_source.Pass();
87 primary_frame_source_ = primary_frame_source_store_.get();
111 } 88 }
112 } 89 }
113 90
114 Scheduler::~Scheduler() { 91 Scheduler::~Scheduler() {
115 if (synthetic_begin_frame_source_) { 92 frame_source_->SetNeedsBeginFrames(false);
116 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
117 &begin_retro_frame_args_);
118 }
119 }
120
121 void Scheduler::SetupSyntheticBeginFrames() {
122 scoped_refptr<DelayBasedTimeSource> time_source;
123 if (gfx::FrameTime::TimestampsAreHighRes()) {
124 time_source = DelayBasedTimeSourceHighRes::Create(VSyncInterval(),
125 task_runner_.get());
126 } else {
127 time_source =
128 DelayBasedTimeSource::Create(VSyncInterval(), task_runner_.get());
129 }
130 DCHECK(!synthetic_begin_frame_source_);
131 synthetic_begin_frame_source_.reset(
132 new SyntheticBeginFrameSource(this, time_source));
133 } 93 }
134 94
135 base::TimeTicks Scheduler::Now() const { 95 base::TimeTicks Scheduler::Now() const {
136 return gfx::FrameTime::Now(); 96 return gfx::FrameTime::Now();
137 } 97 }
138 98
139 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, 99 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
140 base::TimeDelta interval) { 100 base::TimeDelta interval) {
141 // TODO(brianderson): We should not be receiving 0 intervals. 101 // TODO(brianderson): We should not be receiving 0 intervals.
142 if (interval == base::TimeDelta()) 102 if (interval == base::TimeDelta())
143 interval = BeginFrameArgs::DefaultInterval(); 103 interval = BeginFrameArgs::DefaultInterval();
144 vsync_interval_ = interval; 104
145 if (!settings_.begin_frame_scheduling_enabled) 105 if (vsync_observer_)
146 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); 106 vsync_observer_->OnUpdateVSyncParameters(timebase, interval);
brianderson 2014/09/13 01:38:13 How does this additional indirection help?
147 } 107 }
148 108
149 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { 109 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
150 DCHECK_GE(draw_time.ToInternalValue(), 0); 110 DCHECK_GE(draw_time.ToInternalValue(), 0);
151 estimated_parent_draw_time_ = draw_time; 111 estimated_parent_draw_time_ = draw_time;
152 } 112 }
153 113
154 void Scheduler::SetCanStart() { 114 void Scheduler::SetCanStart() {
155 state_machine_.SetCanStart(); 115 state_machine_.SetCanStart();
156 ProcessScheduledActions(); 116 ProcessScheduledActions();
157 } 117 }
158 118
159 void Scheduler::SetVisible(bool visible) { 119 void Scheduler::SetVisible(bool visible) {
160 state_machine_.SetVisible(visible); 120 state_machine_.SetVisible(visible);
121 if (visible) {
122 frame_source_->SetActiveSource(primary_frame_source_);
123 } else {
124 frame_source_->SetActiveSource(background_frame_source_store_.get());
125 }
161 ProcessScheduledActions(); 126 ProcessScheduledActions();
162 } 127 }
163 128
164 void Scheduler::SetCanDraw(bool can_draw) { 129 void Scheduler::SetCanDraw(bool can_draw) {
165 state_machine_.SetCanDraw(can_draw); 130 state_machine_.SetCanDraw(can_draw);
166 ProcessScheduledActions(); 131 ProcessScheduledActions();
167 } 132 }
168 133
169 void Scheduler::NotifyReadyToActivate() { 134 void Scheduler::NotifyReadyToActivate() {
170 state_machine_.NotifyReadyToActivate(); 135 state_machine_.NotifyReadyToActivate();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 ProcessScheduledActions(); 198 ProcessScheduledActions();
234 } 199 }
235 200
236 void Scheduler::DidManageTiles() { 201 void Scheduler::DidManageTiles() {
237 state_machine_.DidManageTiles(); 202 state_machine_.DidManageTiles();
238 } 203 }
239 204
240 void Scheduler::DidLoseOutputSurface() { 205 void Scheduler::DidLoseOutputSurface() {
241 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 206 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
242 state_machine_.DidLoseOutputSurface(); 207 state_machine_.DidLoseOutputSurface();
243 last_set_needs_begin_frame_ = false; 208 frame_source_->SetNeedsBeginFrames(false);
244 if (!settings_.begin_frame_scheduling_enabled) {
245 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
246 &begin_retro_frame_args_);
247 }
248 begin_retro_frame_args_.clear(); 209 begin_retro_frame_args_.clear();
249 ProcessScheduledActions(); 210 ProcessScheduledActions();
250 } 211 }
251 212
252 void Scheduler::DidCreateAndInitializeOutputSurface() { 213 void Scheduler::DidCreateAndInitializeOutputSurface() {
253 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 214 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
254 DCHECK(!last_set_needs_begin_frame_); 215 DCHECK(!frame_source_->NeedsBeginFrames());
255 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 216 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
256 state_machine_.DidCreateAndInitializeOutputSurface(); 217 state_machine_.DidCreateAndInitializeOutputSurface();
257 ProcessScheduledActions(); 218 ProcessScheduledActions();
258 } 219 }
259 220
260 void Scheduler::NotifyBeginMainFrameStarted() { 221 void Scheduler::NotifyBeginMainFrameStarted() {
261 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); 222 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted");
262 state_machine_.NotifyBeginMainFrameStarted(); 223 state_machine_.NotifyBeginMainFrameStarted();
263 } 224 }
264 225
265 base::TimeTicks Scheduler::AnticipatedDrawTime() const { 226 base::TimeTicks Scheduler::AnticipatedDrawTime() const {
266 if (!last_set_needs_begin_frame_ || 227 if (!frame_source_->NeedsBeginFrames() ||
267 begin_impl_frame_args_.interval <= base::TimeDelta()) 228 begin_impl_frame_args_.interval <= base::TimeDelta())
268 return base::TimeTicks(); 229 return base::TimeTicks();
269 230
270 base::TimeTicks now = Now(); 231 base::TimeTicks now = Now();
271 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time, 232 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
272 begin_impl_frame_args_.deadline); 233 begin_impl_frame_args_.deadline);
273 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval); 234 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
274 return timebase + (begin_impl_frame_args_.interval * intervals); 235 return timebase + (begin_impl_frame_args_.interval * intervals);
275 } 236 }
276 237
238 const BeginFrameArgs& Scheduler::LastBeginFrameArgs() const {
239 return last_begin_frame_args_;
240 }
241
277 base::TimeTicks Scheduler::LastBeginImplFrameTime() { 242 base::TimeTicks Scheduler::LastBeginImplFrameTime() {
278 return begin_impl_frame_args_.frame_time; 243 return begin_impl_frame_args_.frame_time;
279 } 244 }
280 245
281 void Scheduler::SetupNextBeginFrameIfNeeded() { 246 void Scheduler::SetupNextBeginFrameIfNeeded() {
282 if (!task_runner_.get()) 247 if (!task_runner_.get())
283 return; 248 return;
284 249
285 bool needs_begin_frame = state_machine_.BeginFrameNeeded(); 250 bool needs_begin_frame = state_machine_.BeginFrameNeeded();
286 251
287 if (settings_.throttle_frame_production) { 252 bool at_end_of_deadline =
288 SetupNextBeginFrameWhenVSyncThrottlingEnabled(needs_begin_frame); 253 (state_machine_.begin_impl_frame_state() ==
289 } else { 254 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) ||
290 SetupNextBeginFrameWhenVSyncThrottlingDisabled(needs_begin_frame); 255 (state_machine_.begin_impl_frame_state() ==
256 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
brianderson 2014/09/13 01:38:13 I remember intentionally not including the idle st
257
258 bool should_call_set_needs_begin_frame =
259 // Always request the BeginFrame immediately if it wasn't needed before.
260 needs_begin_frame ||
261 // Only stop requesting BeginFrames after a deadline.
262 (!needs_begin_frame && at_end_of_deadline);
263
264 if (should_call_set_needs_begin_frame) {
265 frame_source_->SetNeedsBeginFrames(needs_begin_frame);
291 } 266 }
267
268 // TODO(mithro): Use pending frames properly.
269 if (at_end_of_deadline)
270 frame_source_->FinishedFrame(0);
271
272 PostBeginRetroFrameIfNeeded();
292 SetupPollingMechanisms(needs_begin_frame); 273 SetupPollingMechanisms(needs_begin_frame);
293 } 274 }
294 275
295 // When we are throttling frame production, we request BeginFrames
296 // from the OutputSurface.
297 void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingEnabled(
298 bool needs_begin_frame) {
299 bool at_end_of_deadline =
300 state_machine_.begin_impl_frame_state() ==
301 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
302
303 bool should_call_set_needs_begin_frame =
304 // Always request the BeginFrame immediately if it wasn't needed before.
305 (needs_begin_frame && !last_set_needs_begin_frame_) ||
306 // Only stop requesting BeginFrames after a deadline.
307 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline);
308
309 if (should_call_set_needs_begin_frame) {
310 if (settings_.begin_frame_scheduling_enabled) {
311 client_->SetNeedsBeginFrame(needs_begin_frame);
312 } else {
313 synthetic_begin_frame_source_->SetNeedsBeginFrame(
314 needs_begin_frame, &begin_retro_frame_args_);
315 }
316 last_set_needs_begin_frame_ = needs_begin_frame;
317 }
318
319 PostBeginRetroFrameIfNeeded();
320 }
321
322 // When we aren't throttling frame production, we initiate a BeginFrame
323 // as soon as one is needed.
324 void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingDisabled(
325 bool needs_begin_frame) {
326 last_set_needs_begin_frame_ = needs_begin_frame;
327
328 if (!needs_begin_frame || begin_unthrottled_frame_posted_)
329 return;
330
331 if (state_machine_.begin_impl_frame_state() !=
332 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE &&
333 state_machine_.begin_impl_frame_state() !=
334 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
335 return;
336 }
337
338 begin_unthrottled_frame_posted_ = true;
339 task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_);
340 }
341
342 // BeginUnthrottledFrame is used when we aren't throttling frame production.
343 // This will usually be because VSync is disabled.
344 void Scheduler::BeginUnthrottledFrame() {
345 DCHECK(!settings_.throttle_frame_production);
346 DCHECK(begin_retro_frame_args_.empty());
347
348 base::TimeTicks now = Now();
349 base::TimeTicks deadline = now + vsync_interval_;
350
351 BeginFrameArgs begin_frame_args =
352 BeginFrameArgs::Create(now, deadline, vsync_interval_);
353 BeginImplFrame(begin_frame_args);
354
355 begin_unthrottled_frame_posted_ = false;
356 }
357
358 // We may need to poll when we can't rely on BeginFrame to advance certain 276 // We may need to poll when we can't rely on BeginFrame to advance certain
359 // state or to avoid deadlock. 277 // state or to avoid deadlock.
360 void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) { 278 void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) {
361 bool needs_advance_commit_state_timer = false; 279 bool needs_advance_commit_state_timer = false;
362 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but 280 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
363 // aren't expecting any more BeginFrames. This should only be needed by 281 // aren't expecting any more BeginFrames. This should only be needed by
364 // the synchronous compositor when BeginFrameNeeded is false. 282 // the synchronous compositor when BeginFrameNeeded is false.
365 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { 283 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
366 DCHECK(!state_machine_.SupportsProactiveBeginFrame()); 284 DCHECK(!state_machine_.SupportsProactiveBeginFrame());
367 DCHECK(!needs_begin_frame); 285 DCHECK(!needs_begin_frame);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 } 319 }
402 } else { 320 } else {
403 advance_commit_state_task_.Cancel(); 321 advance_commit_state_task_.Cancel();
404 } 322 }
405 } 323 }
406 324
407 // BeginFrame is the mechanism that tells us that now is a good time to start 325 // BeginFrame is the mechanism that tells us that now is a good time to start
408 // making a frame. Usually this means that user input for the frame is complete. 326 // making a frame. Usually this means that user input for the frame is complete.
409 // If the scheduler is busy, we queue the BeginFrame to be handled later as 327 // If the scheduler is busy, we queue the BeginFrame to be handled later as
410 // a BeginRetroFrame. 328 // a BeginRetroFrame.
411 void Scheduler::BeginFrame(const BeginFrameArgs& args) { 329 void Scheduler::OnBeginFrame(const BeginFrameArgs& args) {
412 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue()); 330 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue());
413 DCHECK(settings_.throttle_frame_production); 331 DCHECK(settings_.throttle_frame_production);
414 332
415 BeginFrameArgs adjusted_args(args); 333 BeginFrameArgs adjusted_args(args);
416 adjusted_args.deadline -= EstimatedParentDrawTime(); 334 adjusted_args.deadline -= EstimatedParentDrawTime();
417 335
418 bool should_defer_begin_frame; 336 bool should_defer_begin_frame;
419 if (settings_.using_synchronous_renderer_compositor) { 337 if (settings_.using_synchronous_renderer_compositor) {
420 should_defer_begin_frame = false; 338 should_defer_begin_frame = false;
421 } else { 339 } else {
422 should_defer_begin_frame = 340 should_defer_begin_frame =
423 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || 341 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
424 !last_set_needs_begin_frame_ || 342 !frame_source_->NeedsBeginFrames() ||
425 (state_machine_.begin_impl_frame_state() != 343 (state_machine_.begin_impl_frame_state() !=
426 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 344 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
427 } 345 }
428 346
429 if (should_defer_begin_frame) { 347 if (should_defer_begin_frame) {
430 begin_retro_frame_args_.push_back(adjusted_args); 348 begin_retro_frame_args_.push_back(adjusted_args);
431 TRACE_EVENT_INSTANT0( 349 TRACE_EVENT_INSTANT0(
432 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); 350 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
433 return; 351 return;
434 } 352 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 399
482 // There could be a race between the posted BeginRetroFrame and a new 400 // There could be a race between the posted BeginRetroFrame and a new
483 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame 401 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
484 // will check if there is a pending BeginRetroFrame to ensure we handle 402 // will check if there is a pending BeginRetroFrame to ensure we handle
485 // BeginFrames in FIFO order. 403 // BeginFrames in FIFO order.
486 void Scheduler::PostBeginRetroFrameIfNeeded() { 404 void Scheduler::PostBeginRetroFrameIfNeeded() {
487 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 405 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
488 "Scheduler::PostBeginRetroFrameIfNeeded", 406 "Scheduler::PostBeginRetroFrameIfNeeded",
489 "state", 407 "state",
490 AsValue()); 408 AsValue());
491 if (!last_set_needs_begin_frame_) 409 if (!frame_source_->NeedsBeginFrames())
492 return; 410 return;
493 411
494 if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_) 412 if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_)
495 return; 413 return;
496 414
497 // begin_retro_frame_args_ should always be empty for the 415 // begin_retro_frame_args_ should always be empty for the
498 // synchronous compositor. 416 // synchronous compositor.
499 DCHECK(!settings_.using_synchronous_renderer_compositor); 417 DCHECK(!settings_.using_synchronous_renderer_compositor);
500 418
501 if (state_machine_.begin_impl_frame_state() != 419 if (state_machine_.begin_impl_frame_state() !=
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 } 609 }
692 610
693 bool Scheduler::WillDrawIfNeeded() const { 611 bool Scheduler::WillDrawIfNeeded() const {
694 return !state_machine_.PendingDrawsShouldBeAborted(); 612 return !state_machine_.PendingDrawsShouldBeAborted();
695 } 613 }
696 614
697 scoped_refptr<base::debug::ConvertableToTraceFormat> Scheduler::AsValue() 615 scoped_refptr<base::debug::ConvertableToTraceFormat> Scheduler::AsValue()
698 const { 616 const {
699 scoped_refptr<base::debug::TracedValue> state = 617 scoped_refptr<base::debug::TracedValue> state =
700 new base::debug::TracedValue(); 618 new base::debug::TracedValue();
619 AsValueInto(state.get());
620 return state;
621 }
622
623 void Scheduler::AsValueInto(base::debug::TracedValue* state) const {
701 state->BeginDictionary("state_machine"); 624 state->BeginDictionary("state_machine");
702 state_machine_.AsValueInto(state.get()); 625 state_machine_.AsValueInto(state);
703 state->EndDictionary(); 626 state->EndDictionary();
704 if (synthetic_begin_frame_source_) { 627 state->BeginDictionary("frame_source_");
705 state->BeginDictionary("synthetic_begin_frame_source_"); 628 frame_source_->AsValueInto(state);
706 synthetic_begin_frame_source_->AsValueInto(state.get()); 629 state->EndDictionary();
707 state->EndDictionary();
708 }
709 630
710 state->BeginDictionary("scheduler_state"); 631 state->BeginDictionary("scheduler_state");
711 state->SetDouble("time_until_anticipated_draw_time_ms", 632 state->SetDouble("time_until_anticipated_draw_time_ms",
712 (AnticipatedDrawTime() - Now()).InMillisecondsF()); 633 (AnticipatedDrawTime() - Now()).InMillisecondsF());
713 state->SetDouble("vsync_interval_ms", vsync_interval_.InMillisecondsF());
714 state->SetDouble("estimated_parent_draw_time_ms", 634 state->SetDouble("estimated_parent_draw_time_ms",
715 estimated_parent_draw_time_.InMillisecondsF()); 635 estimated_parent_draw_time_.InMillisecondsF());
716 state->SetBoolean("last_set_needs_begin_frame_", last_set_needs_begin_frame_); 636 state->SetBoolean("last_set_needs_begin_frame_",
717 state->SetBoolean("begin_unthrottled_frame_posted_", 637 frame_source_->NeedsBeginFrames());
718 begin_unthrottled_frame_posted_);
719 state->SetBoolean("begin_retro_frame_posted_", begin_retro_frame_posted_); 638 state->SetBoolean("begin_retro_frame_posted_", begin_retro_frame_posted_);
720 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); 639 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size());
721 state->SetBoolean("begin_impl_frame_deadline_task_", 640 state->SetBoolean("begin_impl_frame_deadline_task_",
722 !begin_impl_frame_deadline_task_.IsCancelled()); 641 !begin_impl_frame_deadline_task_.IsCancelled());
723 state->SetBoolean("poll_for_draw_triggers_task_", 642 state->SetBoolean("poll_for_draw_triggers_task_",
724 !poll_for_draw_triggers_task_.IsCancelled()); 643 !poll_for_draw_triggers_task_.IsCancelled());
725 state->SetBoolean("advance_commit_state_task_", 644 state->SetBoolean("advance_commit_state_task_",
726 !advance_commit_state_task_.IsCancelled()); 645 !advance_commit_state_task_.IsCancelled());
727 state->BeginDictionary("begin_impl_frame_args"); 646 state->BeginDictionary("begin_impl_frame_args");
728 begin_impl_frame_args_.AsValueInto(state.get()); 647 begin_impl_frame_args_.AsValueInto(state);
729 state->EndDictionary(); 648 state->EndDictionary();
730 649
731 state->EndDictionary(); 650 state->EndDictionary();
732 651
733 state->BeginDictionary("client_state"); 652 state->BeginDictionary("client_state");
734 state->SetDouble("draw_duration_estimate_ms", 653 state->SetDouble("draw_duration_estimate_ms",
735 client_->DrawDurationEstimate().InMillisecondsF()); 654 client_->DrawDurationEstimate().InMillisecondsF());
736 state->SetDouble( 655 state->SetDouble(
737 "begin_main_frame_to_commit_duration_estimate_ms", 656 "begin_main_frame_to_commit_duration_estimate_ms",
738 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); 657 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF());
739 state->SetDouble( 658 state->SetDouble(
740 "commit_to_activate_duration_estimate_ms", 659 "commit_to_activate_duration_estimate_ms",
741 client_->CommitToActivateDurationEstimate().InMillisecondsF()); 660 client_->CommitToActivateDurationEstimate().InMillisecondsF());
742 state->EndDictionary(); 661 state->EndDictionary();
743 return state;
744 } 662 }
745 663
746 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { 664 bool Scheduler::CanCommitAndActivateBeforeDeadline() const {
747 // Check if the main thread computation and commit can be finished before the 665 // Check if the main thread computation and commit can be finished before the
748 // impl thread's deadline. 666 // impl thread's deadline.
749 base::TimeTicks estimated_draw_time = 667 base::TimeTicks estimated_draw_time =
750 begin_impl_frame_args_.frame_time + 668 begin_impl_frame_args_.frame_time +
751 client_->BeginMainFrameToCommitDurationEstimate() + 669 client_->BeginMainFrameToCommitDurationEstimate() +
752 client_->CommitToActivateDurationEstimate(); 670 client_->CommitToActivateDurationEstimate();
753 671
754 TRACE_EVENT2( 672 TRACE_EVENT2(
755 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 673 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
756 "CanCommitAndActivateBeforeDeadline", 674 "CanCommitAndActivateBeforeDeadline",
757 "time_left_after_drawing_ms", 675 "time_left_after_drawing_ms",
758 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), 676 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(),
759 "state", 677 "state",
760 AsValue()); 678 AsValue());
761 679
762 return estimated_draw_time < begin_impl_frame_args_.deadline; 680 return estimated_draw_time < begin_impl_frame_args_.deadline;
763 } 681 }
764 682
765 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 683 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
766 return (state_machine_.commit_state() == 684 return (state_machine_.commit_state() ==
767 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 685 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
768 state_machine_.commit_state() == 686 state_machine_.commit_state() ==
769 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 687 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
770 } 688 }
771 689
772 } // namespace cc 690 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698