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

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: Rebasing onto master. Created 6 years, 6 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/logging.h" 10 #include "base/logging.h"
11 #include "base/single_thread_task_runner.h" 11 #include "base/single_thread_task_runner.h"
12 #include "cc/debug/devtools_instrumentation.h" 12 #include "cc/debug/devtools_instrumentation.h"
13 #include "cc/debug/traced_value.h" 13 #include "cc/debug/traced_value.h"
14 #include "cc/scheduler/delay_based_time_source.h" 14 #include "cc/scheduler/delay_based_time_source.h"
15 #include "cc/scheduler/frame_source.h"
15 #include "ui/gfx/frame_time.h" 16 #include "ui/gfx/frame_time.h"
16 17
17 namespace cc { 18 namespace cc {
18 19
19 Scheduler::SyntheticBeginFrameSource::SyntheticBeginFrameSource(
20 Scheduler* scheduler,
21 base::SingleThreadTaskRunner* task_runner)
22 : scheduler_(scheduler) {
23 if (gfx::FrameTime::TimestampsAreHighRes()) {
24 time_source_ = DelayBasedTimeSourceHighRes::Create(
25 scheduler_->VSyncInterval(), task_runner);
26 } else {
27 time_source_ = DelayBasedTimeSource::Create(scheduler_->VSyncInterval(),
28 task_runner);
29 }
30 time_source_->SetClient(this);
31 }
32
33 Scheduler::SyntheticBeginFrameSource::~SyntheticBeginFrameSource() {
34 }
35
36 void Scheduler::SyntheticBeginFrameSource::CommitVSyncParameters(
37 base::TimeTicks timebase,
38 base::TimeDelta interval) {
39 time_source_->SetTimebaseAndInterval(timebase, interval);
40 }
41
42 void Scheduler::SyntheticBeginFrameSource::SetNeedsBeginFrame(
43 bool needs_begin_frame,
44 std::deque<BeginFrameArgs>* begin_retro_frame_args) {
45 DCHECK(begin_retro_frame_args);
46 base::TimeTicks missed_tick_time =
47 time_source_->SetActive(needs_begin_frame);
48 if (!missed_tick_time.is_null()) {
49 begin_retro_frame_args->push_back(
50 CreateSyntheticBeginFrameArgs(missed_tick_time));
51 }
52 }
53
54 bool Scheduler::SyntheticBeginFrameSource::IsActive() const {
55 return time_source_->Active();
56 }
57
58 void Scheduler::SyntheticBeginFrameSource::OnTimerTick() {
59 BeginFrameArgs begin_frame_args(
60 CreateSyntheticBeginFrameArgs(time_source_->LastTickTime()));
61 scheduler_->BeginFrame(begin_frame_args);
62 }
63
64 scoped_ptr<base::Value> Scheduler::SyntheticBeginFrameSource::AsValue() const {
65 return time_source_->AsValue();
66 }
67
68 BeginFrameArgs
69 Scheduler::SyntheticBeginFrameSource::CreateSyntheticBeginFrameArgs(
70 base::TimeTicks frame_time) {
71 base::TimeTicks deadline =
72 time_source_->NextTickTime() - scheduler_->EstimatedParentDrawTime();
73 return BeginFrameArgs::Create(
74 frame_time, deadline, scheduler_->VSyncInterval());
75 }
76
77 Scheduler::Scheduler( 20 Scheduler::Scheduler(
78 SchedulerClient* client, 21 SchedulerClient* client,
79 const SchedulerSettings& scheduler_settings, 22 const SchedulerSettings& scheduler_settings,
80 int layer_tree_host_id, 23 int layer_tree_host_id,
24 BeginFrameSource* external_frame_source,
81 const scoped_refptr<base::SingleThreadTaskRunner>& impl_task_runner) 25 const scoped_refptr<base::SingleThreadTaskRunner>& impl_task_runner)
82 : settings_(scheduler_settings), 26 : settings_(scheduler_settings),
83 client_(client), 27 client_(client),
84 layer_tree_host_id_(layer_tree_host_id), 28 layer_tree_host_id_(layer_tree_host_id),
85 impl_task_runner_(impl_task_runner), 29 impl_task_runner_(impl_task_runner),
86 vsync_interval_(BeginFrameArgs::DefaultInterval()),
87 last_set_needs_begin_frame_(false),
88 begin_unthrottled_frame_posted_(false),
89 begin_retro_frame_posted_(false), 30 begin_retro_frame_posted_(false),
90 state_machine_(scheduler_settings), 31 state_machine_(scheduler_settings),
91 inside_process_scheduled_actions_(false), 32 inside_process_scheduled_actions_(false),
92 inside_action_(SchedulerStateMachine::ACTION_NONE), 33 inside_action_(SchedulerStateMachine::ACTION_NONE),
93 weak_factory_(this) { 34 weak_factory_(this) {
94 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 35 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
95 "Scheduler::Scheduler", 36 "Scheduler::Scheduler",
96 "settings", 37 "settings",
97 ToTrace(settings_)); 38 ToTrace(settings_));
98 DCHECK(client_); 39 DCHECK(client_);
99 DCHECK(!state_machine_.BeginFrameNeeded()); 40 DCHECK(!state_machine_.BeginFrameNeeded());
100 if (settings_.main_frame_before_activation_enabled) { 41 if (settings_.main_frame_before_activation_enabled) {
101 DCHECK(settings_.main_frame_before_draw_enabled); 42 DCHECK(settings_.main_frame_before_draw_enabled);
102 } 43 }
103 44
104 begin_retro_frame_closure_ = 45 begin_retro_frame_closure_ =
105 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); 46 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
106 begin_unthrottled_frame_closure_ =
107 base::Bind(&Scheduler::BeginUnthrottledFrame, weak_factory_.GetWeakPtr());
108 begin_impl_frame_deadline_closure_ = base::Bind( 47 begin_impl_frame_deadline_closure_ = base::Bind(
109 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 48 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
110 poll_for_draw_triggers_closure_ = base::Bind( 49 poll_for_draw_triggers_closure_ = base::Bind(
111 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); 50 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
112 advance_commit_state_closure_ = base::Bind( 51 advance_commit_state_closure_ = base::Bind(
113 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 52 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
114 53
115 if (!settings_.begin_frame_scheduling_enabled) { 54 scoped_ptr<BeginFrameSource> primary_frame_source;
simonhong 2014/06/12 13:47:39 foreground_frame_source?
116 SetupSyntheticBeginFrames(); 55
56 if (!settings_.throttle_frame_production) {
57 TRACE_EVENT0("cc", "Scheduler::Scheduler() BackToBackBeginFrameSource");
58 primary_frame_source = scoped_ptr<BeginFrameSource>(
59 new BackToBackBeginFrameSource(this, impl_task_runner_));
60 } else if (settings_.begin_frame_scheduling_enabled) {
61 TRACE_EVENT0("cc", "Scheduler::Scheduler() ProxyBeginFrameSource");
62 primary_frame_source = scoped_ptr<BeginFrameSource>(
63 new ProxyBeginFrameSource(this, external_frame_source));
64 } else {
65 TRACE_EVENT0("cc", "Scheduler::Scheduler() SyntheticBeginFrameSource");
66 primary_frame_source =
67 scoped_ptr<BeginFrameSource>(new SyntheticBeginFrameSource(
68 this, impl_task_runner_, BeginFrameArgs::DefaultInterval()));
117 } 69 }
70 scoped_ptr<BeginFrameSource> background_frame_source(
71 new SyntheticBeginFrameSource(
72 this, impl_task_runner_, base::TimeDelta::FromSeconds(1)));
73
74 frame_source_ = scoped_ptr<DualBeginFrameSource>(new DualBeginFrameSource(
75 this, primary_frame_source.Pass(), background_frame_source.Pass()));
118 } 76 }
119 77
120 Scheduler::~Scheduler() { 78 Scheduler::~Scheduler() {
121 if (synthetic_begin_frame_source_) { 79 frame_source_->SetGenerateFrames(false);
122 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
123 &begin_retro_frame_args_);
124 }
125 }
126
127 void Scheduler::SetupSyntheticBeginFrames() {
128 DCHECK(!synthetic_begin_frame_source_);
129 synthetic_begin_frame_source_.reset(
130 new SyntheticBeginFrameSource(this, impl_task_runner_.get()));
131 } 80 }
132 81
133 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, 82 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
134 base::TimeDelta interval) { 83 base::TimeDelta interval) {
135 // TODO(brianderson): We should not be receiving 0 intervals. 84 frame_source_->SetTimeBaseAndInterval(timebase, interval);
136 if (interval == base::TimeDelta())
137 interval = BeginFrameArgs::DefaultInterval();
138 vsync_interval_ = interval;
139 if (!settings_.begin_frame_scheduling_enabled)
140 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval);
141 } 85 }
142 86
143 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { 87 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
144 estimated_parent_draw_time_ = draw_time; 88 estimated_parent_draw_time_ = draw_time;
145 } 89 }
146 90
147 void Scheduler::SetCanStart() { 91 void Scheduler::SetCanStart() {
148 state_machine_.SetCanStart(); 92 state_machine_.SetCanStart();
149 ProcessScheduledActions(); 93 ProcessScheduledActions();
150 } 94 }
151 95
152 void Scheduler::SetVisible(bool visible) { 96 void Scheduler::SetVisible(bool visible) {
153 TRACE_EVENT1("cc", "Scheduler::SetVisible", "visible?", visible); 97 TRACE_EVENT1("cc", "Scheduler::SetVisible", "visible?", visible);
154 state_machine_.SetVisible(visible); 98 state_machine_.SetVisible(visible);
99 if (visible) {
100 frame_source_->SwitchSource(frame_source_->SourceForeground());
brianderson 2014/06/17 06:24:43 SwitchToForeground() and SwitchToBackground()?
101 } else {
102 frame_source_->SwitchSource(frame_source_->SourceBackground());
103 }
simonhong 2014/06/12 13:47:39 I think Scheduler should manage and switch fourgro
155 ProcessScheduledActions(); 104 ProcessScheduledActions();
156 } 105 }
157 106
158 void Scheduler::SetCanDraw(bool can_draw) { 107 void Scheduler::SetCanDraw(bool can_draw) {
159 state_machine_.SetCanDraw(can_draw); 108 state_machine_.SetCanDraw(can_draw);
160 ProcessScheduledActions(); 109 ProcessScheduledActions();
161 } 110 }
162 111
163 void Scheduler::NotifyReadyToActivate() { 112 void Scheduler::NotifyReadyToActivate() {
164 state_machine_.NotifyReadyToActivate(); 113 state_machine_.NotifyReadyToActivate();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 ProcessScheduledActions(); 176 ProcessScheduledActions();
228 } 177 }
229 178
230 void Scheduler::DidManageTiles() { 179 void Scheduler::DidManageTiles() {
231 state_machine_.DidManageTiles(); 180 state_machine_.DidManageTiles();
232 } 181 }
233 182
234 void Scheduler::DidLoseOutputSurface() { 183 void Scheduler::DidLoseOutputSurface() {
235 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 184 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
236 state_machine_.DidLoseOutputSurface(); 185 state_machine_.DidLoseOutputSurface();
237 last_set_needs_begin_frame_ = false; 186 frame_source_->SetGenerateFrames(false);
238 if (!settings_.begin_frame_scheduling_enabled) {
239 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
240 &begin_retro_frame_args_);
241 }
242 begin_retro_frame_args_.clear(); 187 begin_retro_frame_args_.clear();
243 ProcessScheduledActions(); 188 ProcessScheduledActions();
244 } 189 }
245 190
246 void Scheduler::DidCreateAndInitializeOutputSurface() { 191 void Scheduler::DidCreateAndInitializeOutputSurface() {
247 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 192 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
248 DCHECK(!last_set_needs_begin_frame_); 193 DCHECK(!frame_source_->IsGeneratingFrames());
249 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 194 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
250 state_machine_.DidCreateAndInitializeOutputSurface(); 195 state_machine_.DidCreateAndInitializeOutputSurface();
251 ProcessScheduledActions(); 196 ProcessScheduledActions();
252 } 197 }
253 198
254 void Scheduler::NotifyBeginMainFrameStarted() { 199 void Scheduler::NotifyBeginMainFrameStarted() {
255 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); 200 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted");
256 state_machine_.NotifyBeginMainFrameStarted(); 201 state_machine_.NotifyBeginMainFrameStarted();
257 } 202 }
258 203
259 base::TimeTicks Scheduler::AnticipatedDrawTime() const { 204 base::TimeTicks Scheduler::AnticipatedDrawTime() const {
260 if (!last_set_needs_begin_frame_ || 205 if (!frame_source_->IsGeneratingFrames() ||
261 begin_impl_frame_args_.interval <= base::TimeDelta()) 206 begin_impl_frame_args_.interval <= base::TimeDelta())
262 return base::TimeTicks(); 207 return base::TimeTicks();
263 208
264 base::TimeTicks now = gfx::FrameTime::Now(); 209 base::TimeTicks now = gfx::FrameTime::Now();
265 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time, 210 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
266 begin_impl_frame_args_.deadline); 211 begin_impl_frame_args_.deadline);
267 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval); 212 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
268 return timebase + (begin_impl_frame_args_.interval * intervals); 213 return timebase + (begin_impl_frame_args_.interval * intervals);
269 } 214 }
270 215
271 base::TimeTicks Scheduler::LastBeginImplFrameTime() { 216 base::TimeTicks Scheduler::LastBeginImplFrameTime() {
272 return begin_impl_frame_args_.frame_time; 217 return begin_impl_frame_args_.frame_time;
273 } 218 }
274 219
275 void Scheduler::SetupNextBeginFrameIfNeeded() { 220 void Scheduler::SetupNextBeginFrameIfNeeded() {
276 bool needs_begin_frame = state_machine_.BeginFrameNeeded(); 221 bool needs_begin_frame = state_machine_.BeginFrameNeeded();
277 222
278 if (settings_.throttle_frame_production) { 223 bool at_end_of_deadline =
279 SetupNextBeginFrameWhenVSyncThrottlingEnabled(needs_begin_frame); 224 (state_machine_.begin_impl_frame_state() ==
280 } else { 225 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) ||
281 SetupNextBeginFrameWhenVSyncThrottlingDisabled(needs_begin_frame); 226 (state_machine_.begin_impl_frame_state() ==
227 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
228
229 bool should_call_set_needs_begin_frame =
230 // Always request the BeginFrame immediately if it wasn't needed before.
231 needs_begin_frame ||
232 // Only stop requesting BeginFrames after a deadline.
233 (!needs_begin_frame && at_end_of_deadline);
234
235 if (should_call_set_needs_begin_frame) {
236 frame_source_->SetGenerateFrames(needs_begin_frame);
282 } 237 }
238
239 // TODO(mithro): Use pending frames properly.
240 if (at_end_of_deadline)
241 frame_source_->PendingFrames(0);
242
243 PostBeginRetroFrameIfNeeded();
283 SetupPollingMechanisms(needs_begin_frame); 244 SetupPollingMechanisms(needs_begin_frame);
284 } 245 }
285 246
286 // When we are throttling frame production, we request BeginFrames
287 // from the OutputSurface.
288 void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingEnabled(
289 bool needs_begin_frame) {
290 bool at_end_of_deadline =
291 state_machine_.begin_impl_frame_state() ==
292 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
293
294 bool should_call_set_needs_begin_frame =
295 // Always request the BeginFrame immediately if it wasn't needed before.
296 (needs_begin_frame && !last_set_needs_begin_frame_) ||
297 // Only stop requesting BeginFrames after a deadline.
298 (!needs_begin_frame && last_set_needs_begin_frame_ && at_end_of_deadline);
299
300 if (should_call_set_needs_begin_frame) {
301 if (settings_.begin_frame_scheduling_enabled) {
302 client_->SetNeedsBeginFrame(needs_begin_frame);
303 } else {
304 synthetic_begin_frame_source_->SetNeedsBeginFrame(
305 needs_begin_frame, &begin_retro_frame_args_);
306 }
307 last_set_needs_begin_frame_ = needs_begin_frame;
308 }
309
310 PostBeginRetroFrameIfNeeded();
311 }
312
313 // When we aren't throttling frame production, we initiate a BeginFrame
314 // as soon as one is needed.
315 void Scheduler::SetupNextBeginFrameWhenVSyncThrottlingDisabled(
316 bool needs_begin_frame) {
317 last_set_needs_begin_frame_ = needs_begin_frame;
318
319 if (!needs_begin_frame || begin_unthrottled_frame_posted_)
320 return;
321
322 if (state_machine_.begin_impl_frame_state() !=
323 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE &&
324 state_machine_.begin_impl_frame_state() !=
325 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) {
326 return;
327 }
328
329 begin_unthrottled_frame_posted_ = true;
330 impl_task_runner_->PostTask(FROM_HERE, begin_unthrottled_frame_closure_);
331 }
332
333 // BeginUnthrottledFrame is used when we aren't throttling frame production.
334 // This will usually be because VSync is disabled.
335 void Scheduler::BeginUnthrottledFrame() {
336 DCHECK(!settings_.throttle_frame_production);
337 DCHECK(begin_retro_frame_args_.empty());
338
339 base::TimeTicks now = gfx::FrameTime::Now();
340 base::TimeTicks deadline = now + vsync_interval_;
341
342 BeginFrameArgs begin_frame_args =
343 BeginFrameArgs::Create(now, deadline, vsync_interval_);
344 BeginImplFrame(begin_frame_args);
345
346 begin_unthrottled_frame_posted_ = false;
347 }
348
349 // We may need to poll when we can't rely on BeginFrame to advance certain 247 // We may need to poll when we can't rely on BeginFrame to advance certain
350 // state or to avoid deadlock. 248 // state or to avoid deadlock.
351 void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) { 249 void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) {
352 bool needs_advance_commit_state_timer = false; 250 bool needs_advance_commit_state_timer = false;
353 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but 251 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
354 // aren't expecting any more BeginFrames. This should only be needed by 252 // aren't expecting any more BeginFrames. This should only be needed by
355 // the synchronous compositor when BeginFrameNeeded is false. 253 // the synchronous compositor when BeginFrameNeeded is false.
356 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { 254 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
357 DCHECK(!state_machine_.SupportsProactiveBeginFrame()); 255 DCHECK(!state_machine_.SupportsProactiveBeginFrame());
358 DCHECK(!needs_begin_frame); 256 DCHECK(!needs_begin_frame);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
394 advance_commit_state_task_.Cancel(); 292 advance_commit_state_task_.Cancel();
395 } 293 }
396 } 294 }
397 295
398 // BeginFrame is the mechanism that tells us that now is a good time to start 296 // BeginFrame is the mechanism that tells us that now is a good time to start
399 // making a frame. Usually this means that user input for the frame is complete. 297 // making a frame. Usually this means that user input for the frame is complete.
400 // If the scheduler is busy, we queue the BeginFrame to be handled later as 298 // If the scheduler is busy, we queue the BeginFrame to be handled later as
401 // a BeginRetroFrame. 299 // a BeginRetroFrame.
402 void Scheduler::BeginFrame(const BeginFrameArgs& args) { 300 void Scheduler::BeginFrame(const BeginFrameArgs& args) {
403 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", ToTrace(args)); 301 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", ToTrace(args));
404 DCHECK(settings_.throttle_frame_production); 302
303 BeginFrameArgs adjusted_args(args);
304 adjusted_args.deadline -= EstimatedParentDrawTime();
405 305
406 bool should_defer_begin_frame; 306 bool should_defer_begin_frame;
407 if (settings_.using_synchronous_renderer_compositor) { 307 if (settings_.using_synchronous_renderer_compositor) {
408 should_defer_begin_frame = false; 308 should_defer_begin_frame = false;
409 } else { 309 } else {
410 should_defer_begin_frame = 310 should_defer_begin_frame =
411 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || 311 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
412 !last_set_needs_begin_frame_ || 312 !frame_source_->IsGeneratingFrames() ||
413 (state_machine_.begin_impl_frame_state() != 313 (state_machine_.begin_impl_frame_state() !=
414 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 314 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
415 } 315 }
416 316
417 if (should_defer_begin_frame) { 317 if (should_defer_begin_frame) {
418 begin_retro_frame_args_.push_back(args); 318 begin_retro_frame_args_.push_back(adjusted_args);
419 TRACE_EVENT_INSTANT0( 319 TRACE_EVENT_INSTANT1("cc",
420 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); 320 "Scheduler::BeginFrame deferred",
321 TRACE_EVENT_SCOPE_THREAD,
322 "args",
323 ToTrace(adjusted_args));
421 return; 324 return;
422 } 325 }
423 326
424 BeginImplFrame(args); 327 BeginImplFrame(adjusted_args);
425 } 328 }
426 329
427 // BeginRetroFrame is called for BeginFrames that we've deferred because 330 // BeginRetroFrame is called for BeginFrames that we've deferred because
428 // the scheduler was in the middle of processing a previous BeginFrame. 331 // the scheduler was in the middle of processing a previous BeginFrame.
429 void Scheduler::BeginRetroFrame() { 332 void Scheduler::BeginRetroFrame() {
430 TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame"); 333 TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame");
431 DCHECK(!settings_.using_synchronous_renderer_compositor); 334 DCHECK(!settings_.using_synchronous_renderer_compositor);
432 DCHECK(begin_retro_frame_posted_); 335 DCHECK(begin_retro_frame_posted_);
433 begin_retro_frame_posted_ = false; 336 begin_retro_frame_posted_ = false;
434 337
(...skipping 10 matching lines...) Expand all
445 // draining the queue if we don't catch up. If we consistently can't catch 348 // draining the queue if we don't catch up. If we consistently can't catch
446 // up, our fallback should be to lower our frame rate. 349 // up, our fallback should be to lower our frame rate.
447 base::TimeTicks now = gfx::FrameTime::Now(); 350 base::TimeTicks now = gfx::FrameTime::Now();
448 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate(); 351 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
449 while (!begin_retro_frame_args_.empty() && 352 while (!begin_retro_frame_args_.empty() &&
450 now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(), 353 now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(),
451 draw_duration_estimate)) { 354 draw_duration_estimate)) {
452 TRACE_EVENT1("cc", 355 TRACE_EVENT1("cc",
453 "Scheduler::BeginRetroFrame discarding", 356 "Scheduler::BeginRetroFrame discarding",
454 "frame_time", 357 "frame_time",
455 begin_retro_frame_args_.front().frame_time); 358 ToTrace(begin_retro_frame_args_.front()));
456 begin_retro_frame_args_.pop_front(); 359 begin_retro_frame_args_.pop_front();
457 } 360 }
458 361
459 if (begin_retro_frame_args_.empty()) { 362 if (begin_retro_frame_args_.empty()) {
460 DCHECK(settings_.throttle_frame_production);
brianderson 2014/06/17 06:24:43 Why is this DCHECK removed?
461 TRACE_EVENT_INSTANT0("cc", 363 TRACE_EVENT_INSTANT0("cc",
462 "Scheduler::BeginRetroFrames all expired", 364 "Scheduler::BeginRetroFrames all expired",
463 TRACE_EVENT_SCOPE_THREAD); 365 TRACE_EVENT_SCOPE_THREAD);
464 } else { 366 } else {
465 BeginImplFrame(begin_retro_frame_args_.front()); 367 BeginImplFrame(begin_retro_frame_args_.front());
466 begin_retro_frame_args_.pop_front(); 368 begin_retro_frame_args_.pop_front();
467 } 369 }
468 } 370 }
469 371
470 // There could be a race between the posted BeginRetroFrame and a new 372 // There could be a race between the posted BeginRetroFrame and a new
471 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame 373 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
472 // will check if there is a pending BeginRetroFrame to ensure we handle 374 // will check if there is a pending BeginRetroFrame to ensure we handle
473 // BeginFrames in FIFO order. 375 // BeginFrames in FIFO order.
474 void Scheduler::PostBeginRetroFrameIfNeeded() { 376 void Scheduler::PostBeginRetroFrameIfNeeded() {
475 if (!last_set_needs_begin_frame_) 377 if (!frame_source_->IsGeneratingFrames())
476 return; 378 return;
477 379
478 if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_) 380 if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_)
479 return; 381 return;
480 382
481 // begin_retro_frame_args_ should always be empty for the 383 // begin_retro_frame_args_ should always be empty for the
482 // synchronous compositor. 384 // synchronous compositor.
483 DCHECK(!settings_.using_synchronous_renderer_compositor); 385 DCHECK(!settings_.using_synchronous_renderer_compositor);
484 386
485 if (state_machine_.begin_impl_frame_state() != 387 if (state_machine_.begin_impl_frame_state() !=
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 } 576 }
675 } 577 }
676 578
677 bool Scheduler::WillDrawIfNeeded() const { 579 bool Scheduler::WillDrawIfNeeded() const {
678 return !state_machine_.PendingDrawsShouldBeAborted(); 580 return !state_machine_.PendingDrawsShouldBeAborted();
679 } 581 }
680 582
681 scoped_ptr<base::Value> Scheduler::AsValue() const { 583 scoped_ptr<base::Value> Scheduler::AsValue() const {
682 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); 584 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
683 state->Set("state_machine", state_machine_.AsValue().release()); 585 state->Set("state_machine", state_machine_.AsValue().release());
684 if (synthetic_begin_frame_source_) 586 state->Set("frame_source",
685 state->Set("synthetic_begin_frame_source_", 587 frame_source_->BeginFrameSourceAsValue().release());
brianderson 2014/06/17 06:24:43 BeginFrameSourceAsValue -> AsValue()?
686 synthetic_begin_frame_source_->AsValue().release());
687 588
688 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); 589 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue);
689 scheduler_state->SetDouble( 590 scheduler_state->SetDouble(
690 "time_until_anticipated_draw_time_ms", 591 "time_until_anticipated_draw_time_ms",
691 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); 592 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF());
692 scheduler_state->SetDouble("vsync_interval_ms",
693 vsync_interval_.InMillisecondsF());
694 scheduler_state->SetDouble("estimated_parent_draw_time_ms", 593 scheduler_state->SetDouble("estimated_parent_draw_time_ms",
695 estimated_parent_draw_time_.InMillisecondsF()); 594 estimated_parent_draw_time_.InMillisecondsF());
696 scheduler_state->SetBoolean("last_set_needs_begin_frame_", 595 scheduler_state->SetBoolean("last_set_needs_begin_frame_",
697 last_set_needs_begin_frame_); 596 frame_source_->IsGeneratingFrames());
698 scheduler_state->SetBoolean("begin_unthrottled_frame_posted_",
699 begin_unthrottled_frame_posted_);
700 scheduler_state->SetBoolean("begin_retro_frame_posted_", 597 scheduler_state->SetBoolean("begin_retro_frame_posted_",
701 begin_retro_frame_posted_); 598 begin_retro_frame_posted_);
702 scheduler_state->SetInteger("begin_retro_frame_args_", 599 scheduler_state->SetInteger("begin_retro_frame_args_",
703 begin_retro_frame_args_.size()); 600 begin_retro_frame_args_.size());
704 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", 601 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_",
705 !begin_impl_frame_deadline_task_.IsCancelled()); 602 !begin_impl_frame_deadline_task_.IsCancelled());
706 scheduler_state->SetBoolean("poll_for_draw_triggers_task_", 603 scheduler_state->SetBoolean("poll_for_draw_triggers_task_",
707 !poll_for_draw_triggers_task_.IsCancelled()); 604 !poll_for_draw_triggers_task_.IsCancelled());
708 scheduler_state->SetBoolean("advance_commit_state_task_", 605 scheduler_state->SetBoolean("advance_commit_state_task_",
709 !advance_commit_state_task_.IsCancelled()); 606 !advance_commit_state_task_.IsCancelled());
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 } 642 }
746 643
747 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 644 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
748 return (state_machine_.commit_state() == 645 return (state_machine_.commit_state() ==
749 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 646 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
750 state_machine_.commit_state() == 647 state_machine_.commit_state() ==
751 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 648 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
752 } 649 }
753 650
754 } // namespace cc 651 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698