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

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

Issue 1068743003: Revert of Add DisplayScheduler for Surfaces (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "cc/surfaces/display_scheduler.h"
6
7 #include <vector>
8
9 #include "base/stl_util.h"
10 #include "base/trace_event/trace_event.h"
11 #include "cc/output/output_surface.h"
12 #include "ui/gfx/frame_time.h"
13
14 namespace cc {
15
16 DisplayScheduler::DisplayScheduler(
17 DisplaySchedulerClient* client,
18 BeginFrameSource* begin_frame_source,
19 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
20 int max_pending_swaps)
21 : client_(client),
22 begin_frame_source_(begin_frame_source),
23 task_runner_(task_runner),
24 output_surface_lost_(false),
25 resources_locked_by_browser_(true),
26 inside_begin_frame_deadline_interval_(false),
27 needs_draw_(false),
28 entire_display_damaged_(false),
29 all_active_surfaces_ready_to_draw_(false),
30 pending_swaps_(0),
31 max_pending_swaps_(max_pending_swaps),
32 weak_ptr_factory_(this) {
33 begin_frame_source_->AddObserver(this);
34 begin_frame_deadline_closure_ = base::Bind(
35 &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr());
36 }
37
38 DisplayScheduler::~DisplayScheduler() {
39 begin_frame_source_->RemoveObserver(this);
40 }
41
42 // If we try to draw when the Browser has locked it's resources, the
43 // draw will fail.
44 void DisplayScheduler::SetResourcesLockedByBrowser(bool locked) {
45 resources_locked_by_browser_ = locked;
46 ScheduleBeginFrameDeadline();
47 }
48
49 // Notification that there was a resize or the root surface changed and
50 // that we should just draw immediately.
51 void DisplayScheduler::EntireDisplayDamaged() {
52 TRACE_EVENT0("cc", "DisplayScheduler::EntireDisplayDamaged");
53 needs_draw_ = true;
54 entire_display_damaged_ = true;
55
56 begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_);
57 ScheduleBeginFrameDeadline();
58 }
59
60 // Indicates that there was damage to one of the surfaces.
61 // Has some logic to wait for multiple active surfaces before
62 // triggering the deadline.
63 void DisplayScheduler::SurfaceDamaged(SurfaceId surface_id) {
64 TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id",
65 surface_id.id);
66
67 needs_draw_ = true;
68
69 surface_ids_damaged_.insert(surface_id);
70
71 // TODO(mithro): Use hints from SetNeedsBeginFrames.
72 all_active_surfaces_ready_to_draw_ = base::STLIncludes(
73 surface_ids_damaged_, surface_ids_to_expect_damage_from_);
74
75 begin_frame_source_->SetNeedsBeginFrames(!output_surface_lost_);
76 ScheduleBeginFrameDeadline();
77 }
78
79 void DisplayScheduler::OutputSurfaceLost() {
80 TRACE_EVENT0("cc", "DisplayScheduler::OutputSurfaceLost");
81 output_surface_lost_ = true;
82 begin_frame_source_->SetNeedsBeginFrames(false);
83 ScheduleBeginFrameDeadline();
84 }
85
86 void DisplayScheduler::DrawAndSwap() {
87 TRACE_EVENT0("cc", "DisplayScheduler::DrawAndSwap");
88 DCHECK_LT(pending_swaps_, max_pending_swaps_);
89 DCHECK(!output_surface_lost_);
90
91 bool success = client_->DrawAndSwap();
92 if (!success)
93 return;
94
95 needs_draw_ = false;
96 entire_display_damaged_ = false;
97 all_active_surfaces_ready_to_draw_ = false;
98
99 surface_ids_to_expect_damage_from_ =
100 base::STLSetIntersection<std::vector<SurfaceId>>(
101 surface_ids_damaged_, surface_ids_damaged_prev_);
102
103 surface_ids_damaged_prev_.swap(surface_ids_damaged_);
104 surface_ids_damaged_.clear();
105 }
106
107 bool DisplayScheduler::OnBeginFrameMixInDelegate(const BeginFrameArgs& args) {
108 TRACE_EVENT1("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue());
109
110 // If we get another BeginFrame before the previous deadline,
111 // synchronously trigger the previous deadline before progressing.
112 if (inside_begin_frame_deadline_interval_) {
113 OnBeginFrameDeadline();
114 }
115
116 // Schedule the deadline.
117 current_begin_frame_args_ = args;
118 current_begin_frame_args_.deadline -=
119 BeginFrameArgs::DefaultEstimatedParentDrawTime();
120 inside_begin_frame_deadline_interval_ = true;
121 ScheduleBeginFrameDeadline();
122
123 return true;
124 }
125
126 base::TimeTicks DisplayScheduler::DesiredBeginFrameDeadlineTime() {
127 if (output_surface_lost_) {
128 TRACE_EVENT_INSTANT0("cc", "Lost output surface", TRACE_EVENT_SCOPE_THREAD);
129 return base::TimeTicks();
130 }
131
132 if (!needs_draw_) {
133 TRACE_EVENT_INSTANT0("cc", "No damage yet", TRACE_EVENT_SCOPE_THREAD);
134 return current_begin_frame_args_.frame_time +
135 current_begin_frame_args_.interval;
136 }
137
138 if (pending_swaps_ >= max_pending_swaps_) {
139 TRACE_EVENT_INSTANT0("cc", "Swap throttled", TRACE_EVENT_SCOPE_THREAD);
140 return current_begin_frame_args_.frame_time +
141 current_begin_frame_args_.interval;
142 }
143
144 if (resources_locked_by_browser_) {
145 TRACE_EVENT_INSTANT0("cc", "Resources locked by Browser",
146 TRACE_EVENT_SCOPE_THREAD);
147 return current_begin_frame_args_.frame_time +
148 current_begin_frame_args_.interval;
149 }
150
151 // TODO(mithro): Be smarter about resize deadlines.
152 if (entire_display_damaged_) {
153 TRACE_EVENT_INSTANT0("cc", "Entire display damaged",
154 TRACE_EVENT_SCOPE_THREAD);
155 return base::TimeTicks();
156 }
157
158 if (all_active_surfaces_ready_to_draw_) {
159 TRACE_EVENT_INSTANT0("cc", "Active surfaces ready",
160 TRACE_EVENT_SCOPE_THREAD);
161 return base::TimeTicks();
162 }
163
164 TRACE_EVENT_INSTANT0("cc", "More damage expected soon",
165 TRACE_EVENT_SCOPE_THREAD);
166 return current_begin_frame_args_.deadline;
167 }
168
169 void DisplayScheduler::ScheduleBeginFrameDeadline() {
170 TRACE_EVENT0("cc", "DisplayScheduler::ScheduleBeginFrameDeadline");
171
172 // We need to wait for the next BeginFrame before scheduling a deadline.
173 if (!inside_begin_frame_deadline_interval_) {
174 TRACE_EVENT_INSTANT0("cc", "Waiting for next BeginFrame",
175 TRACE_EVENT_SCOPE_THREAD);
176 DCHECK(begin_frame_deadline_task_.IsCancelled());
177 return;
178 }
179
180 // Determine the deadline we want to use.
181 base::TimeTicks desired_deadline = DesiredBeginFrameDeadlineTime();
182
183 // Avoid re-scheduling the deadline if it's already correctly scheduled.
184 if (!begin_frame_deadline_task_.IsCancelled() &&
185 desired_deadline == begin_frame_deadline_task_time_)
186 return;
187
188 // Schedule the deadline.
189 begin_frame_deadline_task_time_ = desired_deadline;
190 begin_frame_deadline_task_.Cancel();
191 begin_frame_deadline_task_.Reset(begin_frame_deadline_closure_);
192
193 base::TimeDelta delta =
194 std::max(base::TimeDelta(), desired_deadline - base::TimeTicks::Now());
195 task_runner_->PostDelayedTask(FROM_HERE,
196 begin_frame_deadline_task_.callback(), delta);
197 }
198
199 void DisplayScheduler::OnBeginFrameDeadline() {
200 TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline");
201 inside_begin_frame_deadline_interval_ = false;
202 begin_frame_deadline_task_.Cancel();
203 begin_frame_deadline_task_time_ = base::TimeTicks();
204
205 if (needs_draw_ && !output_surface_lost_) {
206 if (pending_swaps_ < max_pending_swaps_ && !resources_locked_by_browser_)
207 DrawAndSwap();
208 } else {
209 begin_frame_source_->SetNeedsBeginFrames(false);
210 }
211
212 begin_frame_source_->DidFinishFrame(0);
213 }
214
215 void DisplayScheduler::DidSwapBuffers() {
216 pending_swaps_++;
217 TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffers", "pending_frames",
218 pending_swaps_);
219 }
220
221 void DisplayScheduler::DidSwapBuffersComplete() {
222 pending_swaps_--;
223 TRACE_EVENT1("cc", "DisplayScheduler::DidSwapBuffersComplete",
224 "pending_frames", pending_swaps_);
225 ScheduleBeginFrameDeadline();
226 }
227
228 } // 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