Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 |
| 37 begin_impl_frame_deadline_closure_ = base::Bind( | 38 begin_impl_frame_deadline_closure_ = base::Bind( |
| 38 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); | 39 &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); |
| 39 poll_for_draw_triggers_closure_ = base::Bind( | 40 poll_for_draw_triggers_closure_ = base::Bind( |
| 40 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); | 41 &Scheduler::PollForAnticipatedDrawTriggers, weak_factory_.GetWeakPtr()); |
| 41 advance_commit_state_closure_ = base::Bind( | 42 advance_commit_state_closure_ = base::Bind( |
| 42 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); | 43 &Scheduler::PollToAdvanceCommitState, weak_factory_.GetWeakPtr()); |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 ProcessScheduledActions(); | 117 ProcessScheduledActions(); |
| 117 } | 118 } |
| 118 | 119 |
| 119 void Scheduler::DidManageTiles() { | 120 void Scheduler::DidManageTiles() { |
| 120 state_machine_.DidManageTiles(); | 121 state_machine_.DidManageTiles(); |
| 121 } | 122 } |
| 122 | 123 |
| 123 void Scheduler::DidLoseOutputSurface() { | 124 void Scheduler::DidLoseOutputSurface() { |
| 124 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); | 125 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
| 125 state_machine_.DidLoseOutputSurface(); | 126 state_machine_.DidLoseOutputSurface(); |
| 126 last_set_needs_begin_impl_frame_ = false; | 127 last_set_needs_begin_frame_ = false; |
| 128 begin_retro_frame_args_.clear(); | |
| 127 ProcessScheduledActions(); | 129 ProcessScheduledActions(); |
| 128 } | 130 } |
| 129 | 131 |
| 130 void Scheduler::DidCreateAndInitializeOutputSurface() { | 132 void Scheduler::DidCreateAndInitializeOutputSurface() { |
| 131 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); | 133 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
| 132 DCHECK(!last_set_needs_begin_impl_frame_); | 134 DCHECK(!last_set_needs_begin_frame_); |
| 133 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); | 135 DCHECK(begin_impl_frame_deadline_task_.IsCancelled()); |
| 134 state_machine_.DidCreateAndInitializeOutputSurface(); | 136 state_machine_.DidCreateAndInitializeOutputSurface(); |
| 135 ProcessScheduledActions(); | 137 ProcessScheduledActions(); |
| 136 } | 138 } |
| 137 | 139 |
| 138 void Scheduler::NotifyBeginMainFrameStarted() { | 140 void Scheduler::NotifyBeginMainFrameStarted() { |
| 139 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); | 141 TRACE_EVENT0("cc", "Scheduler::NotifyBeginMainFrameStarted"); |
| 140 state_machine_.NotifyBeginMainFrameStarted(); | 142 state_machine_.NotifyBeginMainFrameStarted(); |
| 141 } | 143 } |
| 142 | 144 |
| 143 base::TimeTicks Scheduler::AnticipatedDrawTime() const { | 145 base::TimeTicks Scheduler::AnticipatedDrawTime() const { |
| 144 if (!last_set_needs_begin_impl_frame_ || | 146 if (!last_set_needs_begin_frame_ || |
| 145 last_begin_impl_frame_args_.interval <= base::TimeDelta()) | 147 begin_impl_frame_args_.interval <= base::TimeDelta()) |
| 146 return base::TimeTicks(); | 148 return base::TimeTicks(); |
| 147 | 149 |
| 148 base::TimeTicks now = gfx::FrameTime::Now(); | 150 base::TimeTicks now = gfx::FrameTime::Now(); |
| 149 base::TimeTicks timebase = std::max(last_begin_impl_frame_args_.frame_time, | 151 base::TimeTicks timebase = std::max(begin_impl_frame_args_.frame_time, |
| 150 last_begin_impl_frame_args_.deadline); | 152 begin_impl_frame_args_.deadline); |
| 151 int64 intervals = | 153 int64 intervals = 1 + ((now - timebase) / begin_impl_frame_args_.interval); |
| 152 1 + ((now - timebase) / last_begin_impl_frame_args_.interval); | 154 return timebase + (begin_impl_frame_args_.interval * intervals); |
| 153 return timebase + (last_begin_impl_frame_args_.interval * intervals); | |
| 154 } | 155 } |
| 155 | 156 |
| 156 base::TimeTicks Scheduler::LastBeginImplFrameTime() { | 157 base::TimeTicks Scheduler::LastBeginImplFrameTime() { |
| 157 return last_begin_impl_frame_args_.frame_time; | 158 return begin_impl_frame_args_.frame_time; |
| 158 } | 159 } |
| 159 | 160 |
| 160 void Scheduler::SetupNextBeginImplFrameIfNeeded() { | 161 void Scheduler::SetupNextBeginFrameIfNeeded() { |
| 161 bool needs_begin_impl_frame = | 162 bool needs_begin_frame = state_machine_.BeginFrameNeeded(); |
| 162 state_machine_.BeginImplFrameNeeded(); | |
| 163 | 163 |
| 164 bool at_end_of_deadline = | 164 bool at_end_of_deadline = |
| 165 state_machine_.begin_impl_frame_state() == | 165 state_machine_.begin_impl_frame_state() == |
| 166 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; | 166 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; |
| 167 | 167 |
| 168 bool should_call_set_needs_begin_impl_frame = | 168 bool should_call_set_needs_begin_frame = |
| 169 // Always request the BeginImplFrame immediately if it wasn't needed | 169 // Always request the BeginFrame immediately if it wasn't needed before. |
| 170 // before. | 170 (needs_begin_frame && !last_set_needs_begin_frame_) || |
| 171 (needs_begin_impl_frame && !last_set_needs_begin_impl_frame_) || | 171 // We always need to explicitly request our next BeginFrame. |
| 172 // We always need to explicitly request our next BeginImplFrame. | |
| 173 at_end_of_deadline; | 172 at_end_of_deadline; |
| 174 | 173 |
| 175 if (should_call_set_needs_begin_impl_frame) { | 174 if (should_call_set_needs_begin_frame) { |
| 176 client_->SetNeedsBeginImplFrame(needs_begin_impl_frame); | 175 client_->SetNeedsBeginFrame(needs_begin_frame); |
| 177 last_set_needs_begin_impl_frame_ = needs_begin_impl_frame; | 176 last_set_needs_begin_frame_ = needs_begin_frame; |
| 177 } | |
| 178 | |
| 179 // Handle retroactive BeginFrames. | |
| 180 if (needs_begin_frame && !begin_retro_frame_posted_ && | |
|
Sami
2014/04/03 15:55:58
Not sure if you saw my earlier question: do we nee
brianderson
2014/04/03 16:36:17
Yes, I need to disable this for WebView.
brianderson
2014/04/03 21:55:55
Done.
| |
| 181 !begin_retro_frame_args_.empty() && | |
| 182 state_machine_.begin_impl_frame_state() == | |
| 183 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { | |
| 184 begin_retro_frame_posted_ = true; | |
| 185 impl_task_runner_->PostTask( | |
| 186 FROM_HERE, | |
| 187 base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr())); | |
|
Sami
2014/04/03 15:55:58
While we're at it should we make this a pre-create
brianderson
2014/04/03 16:36:17
Oops. Yes.
brianderson
2014/04/03 21:55:55
Done.
| |
| 178 } | 188 } |
| 179 | 189 |
| 180 bool needs_advance_commit_state_timer = false; | 190 bool needs_advance_commit_state_timer = false; |
| 181 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but | 191 // Setup PollForAnticipatedDrawTriggers if we need to monitor state but |
| 182 // aren't expecting any more BeginImplFrames. This should only be needed by | 192 // aren't expecting any more BeginFrames. This should only be needed by |
| 183 // the synchronous compositor when BeginImplFrameNeeded is false. | 193 // the synchronous compositor when BeginFrameNeeded is false. |
| 184 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { | 194 if (state_machine_.ShouldPollForAnticipatedDrawTriggers()) { |
| 185 DCHECK(!state_machine_.SupportsProactiveBeginImplFrame()); | 195 DCHECK(!state_machine_.SupportsProactiveBeginFrame()); |
| 186 DCHECK(!needs_begin_impl_frame); | 196 DCHECK(!needs_begin_frame); |
| 187 if (poll_for_draw_triggers_task_.IsCancelled()) { | 197 if (poll_for_draw_triggers_task_.IsCancelled()) { |
| 188 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); | 198 poll_for_draw_triggers_task_.Reset(poll_for_draw_triggers_closure_); |
| 189 impl_task_runner_->PostDelayedTask( | 199 impl_task_runner_->PostDelayedTask( |
| 190 FROM_HERE, | 200 FROM_HERE, |
| 191 poll_for_draw_triggers_task_.callback(), | 201 poll_for_draw_triggers_task_.callback(), |
| 192 last_begin_impl_frame_args_.interval); | 202 begin_impl_frame_args_.interval); |
| 193 } | 203 } |
| 194 } else { | 204 } else { |
| 195 poll_for_draw_triggers_task_.Cancel(); | 205 poll_for_draw_triggers_task_.Cancel(); |
| 196 | 206 |
| 197 // At this point we'd prefer to advance through the commit flow by | 207 // At this point we'd prefer to advance through the commit flow by |
| 198 // drawing a frame, however it's possible that the frame rate controller | 208 // drawing a frame, however it's possible that the frame rate controller |
| 199 // will not give us a BeginImplFrame until the commit completes. See | 209 // will not give us a BeginFrame until the commit completes. See |
| 200 // crbug.com/317430 for an example of a swap ack being held on commit. Thus | 210 // crbug.com/317430 for an example of a swap ack being held on commit. Thus |
| 201 // we set a repeating timer to poll on ProcessScheduledActions until we | 211 // we set a repeating timer to poll on ProcessScheduledActions until we |
| 202 // successfully reach BeginImplFrame. Synchronous compositor does not use | 212 // successfully reach BeginFrame. Synchronous compositor does not use |
| 203 // frame rate controller or have the circular wait in the bug. | 213 // frame rate controller or have the circular wait in the bug. |
| 204 if (IsBeginMainFrameSentOrStarted() && | 214 if (IsBeginMainFrameSentOrStarted() && |
| 205 !settings_.using_synchronous_renderer_compositor) { | 215 !settings_.using_synchronous_renderer_compositor) { |
| 206 needs_advance_commit_state_timer = true; | 216 needs_advance_commit_state_timer = true; |
| 207 } | 217 } |
| 208 } | 218 } |
| 209 | 219 |
| 210 if (needs_advance_commit_state_timer) { | 220 if (needs_advance_commit_state_timer) { |
| 211 if (advance_commit_state_task_.IsCancelled() && | 221 if (advance_commit_state_task_.IsCancelled() && |
| 212 last_begin_impl_frame_args_.IsValid()) { | 222 begin_impl_frame_args_.IsValid()) { |
| 213 // Since we'd rather get a BeginImplFrame by the normal mechanism, we | 223 // Since we'd rather get a BeginImplFrame by the normal mechanism, we |
| 214 // set the interval to twice the interval from the previous frame. | 224 // set the interval to twice the interval from the previous frame. |
| 215 advance_commit_state_task_.Reset(advance_commit_state_closure_); | 225 advance_commit_state_task_.Reset(advance_commit_state_closure_); |
| 216 impl_task_runner_->PostDelayedTask( | 226 impl_task_runner_->PostDelayedTask(FROM_HERE, |
| 217 FROM_HERE, | 227 advance_commit_state_task_.callback(), |
| 218 advance_commit_state_task_.callback(), | 228 begin_impl_frame_args_.interval * 2); |
| 219 last_begin_impl_frame_args_.interval * 2); | |
| 220 } | 229 } |
| 221 } else { | 230 } else { |
| 222 advance_commit_state_task_.Cancel(); | 231 advance_commit_state_task_.Cancel(); |
| 223 } | 232 } |
| 224 } | 233 } |
| 225 | 234 |
| 235 void Scheduler::BeginFrame(const BeginFrameArgs& args) { | |
| 236 if (last_set_needs_begin_frame_ && begin_retro_frame_args_.empty() && | |
| 237 state_machine_.begin_impl_frame_state() == | |
| 238 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { | |
| 239 BeginImplFrame(args); | |
| 240 } else { | |
| 241 begin_retro_frame_args_.push_back(args); | |
| 242 TRACE_EVENT_INSTANT0( | |
| 243 "cc", "Scheduler::BeginFrame deferred", TRACE_EVENT_SCOPE_THREAD); | |
| 244 } | |
| 245 } | |
| 246 | |
| 247 void Scheduler::BeginRetroFrame() { | |
| 248 TRACE_EVENT0("cc", "Scheduler::BeginRetroFrame"); | |
| 249 DCHECK(!begin_retro_frame_args_.empty()); | |
|
Sami
2014/04/03 15:55:58
DCHECK(begin_retro_frame_posted_)?
brianderson
2014/04/03 16:36:17
Good idea.
brianderson
2014/04/03 21:55:55
Done.
| |
| 250 | |
| 251 // Discard expired BeginRetroFrames | |
| 252 base::TimeTicks now = gfx::FrameTime::Now(); | |
| 253 while (!begin_retro_frame_args_.empty() && | |
| 254 now > | |
| 255 AdjustedBeginImplFrameDeadline(begin_retro_frame_args_.front())) { | |
|
Sami
2014/04/03 15:55:58
Side note: the client call to compute the estimate
brianderson
2014/04/03 16:36:17
I will pull out the duration calculation.
brianderson
2014/04/03 21:55:55
Done.
| |
| 256 begin_retro_frame_args_.pop_front(); | |
| 257 } | |
| 258 | |
| 259 if (begin_retro_frame_args_.empty()) { | |
| 260 TRACE_EVENT_INSTANT0( | |
| 261 "cc", "Scheduler::BeginRetroFrames expired", TRACE_EVENT_SCOPE_THREAD); | |
| 262 } else { | |
| 263 BeginImplFrame(begin_retro_frame_args_.front()); | |
| 264 begin_retro_frame_args_.pop_front(); | |
| 265 } | |
| 266 | |
| 267 begin_retro_frame_posted_ = false; | |
| 268 } | |
| 269 | |
| 226 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { | 270 void Scheduler::BeginImplFrame(const BeginFrameArgs& args) { |
| 227 TRACE_EVENT0("cc", "Scheduler::BeginImplFrame"); | 271 TRACE_EVENT0("cc", "Scheduler::BeginImplFrame"); |
| 228 DCHECK(state_machine_.begin_impl_frame_state() == | 272 DCHECK(state_machine_.begin_impl_frame_state() == |
| 229 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); | 273 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); |
| 230 DCHECK(state_machine_.HasInitializedOutputSurface()); | 274 DCHECK(state_machine_.HasInitializedOutputSurface()); |
| 231 | 275 |
| 232 advance_commit_state_task_.Cancel(); | 276 advance_commit_state_task_.Cancel(); |
| 233 | 277 |
| 234 last_begin_impl_frame_args_ = args; | |
| 235 last_begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); | |
| 236 | |
| 237 if (!state_machine_.smoothness_takes_priority() && | 278 if (!state_machine_.smoothness_takes_priority() && |
| 238 state_machine_.MainThreadIsInHighLatencyMode() && | 279 state_machine_.MainThreadIsInHighLatencyMode() && |
| 239 CanCommitAndActivateBeforeDeadline()) { | 280 CanCommitAndActivateBeforeDeadline()) { |
| 240 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); | 281 state_machine_.SetSkipNextBeginMainFrameToReduceLatency(); |
| 241 } | 282 } |
| 242 | 283 |
| 243 state_machine_.OnBeginImplFrame(last_begin_impl_frame_args_); | 284 begin_impl_frame_args_ = args; |
|
Sami
2014/04/03 15:55:58
Do we need to move this down for a particular reas
brianderson
2014/04/03 16:36:17
Bad cherry-pick. Will move back up.
brianderson
2014/04/03 21:55:55
Done.
| |
| 285 begin_impl_frame_args_.deadline -= client_->DrawDurationEstimate(); | |
| 286 | |
| 287 client_->WillBeginImplFrame(begin_impl_frame_args_); | |
| 288 state_machine_.OnBeginImplFrame(begin_impl_frame_args_); | |
| 244 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); | 289 devtools_instrumentation::DidBeginFrame(layer_tree_host_id_); |
| 245 | 290 |
| 246 ProcessScheduledActions(); | 291 ProcessScheduledActions(); |
| 247 | 292 |
| 248 if (!state_machine_.HasInitializedOutputSurface()) | 293 if (!state_machine_.HasInitializedOutputSurface()) |
| 249 return; | 294 return; |
| 250 | 295 |
| 251 state_machine_.OnBeginImplFrameDeadlinePending(); | 296 state_machine_.OnBeginImplFrameDeadlinePending(); |
| 252 base::TimeTicks adjusted_deadline = AdjustedBeginImplFrameDeadline(); | 297 ScheduleBeginImplFrameDeadline(AdjustedBeginImplFrameDeadline(args)); |
| 253 ScheduleBeginImplFrameDeadline(adjusted_deadline); | |
| 254 } | 298 } |
| 255 | 299 |
| 256 base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline() const { | 300 base::TimeTicks Scheduler::AdjustedBeginImplFrameDeadline( |
| 301 const BeginFrameArgs& args) const { | |
| 257 if (settings_.using_synchronous_renderer_compositor) { | 302 if (settings_.using_synchronous_renderer_compositor) { |
| 258 // The synchronous compositor needs to draw right away. | 303 // The synchronous compositor needs to draw right away. |
| 259 return base::TimeTicks(); | 304 return base::TimeTicks(); |
| 260 } else if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { | 305 } else if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { |
| 261 // We are ready to draw a new active tree immediately. | 306 // We are ready to draw a new active tree immediately. |
| 262 return base::TimeTicks(); | 307 return base::TimeTicks(); |
| 263 } else if (state_machine_.needs_redraw()) { | 308 } else if (state_machine_.needs_redraw()) { |
| 264 // We have an animation or fast input path on the impl thread that wants | 309 // We have an animation or fast input path on the impl thread that wants |
| 265 // to draw, so don't wait too long for a new active tree. | 310 // to draw, so don't wait too long for a new active tree. |
| 266 return last_begin_impl_frame_args_.deadline; | 311 return args.deadline - client_->DrawDurationEstimate(); |
| 267 } else { | 312 } else { |
| 268 // The impl thread doesn't have anything it wants to draw and we are just | 313 // The impl thread doesn't have anything it wants to draw and we are just |
| 269 // waiting for a new active tree, so post the deadline for the next | 314 // waiting for a new active tree, so post the deadline for the next |
| 270 // expected BeginImplFrame start. This allows us to draw immediately when | 315 // expected BeginImplFrame start. This allows us to draw immediately when |
| 271 // there is a new active tree, instead of waiting for the next | 316 // there is a new active tree, instead of waiting for the next |
| 272 // BeginImplFrame. | 317 // BeginImplFrame. |
| 273 // TODO(brianderson): Handle long deadlines (that are past the next frame's | 318 // TODO(brianderson): Handle long deadlines (that are past the next frame's |
| 274 // frame time) properly instead of using this hack. | 319 // frame time) properly instead of using this hack. |
| 275 return last_begin_impl_frame_args_.frame_time + | 320 return args.frame_time + args.interval; |
| 276 last_begin_impl_frame_args_.interval; | |
| 277 } | 321 } |
| 278 } | 322 } |
| 279 | 323 |
| 280 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) { | 324 void Scheduler::ScheduleBeginImplFrameDeadline(base::TimeTicks deadline) { |
| 281 if (settings_.using_synchronous_renderer_compositor) { | 325 if (settings_.using_synchronous_renderer_compositor) { |
| 282 // The synchronous renderer compositor has to make its GL calls | 326 // The synchronous renderer compositor has to make its GL calls |
| 283 // within this call. | 327 // within this call. |
| 284 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks | 328 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks |
| 285 // so the sychronous renderer compositor can take advantage of splitting | 329 // so the sychronous renderer compositor can take advantage of splitting |
| 286 // up the BeginImplFrame and deadline as well. | 330 // up the BeginImplFrame and deadline as well. |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 break; | 446 break; |
| 403 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: | 447 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: |
| 404 client_->ScheduledActionAcquireLayerTexturesForMainThread(); | 448 client_->ScheduledActionAcquireLayerTexturesForMainThread(); |
| 405 break; | 449 break; |
| 406 case SchedulerStateMachine::ACTION_MANAGE_TILES: | 450 case SchedulerStateMachine::ACTION_MANAGE_TILES: |
| 407 client_->ScheduledActionManageTiles(); | 451 client_->ScheduledActionManageTiles(); |
| 408 break; | 452 break; |
| 409 } | 453 } |
| 410 } while (action != SchedulerStateMachine::ACTION_NONE); | 454 } while (action != SchedulerStateMachine::ACTION_NONE); |
| 411 | 455 |
| 412 SetupNextBeginImplFrameIfNeeded(); | 456 SetupNextBeginFrameIfNeeded(); |
| 413 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); | 457 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); |
| 414 | 458 |
| 415 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { | 459 if (state_machine_.ShouldTriggerBeginImplFrameDeadlineEarly()) { |
| 416 DCHECK(!settings_.using_synchronous_renderer_compositor); | 460 DCHECK(!settings_.using_synchronous_renderer_compositor); |
| 417 ScheduleBeginImplFrameDeadline(base::TimeTicks()); | 461 ScheduleBeginImplFrameDeadline(base::TimeTicks()); |
| 418 } | 462 } |
| 419 } | 463 } |
| 420 | 464 |
| 421 bool Scheduler::WillDrawIfNeeded() const { | 465 bool Scheduler::WillDrawIfNeeded() const { |
| 422 return !state_machine_.PendingDrawsShouldBeAborted(); | 466 return !state_machine_.PendingDrawsShouldBeAborted(); |
| 423 } | 467 } |
| 424 | 468 |
| 425 scoped_ptr<base::Value> Scheduler::StateAsValue() const { | 469 scoped_ptr<base::Value> Scheduler::StateAsValue() const { |
| 426 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); | 470 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); |
| 427 state->Set("state_machine", state_machine_.AsValue().release()); | 471 state->Set("state_machine", state_machine_.AsValue().release()); |
| 428 | 472 |
| 429 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); | 473 scoped_ptr<base::DictionaryValue> scheduler_state(new base::DictionaryValue); |
| 430 scheduler_state->SetDouble( | 474 scheduler_state->SetDouble( |
| 431 "time_until_anticipated_draw_time_ms", | 475 "time_until_anticipated_draw_time_ms", |
| 432 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); | 476 (AnticipatedDrawTime() - base::TimeTicks::Now()).InMillisecondsF()); |
| 433 scheduler_state->SetBoolean("last_set_needs_begin_impl_frame_", | 477 scheduler_state->SetBoolean("last_set_needs_begin_frame_", |
| 434 last_set_needs_begin_impl_frame_); | 478 last_set_needs_begin_frame_); |
| 435 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", | 479 scheduler_state->SetBoolean("begin_impl_frame_deadline_task_", |
| 436 !begin_impl_frame_deadline_task_.IsCancelled()); | 480 !begin_impl_frame_deadline_task_.IsCancelled()); |
| 437 scheduler_state->SetBoolean("poll_for_draw_triggers_task_", | 481 scheduler_state->SetBoolean("poll_for_draw_triggers_task_", |
| 438 !poll_for_draw_triggers_task_.IsCancelled()); | 482 !poll_for_draw_triggers_task_.IsCancelled()); |
| 439 scheduler_state->SetBoolean("advance_commit_state_task_", | 483 scheduler_state->SetBoolean("advance_commit_state_task_", |
| 440 !advance_commit_state_task_.IsCancelled()); | 484 !advance_commit_state_task_.IsCancelled()); |
| 441 state->Set("scheduler_state", scheduler_state.release()); | 485 state->Set("scheduler_state", scheduler_state.release()); |
| 442 | 486 |
| 443 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue); | 487 scoped_ptr<base::DictionaryValue> client_state(new base::DictionaryValue); |
| 444 client_state->SetDouble("draw_duration_estimate_ms", | 488 client_state->SetDouble("draw_duration_estimate_ms", |
| 445 client_->DrawDurationEstimate().InMillisecondsF()); | 489 client_->DrawDurationEstimate().InMillisecondsF()); |
| 446 client_state->SetDouble( | 490 client_state->SetDouble( |
| 447 "begin_main_frame_to_commit_duration_estimate_ms", | 491 "begin_main_frame_to_commit_duration_estimate_ms", |
| 448 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); | 492 client_->BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); |
| 449 client_state->SetDouble( | 493 client_state->SetDouble( |
| 450 "commit_to_activate_duration_estimate_ms", | 494 "commit_to_activate_duration_estimate_ms", |
| 451 client_->CommitToActivateDurationEstimate().InMillisecondsF()); | 495 client_->CommitToActivateDurationEstimate().InMillisecondsF()); |
| 452 state->Set("client_state", client_state.release()); | 496 state->Set("client_state", client_state.release()); |
| 453 return state.PassAs<base::Value>(); | 497 return state.PassAs<base::Value>(); |
| 454 } | 498 } |
| 455 | 499 |
| 456 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { | 500 bool Scheduler::CanCommitAndActivateBeforeDeadline() const { |
| 457 // Check if the main thread computation and commit can be finished before the | 501 // Check if the main thread computation and commit can be finished before the |
| 458 // impl thread's deadline. | 502 // impl thread's deadline. |
| 459 base::TimeTicks estimated_draw_time = | 503 base::TimeTicks estimated_draw_time = |
| 460 last_begin_impl_frame_args_.frame_time + | 504 begin_impl_frame_args_.frame_time + |
| 461 client_->BeginMainFrameToCommitDurationEstimate() + | 505 client_->BeginMainFrameToCommitDurationEstimate() + |
| 462 client_->CommitToActivateDurationEstimate(); | 506 client_->CommitToActivateDurationEstimate(); |
| 463 | 507 |
| 464 TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), | 508 TRACE_EVENT2( |
| 465 "CanCommitAndActivateBeforeDeadline", | 509 TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), |
| 466 "time_left_after_drawing_ms", | 510 "CanCommitAndActivateBeforeDeadline", |
| 467 (last_begin_impl_frame_args_.deadline - estimated_draw_time) | 511 "time_left_after_drawing_ms", |
| 468 .InMillisecondsF(), | 512 (begin_impl_frame_args_.deadline - estimated_draw_time).InMillisecondsF(), |
| 469 "state", | 513 "state", |
| 470 TracedValue::FromValue(StateAsValue().release())); | 514 TracedValue::FromValue(StateAsValue().release())); |
| 471 | 515 |
| 472 return estimated_draw_time < last_begin_impl_frame_args_.deadline; | 516 return estimated_draw_time < begin_impl_frame_args_.deadline; |
| 473 } | 517 } |
| 474 | 518 |
| 475 bool Scheduler::IsBeginMainFrameSentOrStarted() const { | 519 bool Scheduler::IsBeginMainFrameSentOrStarted() const { |
| 476 return (state_machine_.commit_state() == | 520 return (state_machine_.commit_state() == |
| 477 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || | 521 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT || |
| 478 state_machine_.commit_state() == | 522 state_machine_.commit_state() == |
| 479 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); | 523 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED); |
| 480 } | 524 } |
| 481 | 525 |
| 482 } // namespace cc | 526 } // namespace cc |
| OLD | NEW |