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

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

Issue 1258273005: Revert of cc: Consider Surface active if frame received recently (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 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/surfaces/display_scheduler_unittest.cc » ('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/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
11 #include "cc/output/output_surface.h" 11 #include "cc/output/output_surface.h"
12 12
13 namespace cc { 13 namespace cc {
14 14
15 DisplayScheduler::DisplayScheduler(DisplaySchedulerClient* client, 15 DisplayScheduler::DisplayScheduler(DisplaySchedulerClient* client,
16 BeginFrameSource* begin_frame_source, 16 BeginFrameSource* begin_frame_source,
17 base::SingleThreadTaskRunner* task_runner, 17 base::SingleThreadTaskRunner* task_runner,
18 int max_pending_swaps) 18 int max_pending_swaps)
19 : client_(client), 19 : client_(client),
20 begin_frame_source_(begin_frame_source), 20 begin_frame_source_(begin_frame_source),
21 task_runner_(task_runner), 21 task_runner_(task_runner),
22 output_surface_lost_(false), 22 output_surface_lost_(false),
23 root_surface_resources_locked_(true), 23 root_surface_resources_locked_(true),
24 inside_begin_frame_deadline_interval_(false), 24 inside_begin_frame_deadline_interval_(false),
25 needs_draw_(false), 25 needs_draw_(false),
26 child_surfaces_ready_to_draw_(false), 26 expecting_root_surface_damage_because_of_resize_(false),
27 all_active_child_surfaces_ready_to_draw_(false),
27 pending_swaps_(0), 28 pending_swaps_(0),
28 max_pending_swaps_(max_pending_swaps), 29 max_pending_swaps_(max_pending_swaps),
29 root_surface_damaged_(false), 30 root_surface_damaged_(false),
30 root_surface_active_(false), 31 expect_damage_from_root_surface_(false),
31 expecting_root_surface_damage_because_of_resize_(false),
32 active_child_surface_ids_index_(0),
33 weak_ptr_factory_(this) { 32 weak_ptr_factory_(this) {
34 begin_frame_source_->AddObserver(this); 33 begin_frame_source_->AddObserver(this);
35 begin_frame_deadline_closure_ = base::Bind( 34 begin_frame_deadline_closure_ = base::Bind(
36 &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr()); 35 &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr());
37 } 36 }
38 37
39 DisplayScheduler::~DisplayScheduler() { 38 DisplayScheduler::~DisplayScheduler() {
40 begin_frame_source_->RemoveObserver(this); 39 begin_frame_source_->RemoveObserver(this);
41 } 40 }
42 41
(...skipping 10 matching lines...) Expand all
53 void DisplayScheduler::ForceImmediateSwapIfPossible() { 52 void DisplayScheduler::ForceImmediateSwapIfPossible() {
54 TRACE_EVENT0("cc", "DisplayScheduler::ForceImmediateSwapIfPossible"); 53 TRACE_EVENT0("cc", "DisplayScheduler::ForceImmediateSwapIfPossible");
55 bool in_begin = inside_begin_frame_deadline_interval_; 54 bool in_begin = inside_begin_frame_deadline_interval_;
56 AttemptDrawAndSwap(); 55 AttemptDrawAndSwap();
57 if (in_begin) 56 if (in_begin)
58 begin_frame_source_->DidFinishFrame(0); 57 begin_frame_source_->DidFinishFrame(0);
59 } 58 }
60 59
61 void DisplayScheduler::DisplayResized() { 60 void DisplayScheduler::DisplayResized() {
62 expecting_root_surface_damage_because_of_resize_ = true; 61 expecting_root_surface_damage_because_of_resize_ = true;
63 root_surface_active_ = true; 62 expect_damage_from_root_surface_ = true;
64 ScheduleBeginFrameDeadline(); 63 ScheduleBeginFrameDeadline();
65 } 64 }
66 65
67 // Notification that there was a resize or the root surface changed and 66 // Notification that there was a resize or the root surface changed and
68 // that we should just draw immediately. 67 // that we should just draw immediately.
69 void DisplayScheduler::SetNewRootSurface(SurfaceId root_surface_id) { 68 void DisplayScheduler::SetNewRootSurface(SurfaceId root_surface_id) {
70 TRACE_EVENT0("cc", "DisplayScheduler::SetNewRootSurface"); 69 TRACE_EVENT0("cc", "DisplayScheduler::SetNewRootSurface");
71 root_surface_id_ = root_surface_id; 70 root_surface_id_ = root_surface_id;
72 SurfaceDamaged(root_surface_id); 71 SurfaceDamaged(root_surface_id);
73 } 72 }
74 73
75 // Indicates that there was damage to one of the surfaces. 74 // Indicates that there was damage to one of the surfaces.
76 // Has some logic to wait for multiple active surfaces before 75 // Has some logic to wait for multiple active surfaces before
77 // triggering the deadline. 76 // triggering the deadline.
78 void DisplayScheduler::SurfaceDamaged(SurfaceId surface_id) { 77 void DisplayScheduler::SurfaceDamaged(SurfaceId surface_id) {
79 TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id", 78 TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id",
80 surface_id.id); 79 surface_id.id);
81 80
82 needs_draw_ = true; 81 needs_draw_ = true;
83 82
84 if (surface_id == root_surface_id_) { 83 if (surface_id == root_surface_id_) {
85 root_surface_damaged_ = true; 84 root_surface_damaged_ = true;
86 expecting_root_surface_damage_because_of_resize_ = false; 85 expecting_root_surface_damage_because_of_resize_ = false;
87 } else { 86 } else {
88 child_surface_ids_damaged_.insert(surface_id); 87 child_surface_ids_damaged_.insert(surface_id);
89 88
90 // Update future expectations for active child surfaces.
91 for (int i = 0; i < kNumFramesSurfaceIsActive; i++)
92 active_child_surface_ids_[i].insert(surface_id);
93
94 // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts. 89 // TODO(mithro): Use hints from SetNeedsBeginFrames and SwapAborts.
95 child_surfaces_ready_to_draw_ = base::STLIncludes( 90 all_active_child_surfaces_ready_to_draw_ = base::STLIncludes(
96 child_surface_ids_damaged_, 91 child_surface_ids_damaged_, child_surface_ids_to_expect_damage_from_);
97 active_child_surface_ids_[active_child_surface_ids_index_]);
98 } 92 }
99 93
100 begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_); 94 begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_);
101 ScheduleBeginFrameDeadline(); 95 ScheduleBeginFrameDeadline();
102 } 96 }
103 97
104 void DisplayScheduler::OutputSurfaceLost() { 98 void DisplayScheduler::OutputSurfaceLost() {
105 TRACE_EVENT0("cc", "DisplayScheduler::OutputSurfaceLost"); 99 TRACE_EVENT0("cc", "DisplayScheduler::OutputSurfaceLost");
106 output_surface_lost_ = true; 100 output_surface_lost_ = true;
107 begin_frame_source_->SetNeedsBeginFrames(false); 101 begin_frame_source_->SetNeedsBeginFrames(false);
108 ScheduleBeginFrameDeadline(); 102 ScheduleBeginFrameDeadline();
109 } 103 }
110 104
111 void DisplayScheduler::DrawAndSwap() { 105 void DisplayScheduler::DrawAndSwap() {
112 TRACE_EVENT0("cc", "DisplayScheduler::DrawAndSwap"); 106 TRACE_EVENT0("cc", "DisplayScheduler::DrawAndSwap");
113 DCHECK_LT(pending_swaps_, max_pending_swaps_); 107 DCHECK_LT(pending_swaps_, max_pending_swaps_);
114 DCHECK(!output_surface_lost_); 108 DCHECK(!output_surface_lost_);
115 109
116 bool success = client_->DrawAndSwap(); 110 bool success = client_->DrawAndSwap();
117 if (!success) 111 if (!success)
118 return; 112 return;
119 113
120 UpdateActiveSurfaces(); 114 child_surface_ids_to_expect_damage_from_ =
115 base::STLSetIntersection<std::vector<SurfaceId>>(
116 child_surface_ids_damaged_, child_surface_ids_damaged_prev_);
121 117
122 // Update state regarding what needs to be drawn. 118 child_surface_ids_damaged_prev_.swap(child_surface_ids_damaged_);
119 child_surface_ids_damaged_.clear();
120
123 needs_draw_ = false; 121 needs_draw_ = false;
122 all_active_child_surfaces_ready_to_draw_ =
123 child_surface_ids_to_expect_damage_from_.empty();
124
125 expect_damage_from_root_surface_ = root_surface_damaged_;
124 root_surface_damaged_ = false; 126 root_surface_damaged_ = false;
125 child_surface_ids_damaged_.clear();
126 } 127 }
127 128
128 bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { 129 bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
129 base::TimeTicks now = base::TimeTicks::Now(); 130 base::TimeTicks now = base::TimeTicks::Now();
130 TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(), 131 TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(),
131 "now", now); 132 "now", now);
132 133
133 // If we get another BeginFrame before the previous deadline, 134 // If we get another BeginFrame before the previous deadline,
134 // synchronously trigger the previous deadline before progressing. 135 // synchronously trigger the previous deadline before progressing.
135 if (inside_begin_frame_deadline_interval_) { 136 if (inside_begin_frame_deadline_interval_) {
(...skipping 28 matching lines...) Expand all
164 current_begin_frame_args_.interval; 165 current_begin_frame_args_.interval;
165 } 166 }
166 167
167 if (root_surface_resources_locked_) { 168 if (root_surface_resources_locked_) {
168 TRACE_EVENT_INSTANT0("cc", "Root surface resources locked", 169 TRACE_EVENT_INSTANT0("cc", "Root surface resources locked",
169 TRACE_EVENT_SCOPE_THREAD); 170 TRACE_EVENT_SCOPE_THREAD);
170 return current_begin_frame_args_.frame_time + 171 return current_begin_frame_args_.frame_time +
171 current_begin_frame_args_.interval; 172 current_begin_frame_args_.interval;
172 } 173 }
173 174
174 bool root_ready_to_draw = !root_surface_active_ || root_surface_damaged_; 175 bool root_ready_to_draw =
176 !expect_damage_from_root_surface_ || root_surface_damaged_;
175 177
176 if (child_surfaces_ready_to_draw_ && root_ready_to_draw) { 178 if (all_active_child_surfaces_ready_to_draw_ && root_ready_to_draw) {
177 TRACE_EVENT_INSTANT0("cc", "All active surfaces ready", 179 TRACE_EVENT_INSTANT0("cc", "All active surfaces ready",
178 TRACE_EVENT_SCOPE_THREAD); 180 TRACE_EVENT_SCOPE_THREAD);
179 return base::TimeTicks(); 181 return base::TimeTicks();
180 } 182 }
181 183
182 // TODO(mithro): Be smarter about resize deadlines. 184 // TODO(mithro): Be smarter about resize deadlines.
183 if (expecting_root_surface_damage_because_of_resize_) { 185 if (expecting_root_surface_damage_because_of_resize_) {
184 TRACE_EVENT_INSTANT0("cc", "Entire display damaged", 186 TRACE_EVENT_INSTANT0("cc", "Entire display damaged",
185 TRACE_EVENT_SCOPE_THREAD); 187 TRACE_EVENT_SCOPE_THREAD);
186 return current_begin_frame_args_.frame_time + 188 return current_begin_frame_args_.frame_time +
187 current_begin_frame_args_.interval; 189 current_begin_frame_args_.interval;
188 } 190 }
189 191
190 // Use an earlier deadline if we are only waiting for the root surface 192 // Use an earlier deadline if we are only waiting for the root surface
191 // in case our expect_damage_from_root_surface heuristic is incorrect. 193 // in case our expect_damage_from_root_surface heuristic is incorrect.
192 // TODO(mithro): Replace this with SetNeedsBeginFrame and SwapAbort 194 // TODO(mithro): Replace this with SetNeedsBeginFrame and SwapAbort
193 // logic. 195 // logic.
194 if (child_surfaces_ready_to_draw_ && root_surface_active_) { 196 if (all_active_child_surfaces_ready_to_draw_ &&
197 expect_damage_from_root_surface_) {
195 TRACE_EVENT_INSTANT0("cc", "Waiting for damage from root surface", 198 TRACE_EVENT_INSTANT0("cc", "Waiting for damage from root surface",
196 TRACE_EVENT_SCOPE_THREAD); 199 TRACE_EVENT_SCOPE_THREAD);
197 // This adjusts the deadline by DefaultEstimatedParentDrawTime for 200 // This adjusts the deadline by DefaultEstimatedParentDrawTime for
198 // a second time. The first one represented the Surfaces draw to display 201 // a second time. The first one represented the Surfaces draw to display
199 // latency. This one represents root surface commit+raster+draw latency. 202 // latency. This one represents root surface commit+raster+draw latency.
200 // We treat the root surface differently since it lives on the same thread 203 // We treat the root surface differently since it lives on the same thread
201 // as Surfaces and waiting for it too long may push out the Surfaces draw. 204 // as Surfaces and waiting for it too long may push out the Surfaces draw.
202 // If we also assume the root surface is fast to start a commit after the 205 // If we also assume the root surface is fast to start a commit after the
203 // beginning of a frame, it'll have a chance to lock its resources, which 206 // beginning of a frame, it'll have a chance to lock its resources, which
204 // will cause us to wait for it to unlock its resources above. 207 // will cause us to wait for it to unlock its resources above.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 begin_frame_deadline_task_.callback(), delta); 248 begin_frame_deadline_task_.callback(), delta);
246 TRACE_EVENT2("cc", "Using new deadline", "delta", delta.ToInternalValue(), 249 TRACE_EVENT2("cc", "Using new deadline", "delta", delta.ToInternalValue(),
247 "desired_deadline", desired_deadline); 250 "desired_deadline", desired_deadline);
248 } 251 }
249 252
250 void DisplayScheduler::AttemptDrawAndSwap() { 253 void DisplayScheduler::AttemptDrawAndSwap() {
251 inside_begin_frame_deadline_interval_ = false; 254 inside_begin_frame_deadline_interval_ = false;
252 begin_frame_deadline_task_.Cancel(); 255 begin_frame_deadline_task_.Cancel();
253 begin_frame_deadline_task_time_ = base::TimeTicks(); 256 begin_frame_deadline_task_time_ = base::TimeTicks();
254 257
255 bool stay_active = 258 if (needs_draw_ && !output_surface_lost_) {
256 !output_surface_lost_ && 259 if (pending_swaps_ < max_pending_swaps_ && !root_surface_resources_locked_)
257 (needs_draw_ || root_surface_active_ || 260 DrawAndSwap();
258 !active_child_surface_ids_[active_child_surface_ids_index_].empty()); 261 } else {
262 // We are going idle, so reset expectations.
263 child_surface_ids_to_expect_damage_from_.clear();
264 child_surface_ids_damaged_prev_.clear();
265 child_surface_ids_damaged_.clear();
266 all_active_child_surfaces_ready_to_draw_ = true;
267 expect_damage_from_root_surface_ = false;
259 268
260 if (!stay_active) {
261 // We are going idle, so reset expectations.
262 root_surface_active_ = false;
263 child_surfaces_ready_to_draw_ = true;
264 active_child_surface_ids_index_ = 0;
265 for (int i = 0; i < kNumFramesSurfaceIsActive; i++)
266 active_child_surface_ids_[i].clear();
267 begin_frame_source_->SetNeedsBeginFrames(false); 269 begin_frame_source_->SetNeedsBeginFrames(false);
268 return;
269 } 270 }
270
271 if (!needs_draw_) {
272 // In order to properly go idle, make sure to update expectations that
273 // will cause |stay_active| to go false even if we have nothing to draw.
274 // Verify no child surfaces are currently damaged, since
275 // UpdateSurfaceDamageExpectatations will clear that list.
276 DCHECK(child_surface_ids_damaged_.empty());
277 DCHECK(!root_surface_damaged_);
278 UpdateActiveSurfaces();
279 return;
280 }
281
282 if (pending_swaps_ >= max_pending_swaps_ || root_surface_resources_locked_)
283 return;
284
285 DrawAndSwap();
286 } 271 }
287 272
288 void DisplayScheduler::OnBeginFrameDeadline() { 273 void DisplayScheduler::OnBeginFrameDeadline() {
289 TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline"); 274 TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline");
290 275
291 AttemptDrawAndSwap(); 276 AttemptDrawAndSwap();
292 begin_frame_source_->DidFinishFrame(0); 277 begin_frame_source_->DidFinishFrame(0);
293 } 278 }
294 279
295 void DisplayScheduler::DidSwapBuffers() { 280 void DisplayScheduler::DidSwapBuffers() {
296 pending_swaps_++; 281 pending_swaps_++;
297 TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffers", "pending_frames", 282 TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffers", "pending_frames",
298 pending_swaps_); 283 pending_swaps_);
299 } 284 }
300 285
301 void DisplayScheduler::DidSwapBuffersComplete() { 286 void DisplayScheduler::DidSwapBuffersComplete() {
302 pending_swaps_--; 287 pending_swaps_--;
303 TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffersComplete", 288 TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffersComplete",
304 "pending_frames", pending_swaps_); 289 "pending_frames", pending_swaps_);
305 ScheduleBeginFrameDeadline(); 290 ScheduleBeginFrameDeadline();
306 } 291 }
307 292
308 void DisplayScheduler::UpdateActiveSurfaces() {
309 root_surface_active_ = root_surface_damaged_;
310 active_child_surface_ids_[active_child_surface_ids_index_].clear();
311 active_child_surface_ids_index_ =
312 (active_child_surface_ids_index_ + 1) % kNumFramesSurfaceIsActive;
313 child_surfaces_ready_to_draw_ =
314 active_child_surface_ids_[active_child_surface_ids_index_].empty();
315 }
316
317 } // namespace cc 293 } // namespace cc
OLDNEW
« no previous file with comments | « cc/surfaces/display_scheduler.h ('k') | cc/surfaces/display_scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698