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 |