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

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

Issue 218633010: cc: Handle retroactive BeginFrames in the Scheduler. (Closed) Base URL: http://git.chromium.org/chromium/src.git@compositorVsyncDisable
Patch Set: fix comment typo Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "cc/scheduler/scheduler.h" 5 #include "cc/scheduler/scheduler.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #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 "ui/gfx/frame_time.h" 13 #include "ui/gfx/frame_time.h"
14 14
15 namespace cc { 15 namespace cc {
16 16
17 Scheduler::Scheduler( 17 Scheduler::Scheduler(
18 SchedulerClient* client, 18 SchedulerClient* client,
19 const SchedulerSettings& scheduler_settings, 19 const SchedulerSettings& scheduler_settings,
20 int layer_tree_host_id, 20 int layer_tree_host_id,
21 const scoped_refptr<base::SequencedTaskRunner>& impl_task_runner) 21 const scoped_refptr<base::SequencedTaskRunner>& impl_task_runner)
22 : settings_(scheduler_settings), 22 : settings_(scheduler_settings),
23 client_(client), 23 client_(client),
24 layer_tree_host_id_(layer_tree_host_id), 24 layer_tree_host_id_(layer_tree_host_id),
25 impl_task_runner_(impl_task_runner), 25 impl_task_runner_(impl_task_runner),
26 last_set_needs_begin_impl_frame_(false), 26 last_set_needs_begin_frame_(false),
27 begin_retro_frame_posted_(false),
27 state_machine_(scheduler_settings), 28 state_machine_(scheduler_settings),
28 inside_process_scheduled_actions_(false), 29 inside_process_scheduled_actions_(false),
29 inside_action_(SchedulerStateMachine::ACTION_NONE), 30 inside_action_(SchedulerStateMachine::ACTION_NONE),
30 weak_factory_(this) { 31 weak_factory_(this) {
31 DCHECK(client_); 32 DCHECK(client_);
32 DCHECK(!state_machine_.BeginImplFrameNeeded()); 33 DCHECK(!state_machine_.BeginFrameNeeded());
33 if (settings_.main_frame_before_activation_enabled) { 34 if (settings_.main_frame_before_activation_enabled) {
34 DCHECK(settings_.main_frame_before_draw_enabled); 35 DCHECK(settings_.main_frame_before_draw_enabled);
35 } 36 }
36 37
38 begin_retro_frame_closure_ =
39 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr());
37 begin_impl_frame_deadline_closure_ = base::Bind( 40 begin_impl_frame_deadline_closure_ = base::Bind(
38 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); 41 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr());
39 poll_for_draw_triggers_closure_ = base::Bind( 42 poll_for_draw_triggers_closure_ = base::Bind(
40 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); 43 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr());
41 advance_commit_state_closure_ = base::Bind( 44 advance_commit_state_closure_ = base::Bind(
42 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); 45 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr());
43 } 46 }
44 47
45 Scheduler::~Scheduler() {} 48 Scheduler::~Scheduler() {}
46 49
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 ProcessScheduledActions(); 114 ProcessScheduledActions();
112 } 115 }
113 116
114 void Scheduler::DidManageTiles() { 117 void Scheduler::DidManageTiles() {
115 state_machine_.DidManageTiles(); 118 state_machine_.DidManageTiles();
116 } 119 }
117 120
118 void Scheduler::DidLoseOutputSurface() { 121 void Scheduler::DidLoseOutputSurface() {
119 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 122 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
120 state_machine_.DidLoseOutputSurface(); 123 state_machine_.DidLoseOutputSurface();
121 last_set_needs_begin_impl_frame_ = false; 124 last_set_needs_begin_frame_ = false;
125 begin_retro_frame_args_.clear();
122 ProcessScheduledActions(); 126 ProcessScheduledActions();
123 } 127 }
124 128
125 void Scheduler::DidCreateAndInitializeOutputSurface() { 129 void Scheduler::DidCreateAndInitializeOutputSurface() {
126 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 130 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
127 DCHECK(!last_set_needs_begin_impl_frame_); 131 DCHECK(!last_set_needs_begin_frame_);
128 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); 132 DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
129 state_machine_.DidCreateAndInitializeOutputSurface(); 133 state_machine_.DidCreateAndInitializeOutputSurface();
130 ProcessScheduledActions(); 134 ProcessScheduledActions();
131 } 135 }
132 136
133 void Scheduler::NotifyBeginMainFrameStarted() { 137 void Scheduler::NotifyBeginMainFrameStarted() {
134 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); 138 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted");
135 state_machine_.NotifyBeginMainFrameStarted(); 139 state_machine_.NotifyBeginMainFrameStarted();
136 } 140 }
137 141
138 base::TimeTicks Scheduler::AnticipatedDrawTime() const { 142 base::TimeTicks Scheduler::AnticipatedDrawTime() const {
139 if (!last_set_needs_begin_impl_frame_ || 143 if (!last_set_needs_begin_frame_ ||
140 last_begin_impl_frame_args_.interval <= base::TimeDelta()) 144 begin_impl_frame_args_.interval <= base::TimeDelta())
141 return base::TimeTicks(); 145 return base::TimeTicks();
142 146
143 base::TimeTicks now = gfx::FrameTime::Now(); 147 base::TimeTicks now = gfx::FrameTime::Now();
144 base::TimeTicks timebase = std::max(last_begin_impl_frame_args_.frame_time, 148 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time,
145 last_begin_impl_frame_args_.deadline); 149 begin_impl_frame_args_.deadline);
146 int64 intervals = 150 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval);
147 1 + ((now - timebase) / last_begin_impl_frame_args_.interval); 151 return timebase + (begin_impl_frame_args_.interval * intervals);
148 return timebase + (last_begin_impl_frame_args_.interval * intervals);
149 } 152 }
150 153
151 base::TimeTicks Scheduler::LastBeginImplFrameTime() { 154 base::TimeTicks Scheduler::LastBeginImplFrameTime() {
152 return last_begin_impl_frame_args_.frame_time; 155 return begin_impl_frame_args_.frame_time;
153 } 156 }
154 157
155 void Scheduler::SetupNextBeginImplFrameIfNeeded() { 158 void Scheduler::SetupNextBeginFrameIfNeeded() {
156 bool needs_begin_impl_frame = 159 bool needs_begin_frame = state_machine_.BeginFrameNeeded();
157 state_machine_.BeginImplFrameNeeded();
158 160
159 bool at_end_of_deadline = 161 bool at_end_of_deadline =
160 state_machine_.begin_impl_frame_state() == 162 state_machine_.begin_impl_frame_state() ==
161 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 163 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
162 164
163 bool should_call_set_needs_begin_impl_frame = 165 bool should_call_set_needs_begin_frame =
164 // Always request the BeginImplFrame immediately if it wasn't needed 166 // Always request the BeginFrame immediately if it wasn't needed before.
165 // before. 167 (needs_begin_frame && !last_set_needs_begin_frame_) ||
166 (needs_begin_impl_frame && !last_set_needs_begin_impl_frame_) || 168 // We always need to explicitly request our next BeginFrame.
167 // We always need to explicitly request our next BeginImplFrame.
168 at_end_of_deadline; 169 at_end_of_deadline;
169 170
170 if (should_call_set_needs_begin_impl_frame) { 171 if (should_call_set_needs_begin_frame) {
171 client_->SetNeedsBeginImplFrame(needs_begin_impl_frame); 172 client_->SetNeedsBeginFrame(needs_begin_frame);
172 last_set_needs_begin_impl_frame_ = needs_begin_impl_frame; 173 last_set_needs_begin_frame_ = needs_begin_frame;
173 } 174 }
174 175
176 // Handle retroactive BeginFrames.
177 if (last_set_needs_begin_frame_)
178 PostBeginRetroFrameIfNeeded();
179
175 bool needs_advance_commit_state_timer = false; 180 bool needs_advance_commit_state_timer = false;
176 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but 181 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but
177 // aren't expecting any more BeginImplFrames. This should only be needed by 182 // aren't expecting any more BeginFrames. This should only be needed by
178 // the synchronous compositor when BeginImplFrameNeeded is false. 183 // the synchronous compositor when BeginFrameNeeded is false.
179 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { 184 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) {
180 DCHECK(!state_machine_.SupportsProactiveBeginImplFrame()); 185 DCHECK(!state_machine_.SupportsProactiveBeginFrame());
181 DCHECK(!needs_begin_impl_frame); 186 DCHECK(!needs_begin_frame);
182 if (poll_for_draw_triggers_task_.IsCancelled()) { 187 if (poll_for_draw_triggers_task_.IsCancelled()) {
183 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); 188 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_);
184 base::TimeDelta delay = last_begin_impl_frame_args_.IsValid() 189 base::TimeDelta delay = begin_impl_frame_args_.IsValid()
185 ? last_begin_impl_frame_args_.interval 190 ? begin_impl_frame_args_.interval
186 : BeginFrameArgs::DefaultInterval(); 191 : BeginFrameArgs::DefaultInterval();
187 impl_task_runner_->PostDelayedTask( 192 impl_task_runner_->PostDelayedTask(
188 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay); 193 FROM_HERE, poll_for_draw_triggers_task_.callback(), delay);
189 } 194 }
190 } else { 195 } else {
191 poll_for_draw_triggers_task_.Cancel(); 196 poll_for_draw_triggers_task_.Cancel();
192 197
193 // At this point we'd prefer to advance through the commit flow by 198 // At this point we'd prefer to advance through the commit flow by
194 // drawing a frame, however it's possible that the frame rate controller 199 // drawing a frame, however it's possible that the frame rate controller
195 // will not give us a BeginImplFrame until the commit completes. See 200 // will not give us a BeginFrame until the commit completes. See
196 // crbug.com/317430 for an example of a swap ack being held on commit. Thus 201 // crbug.com/317430 for an example of a swap ack being held on commit. Thus
197 // we set a repeating timer to poll on ProcessScheduledActions until we 202 // we set a repeating timer to poll on ProcessScheduledActions until we
198 // successfully reach BeginImplFrame. Synchronous compositor does not use 203 // successfully reach BeginFrame. Synchronous compositor does not use
199 // frame rate controller or have the circular wait in the bug. 204 // frame rate controller or have the circular wait in the bug.
200 if (IsBeginMainFrameSentOrStarted() && 205 if (IsBeginMainFrameSentOrStarted() &&
201 !settings_.using_synchronous_renderer_compositor) { 206 !settings_.using_synchronous_renderer_compositor) {
202 needs_advance_commit_state_timer = true; 207 needs_advance_commit_state_timer = true;
203 } 208 }
204 } 209 }
205 210
206 if (needs_advance_commit_state_timer) { 211 if (needs_advance_commit_state_timer) {
207 if (advance_commit_state_task_.IsCancelled() && 212 if (advance_commit_state_task_.IsCancelled() &&
208 last_begin_impl_frame_args_.IsValid()) { 213 begin_impl_frame_args_.IsValid()) {
209 // Since we'd rather get a BeginImplFrame by the normal mechanism, we 214 // Since we'd rather get a BeginImplFrame by the normal mechanism, we
210 // set the interval to twice the interval from the previous frame. 215 // set the interval to twice the interval from the previous frame.
211 advance_commit_state_task_.Reset(advance_commit_state_closure_); 216 advance_commit_state_task_.Reset(advance_commit_state_closure_);
212 impl_task_runner_->PostDelayedTask( 217 impl_task_runner_->PostDelayedTask(FROM_HERE,
213 FROM_HERE, 218 advance_commit_state_task_.callback(),
214 advance_commit_state_task_.callback(), 219 begin_impl_frame_args_.interval * 2);
215 last_begin_impl_frame_args_.interval * 2);
216 } 220 }
217 } else { 221 } else {
218 advance_commit_state_task_.Cancel(); 222 advance_commit_state_task_.Cancel();
219 } 223 }
220 } 224 }
221 225
226 // BeginFrame is the mechanism that tells us that now is a good time to start
227 // making a frame. Usually this means that user input for the frame is complete.
228 // If the scheduler is busy, we queue the BeginFrame to be handled later as
229 // a BeginRetroFrame.
230 void Scheduler::BeginFrame(const BeginFrameArgs& args) {
231 bool should_defer_begin_frame;
232 if (settings_.using_synchronous_renderer_compositor) {
233 should_defer_begin_frame = false;
234 } else {
235 should_defer_begin_frame =
236 !begin_retro_frame_args_.empty() || begin_retro_frame_posted_ ||
237 !last_set_needs_begin_frame_ ||
238 (state_machine_.begin_impl_frame_state() !=
239 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
240 }
241
242 if (should_defer_begin_frame) {
243 begin_retro_frame_args_.push_back(args);
244 TRACE_EVENT_INSTANT0(
245 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD);
246 return;
247 }
248
249 BeginImplFrame(args);
250 }
251
252 // BeginRetroFrame is called for BeginFrames that we've deferred because
253 // the scheduler was in the middle of processing a previous BeginFrame.
254 void Scheduler::BeginRetroFrame() {
255 TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame");
256 DCHECK(begin_retro_frame_posted_);
257 DCHECK(!begin_retro_frame_args_.empty());
258 DCHECK(!settings_.using_synchronous_renderer_compositor);
259
260 // Discard expired BeginRetroFrames
261 // Today, we should always end up with at most one un-expired BeginRetroFrame
262 // because deadlines will not be greater than the next frame time. We don't
263 // DCHECK though because some systems don't always have monotonic timestamps.
264 // TODO(brianderson): In the future, long deadlines could result in us not
265 // draining the queue if we don't catch up. If we consistently can't catch
266 // up, our fallback should be to lower our frame rate.
267 base::TimeTicks now = gfx::FrameTime::Now();
268 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
269 while (!begin_retro_frame_args_.empty() &&
270 now > AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front(),
271 draw_duration_estimate)) {
272 begin_retro_frame_args_.pop_front();
273 }
274
275 if (begin_retro_frame_args_.empty()) {
276 TRACE_EVENT_INSTANT0(
277 "cc", "Scheduler::BeginRetroFrames expired", TRACE_EVENT_SCOPE_THREAD);
278 } else {
279 BeginImplFrame(begin_retro_frame_args_.front());
280 begin_retro_frame_args_.pop_front();
281 }
282
283 begin_retro_frame_posted_ = false;
284 }
285
286 // There could be a race between the posted BeginRetroFrame and a new
287 // BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame
288 // will check if there is a pending BeginRetroFrame to ensure we handle
289 // BeginFrames in FIFO order.
290 void Scheduler::PostBeginRetroFrameIfNeeded() {
291 if (begin_retro_frame_args_.empty() || begin_retro_frame_posted_)
292 return;
293
294 // begin_retro_frame_args_ should always be empty for the
295 // synchronous compositor.
296 DCHECK(!settings_.using_synchronous_renderer_compositor);
297
298 if (state_machine_.begin_impl_frame_state() !=
299 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE)
300 return;
301
302 begin_retro_frame_posted_ = true;
303 impl_task_runner_->PostTask(FROM_HERE, begin_retro_frame_closure_);
304 }
305
306 // BeginImplFrame starts a compositor frame that will wait up until a deadline
307 // for a BeginMainFrame+activation to complete before it times out and draws
308 // any asynchronous animation and scroll/pinch updates.
222 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { 309 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) {
223 TRACE_EVENT0("cc", "Scheduler::BeginImplFrame"); 310 TRACE_EVENT0("cc", "Scheduler::BeginImplFrame");
224 DCHECK(state_machine_.begin_impl_frame_state() == 311 DCHECK(state_machine_.begin_impl_frame_state() ==
225 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); 312 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE);
226 DCHECK(state_machine_.HasInitializedOutputSurface()); 313 DCHECK(state_machine_.HasInitializedOutputSurface());
227 314
228 advance_commit_state_task_.Cancel(); 315 advance_commit_state_task_.Cancel();
229 316
230 last_begin_impl_frame_args_ = args; 317 base::TimeDelta draw_duration_estimate = client_->DrawDurationEstimate();
231 last_begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); 318 begin_impl_frame_args_ = args;
319 begin_impl_frame_args_.deadline -= draw_duration_estimate;
232 320
233 if (!state_machine_.smoothness_takes_priority() && 321 if (!state_machine_.smoothness_takes_priority() &&
234 state_machine_.MainThreadIsInHighLatencyMode() && 322 state_machine_.MainThreadIsInHighLatencyMode() &&
235 CanCommitAndActivateBeforeDeadline()) { 323 CanCommitAndActivateBeforeDeadline()) {
236 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); 324 state_machine_.SetSkipNextBeginMainFrameToReduceLatency();
237 } 325 }
238 326
239 state_machine_.OnBeginImplFrame(last_begin_impl_frame_args_); 327 client_->WillBeginImplFrame(begin_impl_frame_args_);
328 state_machine_.OnBeginImplFrame(begin_impl_frame_args_);
240 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); 329 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_);
241 330
242 ProcessScheduledActions(); 331 ProcessScheduledActions();
243 332
244 if (!state_machine_.HasInitializedOutputSurface()) 333 if (!state_machine_.HasInitializedOutputSurface())
245 return; 334 return;
246 335
247 state_machine_.OnBeginImplFrameDeadlinePending(); 336 state_machine_.OnBeginImplFrameDeadlinePending();
248 base::TimeTicks adjusted_deadline = AdjustedBeginImplFrameDeadline(); 337 ScheduleBeginImplFrameDeadline(
249 ScheduleBeginImplFrameDeadline(adjusted_deadline); 338 AdjustedBeginImplFrameDeadline(args, draw_duration_estimate));
250 } 339 }
251 340
252 base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline() const { 341 base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline(
342 const BeginFrameArgs& args,
343 base::TimeDelta draw_duration_estimate) const {
253 if (settings_.using_synchronous_renderer_compositor) { 344 if (settings_.using_synchronous_renderer_compositor) {
254 // The synchronous compositor needs to draw right away. 345 // The synchronous compositor needs to draw right away.
255 return base::TimeTicks(); 346 return base::TimeTicks();
256 } else if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { 347 } else if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) {
257 // We are ready to draw a new active tree immediately. 348 // We are ready to draw a new active tree immediately.
258 return base::TimeTicks(); 349 return base::TimeTicks();
259 } else if (state_machine_.needs_redraw()) { 350 } else if (state_machine_.needs_redraw()) {
260 // We have an animation or fast input path on the impl thread that wants 351 // We have an animation or fast input path on the impl thread that wants
261 // to draw, so don't wait too long for a new active tree. 352 // to draw, so don't wait too long for a new active tree.
262 return last_begin_impl_frame_args_.deadline; 353 return args.deadline - draw_duration_estimate;
263 } else { 354 } else {
264 // The impl thread doesn't have anything it wants to draw and we are just 355 // The impl thread doesn't have anything it wants to draw and we are just
265 // waiting for a new active tree, so post the deadline for the next 356 // waiting for a new active tree, so post the deadline for the next
266 // expected BeginImplFrame start. This allows us to draw immediately when 357 // expected BeginImplFrame start. This allows us to draw immediately when
267 // there is a new active tree, instead of waiting for the next 358 // there is a new active tree, instead of waiting for the next
268 // BeginImplFrame. 359 // BeginImplFrame.
269 // TODO(brianderson): Handle long deadlines (that are past the next frame's 360 // TODO(brianderson): Handle long deadlines (that are past the next frame's
270 // frame time) properly instead of using this hack. 361 // frame time) properly instead of using this hack.
271 return last_begin_impl_frame_args_.frame_time + 362 return args.frame_time + args.interval;
272 last_begin_impl_frame_args_.interval;
273 } 363 }
274 } 364 }
275 365
276 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) { 366 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) {
277 if (settings_.using_synchronous_renderer_compositor) { 367 if (settings_.using_synchronous_renderer_compositor) {
278 // The synchronous renderer compositor has to make its GL calls 368 // The synchronous renderer compositor has to make its GL calls
279 // within this call. 369 // within this call.
280 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks 370 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
281 // so the sychronous renderer compositor can take advantage of splitting 371 // so the sychronous renderer compositor can take advantage of splitting
282 // up the BeginImplFrame and deadline as well. 372 // up the BeginImplFrame and deadline as well.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 break; 485 break;
396 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 486 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
397 client_->ScheduledActionBeginOutputSurfaceCreation(); 487 client_->ScheduledActionBeginOutputSurfaceCreation();
398 break; 488 break;
399 case SchedulerStateMachine::ACTION_MANAGE_TILES: 489 case SchedulerStateMachine::ACTION_MANAGE_TILES:
400 client_->ScheduledActionManageTiles(); 490 client_->ScheduledActionManageTiles();
401 break; 491 break;
402 } 492 }
403 } while (action != SchedulerStateMachine::ACTION_NONE); 493 } while (action != SchedulerStateMachine::ACTION_NONE);
404 494
405 SetupNextBeginImplFrameIfNeeded(); 495 SetupNextBeginFrameIfNeeded();
406 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); 496 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
407 497
408 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { 498 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) {
409 DCHECK(!settings_.using_synchronous_renderer_compositor); 499 DCHECK(!settings_.using_synchronous_renderer_compositor);
410 ScheduleBeginImplFrameDeadline(base::TimeTicks()); 500 ScheduleBeginImplFrameDeadline(base::TimeTicks());
411 } 501 }
412 } 502 }
413 503
414 bool Scheduler::WillDrawIfNeeded() const { 504 bool Scheduler::WillDrawIfNeeded() const {
415 return !state_machine_.PendingDrawsShouldBeAborted(); 505 return !state_machine_.PendingDrawsShouldBeAborted();
416 } 506 }
417 507
418 scoped_ptr<base::Value> Scheduler::StateAsValue() const { 508 scoped_ptr<base::Value> Scheduler::StateAsValue() const {
419 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); 509 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
420 state->Set("state_machine", state_machine_.AsValue().release()); 510 state->Set("state_machine", state_machine_.AsValue().release());
421 511
422 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); 512 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue);
423 scheduler_state->SetDouble( 513 scheduler_state->SetDouble(
424 "time_until_anticipated_draw_time_ms", 514 "time_until_anticipated_draw_time_ms",
425 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); 515 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF());
426 scheduler_state->SetBoolean("last_set_needs_begin_impl_frame_", 516 scheduler_state->SetBoolean("last_set_needs_begin_frame_",
427 last_set_needs_begin_impl_frame_); 517 last_set_needs_begin_frame_);
428 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", 518 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_",
429 !begin_impl_frame_deadline_task_.IsCancelled()); 519 !begin_impl_frame_deadline_task_.IsCancelled());
430 scheduler_state->SetBoolean("poll_for_draw_triggers_task_", 520 scheduler_state->SetBoolean("poll_for_draw_triggers_task_",
431 !poll_for_draw_triggers_task_.IsCancelled()); 521 !poll_for_draw_triggers_task_.IsCancelled());
432 scheduler_state->SetBoolean("advance_commit_state_task_", 522 scheduler_state->SetBoolean("advance_commit_state_task_",
433 !advance_commit_state_task_.IsCancelled()); 523 !advance_commit_state_task_.IsCancelled());
434 state->Set("scheduler_state", scheduler_state.release()); 524 state->Set("scheduler_state", scheduler_state.release());
435 525
436 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue); 526 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue);
437 client_state->SetDouble("draw_duration_estimate_ms", 527 client_state->SetDouble("draw_duration_estimate_ms",
438 client_->DrawDurationEstimate().InMillisecondsF()); 528 client_->DrawDurationEstimate().InMillisecondsF());
439 client_state->SetDouble( 529 client_state->SetDouble(
440 "begin_main_frame_to_commit_duration_estimate_ms", 530 "begin_main_frame_to_commit_duration_estimate_ms",
441 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); 531 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF());
442 client_state->SetDouble( 532 client_state->SetDouble(
443 "commit_to_activate_duration_estimate_ms", 533 "commit_to_activate_duration_estimate_ms",
444 client_->CommitToActivateDurationEstimate().InMillisecondsF()); 534 client_->CommitToActivateDurationEstimate().InMillisecondsF());
445 state->Set("client_state", client_state.release()); 535 state->Set("client_state", client_state.release());
446 return state.PassAs<base::Value>(); 536 return state.PassAs<base::Value>();
447 } 537 }
448 538
449 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { 539 bool Scheduler::CanCommitAndActivateBeforeDeadline() const {
450 // Check if the main thread computation and commit can be finished before the 540 // Check if the main thread computation and commit can be finished before the
451 // impl thread's deadline. 541 // impl thread's deadline.
452 base::TimeTicks estimated_draw_time = 542 base::TimeTicks estimated_draw_time =
453 last_begin_impl_frame_args_.frame_time + 543 begin_impl_frame_args_.frame_time +
454 client_->BeginMainFrameToCommitDurationEstimate() + 544 client_->BeginMainFrameToCommitDurationEstimate() +
455 client_->CommitToActivateDurationEstimate(); 545 client_->CommitToActivateDurationEstimate();
456 546
457 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), 547 TRACE_EVENT2(
458 "CanCommitAndActivateBeforeDeadline", 548 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
459 "time_left_after_drawing_ms", 549 "CanCommitAndActivateBeforeDeadline",
460 (last_begin_impl_frame_args_.deadline - estimated_draw_time) 550 "time_left_after_drawing_ms",
461 .InMillisecondsF(), 551 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(),
462 "state", 552 "state",
463 TracedValue::FromValue(StateAsValue().release())); 553 TracedValue::FromValue(StateAsValue().release()));
464 554
465 return estimated_draw_time < last_begin_impl_frame_args_.deadline; 555 return estimated_draw_time < begin_impl_frame_args_.deadline;
466 } 556 }
467 557
468 bool Scheduler::IsBeginMainFrameSentOrStarted() const { 558 bool Scheduler::IsBeginMainFrameSentOrStarted() const {
469 return (state_machine_.commit_state() == 559 return (state_machine_.commit_state() ==
470 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || 560 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT ||
471 state_machine_.commit_state() == 561 state_machine_.commit_state() ==
472 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); 562 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED);
473 } 563 }
474 564
475 } // namespace cc 565 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698