Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/surfaces/display_scheduler.h" | 5 #include "cc/surfaces/display_scheduler.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/auto_reset.h" | |
| 9 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 10 #include "base/trace_event/trace_event.h" | 11 #include "base/trace_event/trace_event.h" |
| 11 #include "cc/output/output_surface.h" | 12 #include "cc/output/output_surface.h" |
| 12 | 13 |
| 13 namespace cc { | 14 namespace cc { |
| 14 | 15 |
| 15 DisplayScheduler::DisplayScheduler(BeginFrameSource* begin_frame_source, | 16 DisplayScheduler::DisplayScheduler(BeginFrameSource* begin_frame_source, |
| 16 base::SingleThreadTaskRunner* task_runner, | 17 base::SingleThreadTaskRunner* task_runner, |
| 17 int max_pending_swaps) | 18 int max_pending_swaps) |
| 18 : begin_frame_source_(begin_frame_source), | 19 : begin_frame_source_(begin_frame_source), |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 90 } else { | 91 } else { |
| 91 child_surface_ids_damaged_.insert(surface_id); | 92 child_surface_ids_damaged_.insert(surface_id); |
| 92 | 93 |
| 93 // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts. | 94 // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts. |
| 94 all_active_child_surfaces_ready_to_draw_ = base::STLIncludes( | 95 all_active_child_surfaces_ready_to_draw_ = base::STLIncludes( |
| 95 child_surface_ids_damaged_, child_surface_ids_to_expect_damage_from_); | 96 child_surface_ids_damaged_, child_surface_ids_to_expect_damage_from_); |
| 96 } | 97 } |
| 97 | 98 |
| 98 if (!output_surface_lost_ && !observing_begin_frame_source_) { | 99 if (!output_surface_lost_ && !observing_begin_frame_source_) { |
| 99 observing_begin_frame_source_ = true; | 100 observing_begin_frame_source_ = true; |
| 101 // When we call AddObserver() this will cause a missed BeginFrame to | |
| 102 // occur. We need to detect this and not process it immediately in the | |
| 103 // same call stack. | |
| 104 base::AutoReset<bool>(&inside_external_action_, true); | |
| 100 begin_frame_source_->AddObserver(this); | 105 begin_frame_source_->AddObserver(this); |
| 101 } | 106 } |
| 102 | 107 |
| 103 ScheduleBeginFrameDeadline(); | 108 ScheduleBeginFrameDeadline(); |
| 104 } | 109 } |
| 105 | 110 |
| 106 void DisplayScheduler::OutputSurfaceLost() { | 111 void DisplayScheduler::OutputSurfaceLost() { |
| 107 TRACE_EVENT0("cc", "DisplayScheduler::OutputSurfaceLost"); | 112 TRACE_EVENT0("cc", "DisplayScheduler::OutputSurfaceLost"); |
| 108 output_surface_lost_ = true; | 113 output_surface_lost_ = true; |
| 109 ScheduleBeginFrameDeadline(); | 114 ScheduleBeginFrameDeadline(); |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 131 | 136 |
| 132 expect_damage_from_root_surface_ = root_surface_damaged_; | 137 expect_damage_from_root_surface_ = root_surface_damaged_; |
| 133 root_surface_damaged_ = false; | 138 root_surface_damaged_ = false; |
| 134 } | 139 } |
| 135 | 140 |
| 136 bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { | 141 bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { |
| 137 base::TimeTicks now = base::TimeTicks::Now(); | 142 base::TimeTicks now = base::TimeTicks::Now(); |
| 138 TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(), | 143 TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(), |
| 139 "now", now); | 144 "now", now); |
| 140 | 145 |
| 146 if (inside_external_action_) { | |
| 147 // Repost this so that we don't run a missed BeginFrame on the same | |
| 148 // callstack. Otherwise we end up running unexpected scheduler actions | |
| 149 // immediately while inside some other action (such as submitting a | |
| 150 // CompositorFrame for a SurfaceFactory). | |
| 151 DCHECK_EQ(args.type, BeginFrameArgs::MISSED); | |
| 152 DCHECK(missed_begin_frame_task_.IsCancelled()); | |
| 153 missed_begin_frame_task_.Reset(base::Bind( | |
| 154 base::IgnoreResult(&DisplayScheduler::OnBeginFrameDerivedImpl), | |
| 155 // The CancelableCallback will not run after it is destroyed, which | |
| 156 // happens when |this| is destroyed. | |
| 157 base::Unretained(this), args)); | |
| 158 task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback()); | |
| 159 return true; | |
| 160 } | |
| 161 | |
| 141 // If we get another BeginFrame before the previous deadline, | 162 // If we get another BeginFrame before the previous deadline, |
| 142 // synchronously trigger the previous deadline before progressing. | 163 // synchronously trigger the previous deadline before progressing. |
| 143 if (inside_begin_frame_deadline_interval_) { | 164 if (inside_begin_frame_deadline_interval_) { |
| 144 OnBeginFrameDeadline(); | 165 OnBeginFrameDeadline(); |
| 145 } | 166 } |
| 146 | 167 |
| 147 // Schedule the deadline. | 168 // Schedule the deadline. |
| 148 current_begin_frame_args_ = args; | 169 current_begin_frame_args_ = args; |
| 149 current_begin_frame_args_.deadline -= | 170 current_begin_frame_args_.deadline -= |
| 150 BeginFrameArgs::DefaultEstimatedParentDrawTime(); | 171 BeginFrameArgs::DefaultEstimatedParentDrawTime(); |
| 151 inside_begin_frame_deadline_interval_ = true; | 172 inside_begin_frame_deadline_interval_ = true; |
| 152 ScheduleBeginFrameDeadline(); | 173 ScheduleBeginFrameDeadline(); |
| 153 | 174 |
| 175 // If we get another BeginFrame before a posted missed frame, just drop the | |
|
sunnyps
2016/07/27 05:21:02
nit: We also need to cancel the missed frame in ca
danakj
2016/07/27 22:34:55
I'm not sure what you mean here sorry, can you exp
sunnyps
2016/07/27 22:44:38
Just a nit about the comment.
The comment seems t
| |
| 176 // missed frame. (Do this last because this might be the missed frame and | |
|
sunnyps
2016/07/27 05:21:02
nit: dangling parens
danakj
2016/07/27 22:34:55
Done.
| |
| 177 // we don't want to destroy |args| prematurely. | |
| 178 missed_begin_frame_task_.Cancel(); | |
| 179 | |
| 154 return true; | 180 return true; |
| 155 } | 181 } |
| 156 | 182 |
| 157 void DisplayScheduler::OnBeginFrameSourcePausedChanged(bool paused) { | 183 void DisplayScheduler::OnBeginFrameSourcePausedChanged(bool paused) { |
| 158 // BeginFrameSources used with DisplayScheduler do not make use of this | 184 // BeginFrameSources used with DisplayScheduler do not make use of this |
| 159 // feature. | 185 // feature. |
| 160 if (paused) | 186 if (paused) |
| 161 NOTIMPLEMENTED(); | 187 NOTIMPLEMENTED(); |
| 162 } | 188 } |
| 163 | 189 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 276 // We are going idle, so reset expectations. | 302 // We are going idle, so reset expectations. |
| 277 child_surface_ids_to_expect_damage_from_.clear(); | 303 child_surface_ids_to_expect_damage_from_.clear(); |
| 278 child_surface_ids_damaged_prev_.clear(); | 304 child_surface_ids_damaged_prev_.clear(); |
| 279 child_surface_ids_damaged_.clear(); | 305 child_surface_ids_damaged_.clear(); |
| 280 all_active_child_surfaces_ready_to_draw_ = true; | 306 all_active_child_surfaces_ready_to_draw_ = true; |
| 281 expect_damage_from_root_surface_ = false; | 307 expect_damage_from_root_surface_ = false; |
| 282 | 308 |
| 283 if (observing_begin_frame_source_) { | 309 if (observing_begin_frame_source_) { |
| 284 observing_begin_frame_source_ = false; | 310 observing_begin_frame_source_ = false; |
| 285 begin_frame_source_->RemoveObserver(this); | 311 begin_frame_source_->RemoveObserver(this); |
| 312 // A missed BeginFrame may be queued, so drop that too if we're going to | |
| 313 // stop listening. | |
| 314 missed_begin_frame_task_.Cancel(); | |
| 286 } | 315 } |
| 287 } | 316 } |
| 288 } | 317 } |
| 289 | 318 |
| 290 void DisplayScheduler::OnBeginFrameDeadline() { | 319 void DisplayScheduler::OnBeginFrameDeadline() { |
| 291 TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline"); | 320 TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline"); |
| 292 | 321 |
| 293 AttemptDrawAndSwap(); | 322 AttemptDrawAndSwap(); |
| 294 begin_frame_source_->DidFinishFrame(this, 0); | 323 begin_frame_source_->DidFinishFrame(this, 0); |
| 295 } | 324 } |
| 296 | 325 |
| 297 void DisplayScheduler::DidSwapBuffers() { | 326 void DisplayScheduler::DidSwapBuffers() { |
| 298 pending_swaps_++; | 327 pending_swaps_++; |
| 299 TRACE_EVENT_ASYNC_BEGIN1("cc", "DisplayScheduler:pending_swaps", this, | 328 TRACE_EVENT_ASYNC_BEGIN1("cc", "DisplayScheduler:pending_swaps", this, |
| 300 "pending_frames", pending_swaps_); | 329 "pending_frames", pending_swaps_); |
| 301 } | 330 } |
| 302 | 331 |
| 303 void DisplayScheduler::DidSwapBuffersComplete() { | 332 void DisplayScheduler::DidSwapBuffersComplete() { |
| 304 pending_swaps_--; | 333 pending_swaps_--; |
| 305 TRACE_EVENT_ASYNC_END1("cc", "DisplayScheduler:pending_swaps", this, | 334 TRACE_EVENT_ASYNC_END1("cc", "DisplayScheduler:pending_swaps", this, |
| 306 "pending_frames", pending_swaps_); | 335 "pending_frames", pending_swaps_); |
| 307 ScheduleBeginFrameDeadline(); | 336 ScheduleBeginFrameDeadline(); |
| 308 } | 337 } |
| 309 | 338 |
| 310 } // namespace cc | 339 } // namespace cc |
| OLD | NEW |