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

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: Trying an alternative to OnMissedBeginFrames method. Created 6 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 | 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( 20 BeginFrameSource* SchedulerFrameSourcesConstructor::ConstructPrimaryFrameSource(
21 Scheduler* scheduler, 21 Scheduler* scheduler) {
22 scoped_refptr<DelayBasedTimeSource> time_source) 22 if (!scheduler->settings_.throttle_frame_production) {
23 : scheduler_(scheduler), time_source_(time_source) { 23 TRACE_EVENT1("cc",
24 time_source_->SetClient(this); 24 "Scheduler::Scheduler()",
25 } 25 "PrimaryFrameSource",
26 "BackToBackBeginFrameSource");
27 DCHECK(!scheduler->primary_frame_source_internal_);
28 scheduler->primary_frame_source_internal_ =
29 BackToBackBeginFrameSource::Create(scheduler->task_runner_.get());
30 return scheduler->primary_frame_source_internal_.get();
31 } else if (scheduler->settings_.begin_frame_scheduling_enabled) {
32 TRACE_EVENT1("cc",
33 "Scheduler::Scheduler()",
34 "PrimaryFrameSource",
35 "SchedulerClient");
36 return scheduler->client_->ExternalBeginFrameSource();
37 } else {
38 TRACE_EVENT1("cc",
39 "Scheduler::Scheduler()",
40 "PrimaryFrameSource",
41 "SyntheticBeginFrameSource");
42 scoped_ptr<SyntheticBeginFrameSource> synthetic_source =
43 SyntheticBeginFrameSource::Create(scheduler->task_runner_.get(),
44 scheduler->Now(),
45 BeginFrameArgs::DefaultInterval());
26 46
27 Scheduler::SyntheticBeginFrameSource::~SyntheticBeginFrameSource() { 47 DCHECK(!scheduler->vsync_observer_);
28 } 48 scheduler->vsync_observer_ = synthetic_source.get();
29 49
30 void Scheduler::SyntheticBeginFrameSource::CommitVSyncParameters( 50 DCHECK(!scheduler->primary_frame_source_internal_);
31 base::TimeTicks timebase, 51 scheduler->primary_frame_source_internal_ = synthetic_source.Pass();
32 base::TimeDelta interval) { 52 return scheduler->primary_frame_source_internal_.get();
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 } 53 }
46 } 54 }
47 55
48 bool Scheduler::SyntheticBeginFrameSource::IsActive() const { 56 BeginFrameSource*
49 return time_source_->Active(); 57 SchedulerFrameSourcesConstructor::ConstructBackgroundFrameSource(
50 } 58 Scheduler* scheduler) {
51 59 TRACE_EVENT1("cc",
52 void Scheduler::SyntheticBeginFrameSource::OnTimerTick() { 60 "Scheduler::Scheduler()",
53 BeginFrameArgs begin_frame_args( 61 "BackgroundFrameSource",
54 CreateSyntheticBeginFrameArgs(time_source_->LastTickTime())); 62 "SyntheticBeginFrameSource");
55 scheduler_->BeginFrame(begin_frame_args); 63 DCHECK(!(scheduler->background_frame_source_internal_));
56 } 64 scheduler->background_frame_source_internal_ =
57 65 SyntheticBeginFrameSource::Create(scheduler->task_runner_.get(),
58 void Scheduler::SyntheticBeginFrameSource::AsValueInto( 66 scheduler->Now(),
59 base::debug::TracedValue* state) const { 67 base::TimeDelta::FromSeconds(1));
60 time_source_->AsValueInto(state); 68 return scheduler->background_frame_source_internal_.get();
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 } 69 }
70 70
71 Scheduler::Scheduler( 71 Scheduler::Scheduler(
72 SchedulerClient* client, 72 SchedulerClient* client,
73 const SchedulerSettings& scheduler_settings, 73 const SchedulerSettings& scheduler_settings,
74 int layer_tree_host_id, 74 int layer_tree_host_id,
75 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) 75 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
76 : settings_(scheduler_settings), 76 SchedulerFrameSourcesConstructor* frame_sources_constructor)
77 : frame_source_(),
78 primary_frame_source_(NULL),
79 background_frame_source_(NULL),
80 primary_frame_source_internal_(),
81 background_frame_source_internal_(),
82 vsync_observer_(NULL),
83 settings_(scheduler_settings),
77 client_(client), 84 client_(client),
78 layer_tree_host_id_(layer_tree_host_id), 85 layer_tree_host_id_(layer_tree_host_id),
79 task_runner_(task_runner), 86 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), 87 begin_retro_frame_posted_(false),
84 state_machine_(scheduler_settings), 88 state_machine_(scheduler_settings),
85 inside_process_scheduled_actions_(false), 89 inside_process_scheduled_actions_(false),
86 inside_action_(SchedulerStateMachine::ACTION_NONE), 90 inside_action_(SchedulerStateMachine::ACTION_NONE),
87 weak_factory_(this) { 91 weak_factory_(this) {
88 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 92 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
89 "Scheduler::Scheduler", 93 "Scheduler::Scheduler",
90 "settings", 94 "settings",
91 settings_.AsValue()); 95 settings_.AsValue());
92 DCHECK(client_); 96 DCHECK(client_);
93 DCHECK(!state_machine_.BeginFrameNeeded()); 97 DCHECK(!state_machine_.BeginFrameNeeded());
94 if (settings_.main_frame_before_activation_enabled) { 98 if (settings_.main_frame_before_activation_enabled) {
95 DCHECK(settings_.main_frame_before_draw_enabled); 99 DCHECK(settings_.main_frame_before_draw_enabled);
96 } 100 }
97 101
98 begin_retro_frame_closure_ = 102 begin_retro_frame_closure_ =
99 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); 103 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( 104 begin_impl_frame_deadline_closure_ = base::Bind(
103 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 105 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
104 poll_for_draw_triggers_closure_ = base::Bind( 106 poll_for_draw_triggers_closure_ = base::Bind(
105 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); 107 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
106 advance_commit_state_closure_ = base::Bind( 108 advance_commit_state_closure_ = base::Bind(
107 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 109 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
108 110
109 if (!settings_.begin_frame_scheduling_enabled) { 111 frame_source_ = BeginFrameSourceMultiplexer::Create();
110 SetupSyntheticBeginFrames(); 112 frame_source_->AddObserver(this);
111 } 113
114 // Primary frame source
115 primary_frame_source_ =
116 frame_sources_constructor->ConstructPrimaryFrameSource(this);
117 frame_source_->AddSource(primary_frame_source_);
118
119 // Background ticking frame source
120 background_frame_source_ =
121 frame_sources_constructor->ConstructBackgroundFrameSource(this);
122 frame_source_->AddSource(background_frame_source_);
112 } 123 }
113 124
114 Scheduler::~Scheduler() { 125 Scheduler::~Scheduler() {
115 if (synthetic_begin_frame_source_) {
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 } 126 }
134 127
135 base::TimeTicks Scheduler::Now() const { 128 base::TimeTicks Scheduler::Now() const {
136 return gfx::FrameTime::Now(); 129 base::TimeTicks now = gfx::FrameTime::Now();
130 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"),
131 "Scheduler::Now",
132 "now",
133 now);
134 return now;
137 } 135 }
138 136
139 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase, 137 void Scheduler::CommitVSyncParameters(base::TimeTicks timebase,
140 base::TimeDelta interval) { 138 base::TimeDelta interval) {
141 // TODO(brianderson): We should not be receiving 0 intervals. 139 // TODO(brianderson): We should not be receiving 0 intervals.
142 if (interval == base::TimeDelta()) 140 if (interval == base::TimeDelta())
143 interval = BeginFrameArgs::DefaultInterval(); 141 interval = BeginFrameArgs::DefaultInterval();
144 vsync_interval_ = interval; 142
145 if (!settings_.begin_frame_scheduling_enabled) 143 if (vsync_observer_)
146 synthetic_begin_frame_source_->CommitVSyncParameters(timebase, interval); 144 vsync_observer_->OnUpdateVSyncParameters(timebase, interval);
147 } 145 }
148 146
149 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) { 147 void Scheduler::SetEstimatedParentDrawTime(base::TimeDelta draw_time) {
150 DCHECK_GE(draw_time.ToInternalValue(), 0); 148 DCHECK_GE(draw_time.ToInternalValue(), 0);
151 estimated_parent_draw_time_ = draw_time; 149 estimated_parent_draw_time_ = draw_time;
152 } 150 }
153 151
154 void Scheduler::SetCanStart() { 152 void Scheduler::SetCanStart() {
155 state_machine_.SetCanStart(); 153 state_machine_.SetCanStart();
156 ProcessScheduledActions(); 154 ProcessScheduledActions();
157 } 155 }
158 156
159 void Scheduler::SetVisible(bool visible) { 157 void Scheduler::SetVisible(bool visible) {
160 state_machine_.SetVisible(visible); 158 state_machine_.SetVisible(visible);
159 if (visible) {
160 frame_source_->SetActiveSource(primary_frame_source_);
161 } else {
162 frame_source_->SetActiveSource(background_frame_source_);
163 }
161 ProcessScheduledActions(); 164 ProcessScheduledActions();
162 } 165 }
163 166
164 void Scheduler::SetCanDraw(bool can_draw) { 167 void Scheduler::SetCanDraw(bool can_draw) {
165 state_machine_.SetCanDraw(can_draw); 168 state_machine_.SetCanDraw(can_draw);
166 ProcessScheduledActions(); 169 ProcessScheduledActions();
167 } 170 }
168 171
169 void Scheduler::NotifyReadyToActivate() { 172 void Scheduler::NotifyReadyToActivate() {
170 state_machine_.NotifyReadyToActivate(); 173 state_machine_.NotifyReadyToActivate();
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 ProcessScheduledActions(); 236 ProcessScheduledActions();
234 } 237 }
235 238
236 void Scheduler::DidManageTiles() { 239 void Scheduler::DidManageTiles() {
237 state_machine_.DidManageTiles(); 240 state_machine_.DidManageTiles();
238 } 241 }
239 242
240 void Scheduler::DidLoseOutputSurface() { 243 void Scheduler::DidLoseOutputSurface() {
241 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 244 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
242 state_machine_.DidLoseOutputSurface(); 245 state_machine_.DidLoseOutputSurface();
243 last_set_needs_begin_frame_ = false; 246 if (frame_source_->NeedsBeginFrames())
244 if (!settings_.begin_frame_scheduling_enabled) { 247 frame_source_->SetNeedsBeginFrames(false);
245 synthetic_begin_frame_source_->SetNeedsBeginFrame(false,
246 &begin_retro_frame_args_);
247 }
248 begin_retro_frame_args_.clear(); 248 begin_retro_frame_args_.clear();
249 ProcessScheduledActions(); 249 ProcessScheduledActions();
250 } 250 }
251 251
252 void Scheduler::DidCreateAndInitializeOutputSurface() { 252 void Scheduler::DidCreateAndInitializeOutputSurface() {
253 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 253 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
254 DCHECK(!last_set_needs_begin_frame_); 254 DCHECK(!frame_source_->NeedsBeginFrames());
255 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 255 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
256 state_machine_.DidCreateAndInitializeOutputSurface(); 256 state_machine_.DidCreateAndInitializeOutputSurface();
257 ProcessScheduledActions(); 257 ProcessScheduledActions();
258 } 258 }
259 259
260 void Scheduler::NotifyBeginMainFrameStarted() { 260 void Scheduler::NotifyBeginMainFrameStarted() {
261 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); 261 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted");
262 state_machine_.NotifyBeginMainFrameStarted(); 262 state_machine_.NotifyBeginMainFrameStarted();
263 } 263 }
264 264
265 base::TimeTicks Scheduler::AnticipatedDrawTime() const { 265 base::TimeTicks Scheduler::AnticipatedDrawTime() const {
266 if (!last_set_needs_begin_frame_ || 266 if (!frame_source_->NeedsBeginFrames() ||
267 begin_impl_frame_args_.interval <= base::TimeDelta()) 267 begin_impl_frame_args_.interval <= base::TimeDelta())
268 return base::TimeTicks(); 268 return base::TimeTicks();
269 269
270 base::TimeTicks now = Now(); 270 base::TimeTicks now = Now();
271 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time, 271 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
272 begin_impl_frame_args_.deadline); 272 begin_impl_frame_args_.deadline);
273 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval); 273 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
274 return timebase + (begin_impl_frame_args_.interval * intervals); 274 return timebase + (begin_impl_frame_args_.interval * intervals);
275 } 275 }
276 276
277 base::TimeTicks Scheduler::LastBeginImplFrameTime() { 277 base::TimeTicks Scheduler::LastBeginImplFrameTime() {
278 return begin_impl_frame_args_.frame_time; 278 return begin_impl_frame_args_.frame_time;
279 } 279 }
280 280
281 void Scheduler::SetupNextBeginFrameIfNeeded() { 281 void Scheduler::SetupNextBeginFrameIfNeeded() {
282 if (!task_runner_.get()) 282 if (!task_runner_.get())
283 return; 283 return;
284 284
285 bool needs_begin_frame = state_machine_.BeginFrameNeeded(); 285 bool needs_begin_frame = state_machine_.BeginFrameNeeded();
286 286
287 if (settings_.throttle_frame_production) { 287 bool at_end_of_deadline =
288 SetupNextBeginFrameWhenVSyncThrottlingEnabled(needs_begin_frame); 288 (state_machine_.begin_impl_frame_state() ==
289 } else { 289 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
290 SetupNextBeginFrameWhenVSyncThrottlingDisabled(needs_begin_frame); 290
291 bool should_call_set_needs_begin_frame =
292 // Always request the BeginFrame immediately if it wasn't needed before.
293 (needs_begin_frame && !frame_source_->NeedsBeginFrames()) ||
294 // Only stop requesting BeginFrames after a deadline.
295 (!needs_begin_frame && frame_source_->NeedsBeginFrames() &&
296 at_end_of_deadline);
297
298 if (should_call_set_needs_begin_frame) {
299 frame_source_->SetNeedsBeginFrames(needs_begin_frame);
291 } 300 }
301
302 if (at_end_of_deadline) {
303 frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
304 }
305
306 PostBeginRetroFrameIfNeeded();
292 SetupPollingMechanisms(needs_begin_frame); 307 SetupPollingMechanisms(needs_begin_frame);
293 } 308 }
294 309
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 310 // We may need to poll when we can't rely on BeginFrame to advance certain
359 // state or to avoid deadlock. 311 // state or to avoid deadlock.
360 void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) { 312 void Scheduler::SetupPollingMechanisms(bool needs_begin_frame) {
361 bool needs_advance_commit_state_timer = false; 313 bool needs_advance_commit_state_timer = false;
362 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but 314 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
363 // aren't expecting any more BeginFrames. This should only be needed by 315 // aren't expecting any more BeginFrames. This should only be needed by
364 // the synchronous compositor when BeginFrameNeeded is false. 316 // the synchronous compositor when BeginFrameNeeded is false.
365 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { 317 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
366 DCHECK(!state_machine_.SupportsProactiveBeginFrame()); 318 DCHECK(!state_machine_.SupportsProactiveBeginFrame());
367 DCHECK(!needs_begin_frame); 319 DCHECK(!needs_begin_frame);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 } 353 }
402 } else { 354 } else {
403 advance_commit_state_task_.Cancel(); 355 advance_commit_state_task_.Cancel();
404 } 356 }
405 } 357 }
406 358
407 // BeginFrame is the mechanism that tells us that now is a good time to start 359 // 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. 360 // 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 361 // If the scheduler is busy, we queue the BeginFrame to be handled later as
410 // a BeginRetroFrame. 362 // a BeginRetroFrame.
411 void Scheduler::BeginFrame(const BeginFrameArgs& args) { 363 bool Scheduler::OnBeginFrameMixInDelegate(const BeginFrameArgs& args) {
412 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue()); 364 TRACE_EVENT1("cc", "Scheduler::BeginFrame", "args", args.AsValue());
413 DCHECK(settings_.throttle_frame_production); 365
366 // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has
367 // sent us the last BeginFrame we have missed. As we might not be able to
368 // actually make rendering for this call, handle it like a "retro frame".
369 // TODO(brainderson): Add a test for this functionality ASAP!
370 if (args.type == BeginFrameArgs::MISSED) {
371 begin_retro_frame_args_.push_back(args);
372 PostBeginRetroFrameIfNeeded();
373 return true;
374 }
414 375
415 BeginFrameArgs adjusted_args(args); 376 BeginFrameArgs adjusted_args(args);
416 adjusted_args.deadline -= EstimatedParentDrawTime(); 377 adjusted_args.deadline -= EstimatedParentDrawTime();
417 378
418 bool should_defer_begin_frame; 379 bool should_defer_begin_frame;
419 if (settings_.using_synchronous_renderer_compositor) { 380 if (settings_.using_synchronous_renderer_compositor) {
420 should_defer_begin_frame = false; 381 should_defer_begin_frame = false;
421 } else { 382 } else {
422 should_defer_begin_frame = 383 should_defer_begin_frame =
423 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ || 384 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
424 !last_set_needs_begin_frame_ || 385 !frame_source_->NeedsBeginFrames() ||
425 (state_machine_.begin_impl_frame_state() != 386 (state_machine_.begin_impl_frame_state() !=
426 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 387 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
427 } 388 }
428 389
429 if (should_defer_begin_frame) { 390 if (should_defer_begin_frame) {
430 begin_retro_frame_args_.push_back(adjusted_args); 391 begin_retro_frame_args_.push_back(adjusted_args);
431 TRACE_EVENT_INSTANT0( 392 TRACE_EVENT_INSTANT0(
432 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); 393 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
433 return; 394 // Queuing the frame counts as "using it", so we need to return true.
395 } else {
396 BeginImplFrame(adjusted_args);
434 } 397 }
435 398 return true;
436 BeginImplFrame(adjusted_args);
437 } 399 }
438 400
439 // BeginRetroFrame is called for BeginFrames that we've deferred because 401 // BeginRetroFrame is called for BeginFrames that we've deferred because
440 // the scheduler was in the middle of processing a previous BeginFrame. 402 // the scheduler was in the middle of processing a previous BeginFrame.
441 void Scheduler::BeginRetroFrame() { 403 void Scheduler::BeginRetroFrame() {
442 TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame"); 404 TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame");
443 DCHECK(!settings_.using_synchronous_renderer_compositor); 405 DCHECK(!settings_.using_synchronous_renderer_compositor);
444 DCHECK(begin_retro_frame_posted_); 406 DCHECK(begin_retro_frame_posted_);
445 begin_retro_frame_posted_ = false; 407 begin_retro_frame_posted_ = false;
446 408
(...skipping 18 matching lines...) Expand all
465 break; 427 break;
466 428
467 TRACE_EVENT_INSTANT2("cc", 429 TRACE_EVENT_INSTANT2("cc",
468 "Scheduler::BeginRetroFrame discarding", 430 "Scheduler::BeginRetroFrame discarding",
469 TRACE_EVENT_SCOPE_THREAD, 431 TRACE_EVENT_SCOPE_THREAD,
470 "deadline - now", 432 "deadline - now",
471 (adjusted_deadline - now).InMicroseconds(), 433 (adjusted_deadline - now).InMicroseconds(),
472 "BeginFrameArgs", 434 "BeginFrameArgs",
473 begin_retro_frame_args_.front().AsValue()); 435 begin_retro_frame_args_.front().AsValue());
474 begin_retro_frame_args_.pop_front(); 436 begin_retro_frame_args_.pop_front();
437 frame_source_->DidFinishFrame(begin_retro_frame_args_.size());
475 } 438 }
476 439
477 if (begin_retro_frame_args_.empty()) { 440 if (begin_retro_frame_args_.empty()) {
478 DCHECK(settings_.throttle_frame_production);
479 TRACE_EVENT_INSTANT0("cc", 441 TRACE_EVENT_INSTANT0("cc",
480 "Scheduler::BeginRetroFrames all expired", 442 "Scheduler::BeginRetroFrames all expired",
481 TRACE_EVENT_SCOPE_THREAD); 443 TRACE_EVENT_SCOPE_THREAD);
482 } else { 444 } else {
483 BeginImplFrame(begin_retro_frame_args_.front()); 445 BeginImplFrame(begin_retro_frame_args_.front());
484 begin_retro_frame_args_.pop_front(); 446 begin_retro_frame_args_.pop_front();
485 } 447 }
486 } 448 }
487 449
488 // There could be a race between the posted BeginRetroFrame and a new 450 // There could be a race between the posted BeginRetroFrame and a new
489 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame 451 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
490 // will check if there is a pending BeginRetroFrame to ensure we handle 452 // will check if there is a pending BeginRetroFrame to ensure we handle
491 // BeginFrames in FIFO order. 453 // BeginFrames in FIFO order.
492 void Scheduler::PostBeginRetroFrameIfNeeded() { 454 void Scheduler::PostBeginRetroFrameIfNeeded() {
493 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 455 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
494 "Scheduler::PostBeginRetroFrameIfNeeded", 456 "Scheduler::PostBeginRetroFrameIfNeeded",
495 "state", 457 "state",
496 AsValue()); 458 AsValue());
497 if (!last_set_needs_begin_frame_) 459 if (!frame_source_->NeedsBeginFrames())
498 return; 460 return;
499 461
500 if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_) 462 if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_)
501 return; 463 return;
502 464
503 // begin_retro_frame_args_ should always be empty for the 465 // begin_retro_frame_args_ should always be empty for the
504 // synchronous compositor. 466 // synchronous compositor.
505 DCHECK(!settings_.using_synchronous_renderer_compositor); 467 DCHECK(!settings_.using_synchronous_renderer_compositor);
506 468
507 if (state_machine_.begin_impl_frame_state() != 469 if (state_machine_.begin_impl_frame_state() !=
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 scoped_refptr<base::debug::TracedValue> state = 667 scoped_refptr<base::debug::TracedValue> state =
706 new base::debug::TracedValue(); 668 new base::debug::TracedValue();
707 AsValueInto(state.get()); 669 AsValueInto(state.get());
708 return state; 670 return state;
709 } 671 }
710 672
711 void Scheduler::AsValueInto(base::debug::TracedValue* state) const { 673 void Scheduler::AsValueInto(base::debug::TracedValue* state) const {
712 state->BeginDictionary("state_machine"); 674 state->BeginDictionary("state_machine");
713 state_machine_.AsValueInto(state, Now()); 675 state_machine_.AsValueInto(state, Now());
714 state->EndDictionary(); 676 state->EndDictionary();
715 if (synthetic_begin_frame_source_) { 677
716 state->BeginDictionary("synthetic_begin_frame_source_"); 678 state->BeginDictionary("frame_source_");
717 synthetic_begin_frame_source_->AsValueInto(state); 679 frame_source_->AsValueInto(state);
718 state->EndDictionary(); 680 state->EndDictionary();
719 }
720 681
721 state->BeginDictionary("scheduler_state"); 682 state->BeginDictionary("scheduler_state");
722 state->SetDouble("time_until_anticipated_draw_time_ms", 683 state->SetDouble("time_until_anticipated_draw_time_ms",
723 (AnticipatedDrawTime() - Now()).InMillisecondsF()); 684 (AnticipatedDrawTime() - Now()).InMillisecondsF());
724 state->SetDouble("vsync_interval_ms", vsync_interval_.InMillisecondsF());
725 state->SetDouble("estimated_parent_draw_time_ms", 685 state->SetDouble("estimated_parent_draw_time_ms",
726 estimated_parent_draw_time_.InMillisecondsF()); 686 estimated_parent_draw_time_.InMillisecondsF());
727 state->SetBoolean("last_set_needs_begin_frame_", last_set_needs_begin_frame_); 687 state->SetBoolean("last_set_needs_begin_frame_",
728 state->SetBoolean("begin_unthrottled_frame_posted_", 688 frame_source_->NeedsBeginFrames());
729 begin_unthrottled_frame_posted_);
730 state->SetBoolean("begin_retro_frame_posted_", begin_retro_frame_posted_); 689 state->SetBoolean("begin_retro_frame_posted_", begin_retro_frame_posted_);
731 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size()); 690 state->SetInteger("begin_retro_frame_args_", begin_retro_frame_args_.size());
732 state->SetBoolean("begin_impl_frame_deadline_task_", 691 state->SetBoolean("begin_impl_frame_deadline_task_",
733 !begin_impl_frame_deadline_task_.IsCancelled()); 692 !begin_impl_frame_deadline_task_.IsCancelled());
734 state->SetBoolean("poll_for_draw_triggers_task_", 693 state->SetBoolean("poll_for_draw_triggers_task_",
735 !poll_for_draw_triggers_task_.IsCancelled()); 694 !poll_for_draw_triggers_task_.IsCancelled());
736 state->SetBoolean("advance_commit_state_task_", 695 state->SetBoolean("advance_commit_state_task_",
737 !advance_commit_state_task_.IsCancelled()); 696 !advance_commit_state_task_.IsCancelled());
738 state->BeginDictionary("begin_impl_frame_args"); 697 state->BeginDictionary("begin_impl_frame_args");
739 begin_impl_frame_args_.AsValueInto(state); 698 begin_impl_frame_args_.AsValueInto(state);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 } 732 }
774 733
775 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 734 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
776 return (state_machine_.commit_state() == 735 return (state_machine_.commit_state() ==
777 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 736 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
778 state_machine_.commit_state() == 737 state_machine_.commit_state() ==
779 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 738 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
780 } 739 }
781 740
782 } // namespace cc 741 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698