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

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

Powered by Google App Engine
This is Rietveld 408576698