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

Side by Side Diff: cc/surfaces/display_scheduler.cc

Issue 2183333003: cc: Post the missed BeginFrame to a new stack (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: post-swapcomplete: comment Created 4 years, 4 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/surfaces/display_scheduler.h ('k') | cc/test/test_delegating_output_surface.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 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),
19 task_runner_(task_runner), 20 task_runner_(task_runner),
21 inside_surface_damaged_(false),
20 output_surface_lost_(false), 22 output_surface_lost_(false),
21 root_surface_resources_locked_(true), 23 root_surface_resources_locked_(true),
22 inside_begin_frame_deadline_interval_(false), 24 inside_begin_frame_deadline_interval_(false),
23 needs_draw_(false), 25 needs_draw_(false),
24 expecting_root_surface_damage_because_of_resize_(false), 26 expecting_root_surface_damage_because_of_resize_(false),
25 all_active_child_surfaces_ready_to_draw_(false), 27 all_active_child_surfaces_ready_to_draw_(false),
26 pending_swaps_(0), 28 pending_swaps_(0),
27 max_pending_swaps_(max_pending_swaps), 29 max_pending_swaps_(max_pending_swaps),
28 observing_begin_frame_source_(false), 30 observing_begin_frame_source_(false),
29 root_surface_damaged_(false), 31 root_surface_damaged_(false),
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 SurfaceDamaged(root_surface_id); 77 SurfaceDamaged(root_surface_id);
76 } 78 }
77 79
78 // Indicates that there was damage to one of the surfaces. 80 // Indicates that there was damage to one of the surfaces.
79 // Has some logic to wait for multiple active surfaces before 81 // Has some logic to wait for multiple active surfaces before
80 // triggering the deadline. 82 // triggering the deadline.
81 void DisplayScheduler::SurfaceDamaged(const SurfaceId& surface_id) { 83 void DisplayScheduler::SurfaceDamaged(const SurfaceId& surface_id) {
82 TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id", 84 TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id",
83 surface_id.ToString()); 85 surface_id.ToString());
84 86
87 // We may cause a new BeginFrame to be run inside this method, but to help
88 // avoid being reentrant to the caller of SurfaceDamaged, track when this is
89 // happening with |inside_surface_damaged_|.
90 base::AutoReset<bool>(&inside_surface_damaged_, true);
91
85 needs_draw_ = true; 92 needs_draw_ = true;
86 93
87 if (surface_id == root_surface_id_) { 94 if (surface_id == root_surface_id_) {
88 root_surface_damaged_ = true; 95 root_surface_damaged_ = true;
89 expecting_root_surface_damage_because_of_resize_ = false; 96 expecting_root_surface_damage_because_of_resize_ = false;
90 } else { 97 } else {
91 child_surface_ids_damaged_.insert(surface_id); 98 child_surface_ids_damaged_.insert(surface_id);
92 99
93 // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts. 100 // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts.
94 all_active_child_surfaces_ready_to_draw_ = base::STLIncludes( 101 all_active_child_surfaces_ready_to_draw_ = base::STLIncludes(
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 138
132 expect_damage_from_root_surface_ = root_surface_damaged_; 139 expect_damage_from_root_surface_ = root_surface_damaged_;
133 root_surface_damaged_ = false; 140 root_surface_damaged_ = false;
134 } 141 }
135 142
136 bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { 143 bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
137 base::TimeTicks now = base::TimeTicks::Now(); 144 base::TimeTicks now = base::TimeTicks::Now();
138 TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(), 145 TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(),
139 "now", now); 146 "now", now);
140 147
148 if (inside_surface_damaged_) {
149 // Repost this so that we don't run a missed BeginFrame on the same
150 // callstack. Otherwise we end up running unexpected scheduler actions
151 // immediately while inside some other action (such as submitting a
152 // CompositorFrame for a SurfaceFactory).
153 DCHECK_EQ(args.type, BeginFrameArgs::MISSED);
154 DCHECK(missed_begin_frame_task_.IsCancelled());
155 missed_begin_frame_task_.Reset(base::Bind(
156 base::IgnoreResult(&DisplayScheduler::OnBeginFrameDerivedImpl),
157 // The CancelableCallback will not run after it is destroyed, which
158 // happens when |this| is destroyed.
159 base::Unretained(this), args));
160 task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
161 return true;
162 }
163
141 // If we get another BeginFrame before the previous deadline, 164 // If we get another BeginFrame before the previous deadline,
142 // synchronously trigger the previous deadline before progressing. 165 // synchronously trigger the previous deadline before progressing.
143 if (inside_begin_frame_deadline_interval_) { 166 if (inside_begin_frame_deadline_interval_) {
144 OnBeginFrameDeadline(); 167 OnBeginFrameDeadline();
145 } 168 }
146 169
147 // Schedule the deadline. 170 // Schedule the deadline.
148 current_begin_frame_args_ = args; 171 current_begin_frame_args_ = args;
149 current_begin_frame_args_.deadline -= 172 current_begin_frame_args_.deadline -=
150 BeginFrameArgs::DefaultEstimatedParentDrawTime(); 173 BeginFrameArgs::DefaultEstimatedParentDrawTime();
151 inside_begin_frame_deadline_interval_ = true; 174 inside_begin_frame_deadline_interval_ = true;
152 ScheduleBeginFrameDeadline(); 175 ScheduleBeginFrameDeadline();
153 176
177 // If we get another BeginFrame before a posted missed frame, just drop the
178 // missed frame. Also if this was the missed frame, drop the Callback inside
179 // it. Do this last because this might be the missed frame and we don't want
180 // to destroy |args| prematurely.
181 missed_begin_frame_task_.Cancel();
182
154 return true; 183 return true;
155 } 184 }
156 185
157 void DisplayScheduler::OnBeginFrameSourcePausedChanged(bool paused) { 186 void DisplayScheduler::OnBeginFrameSourcePausedChanged(bool paused) {
158 // BeginFrameSources used with DisplayScheduler do not make use of this 187 // BeginFrameSources used with DisplayScheduler do not make use of this
159 // feature. 188 // feature.
160 if (paused) 189 if (paused)
161 NOTIMPLEMENTED(); 190 NOTIMPLEMENTED();
162 } 191 }
163 192
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 // We are going idle, so reset expectations. 305 // We are going idle, so reset expectations.
277 child_surface_ids_to_expect_damage_from_.clear(); 306 child_surface_ids_to_expect_damage_from_.clear();
278 child_surface_ids_damaged_prev_.clear(); 307 child_surface_ids_damaged_prev_.clear();
279 child_surface_ids_damaged_.clear(); 308 child_surface_ids_damaged_.clear();
280 all_active_child_surfaces_ready_to_draw_ = true; 309 all_active_child_surfaces_ready_to_draw_ = true;
281 expect_damage_from_root_surface_ = false; 310 expect_damage_from_root_surface_ = false;
282 311
283 if (observing_begin_frame_source_) { 312 if (observing_begin_frame_source_) {
284 observing_begin_frame_source_ = false; 313 observing_begin_frame_source_ = false;
285 begin_frame_source_->RemoveObserver(this); 314 begin_frame_source_->RemoveObserver(this);
315 // A missed BeginFrame may be queued, so drop that too if we're going to
316 // stop listening.
317 missed_begin_frame_task_.Cancel();
286 } 318 }
287 } 319 }
288 } 320 }
289 321
290 void DisplayScheduler::OnBeginFrameDeadline() { 322 void DisplayScheduler::OnBeginFrameDeadline() {
291 TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline"); 323 TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline");
292 324
293 AttemptDrawAndSwap(); 325 AttemptDrawAndSwap();
294 begin_frame_source_->DidFinishFrame(this, 0); 326 begin_frame_source_->DidFinishFrame(this, 0);
295 } 327 }
296 328
297 void DisplayScheduler::DidSwapBuffers() { 329 void DisplayScheduler::DidSwapBuffers() {
298 pending_swaps_++; 330 pending_swaps_++;
299 TRACE_EVENT_ASYNC_BEGIN1("cc", "DisplayScheduler:pending_swaps", this, 331 TRACE_EVENT_ASYNC_BEGIN1("cc", "DisplayScheduler:pending_swaps", this,
300 "pending_frames", pending_swaps_); 332 "pending_frames", pending_swaps_);
301 } 333 }
302 334
303 void DisplayScheduler::DidSwapBuffersComplete() { 335 void DisplayScheduler::DidSwapBuffersComplete() {
304 pending_swaps_--; 336 pending_swaps_--;
305 TRACE_EVENT_ASYNC_END1("cc", "DisplayScheduler:pending_swaps", this, 337 TRACE_EVENT_ASYNC_END1("cc", "DisplayScheduler:pending_swaps", this,
306 "pending_frames", pending_swaps_); 338 "pending_frames", pending_swaps_);
307 ScheduleBeginFrameDeadline(); 339 ScheduleBeginFrameDeadline();
308 } 340 }
309 341
310 } // namespace cc 342 } // namespace cc
OLDNEW
« no previous file with comments | « cc/surfaces/display_scheduler.h ('k') | cc/test/test_delegating_output_surface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698