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

Side by Side Diff: cc/scheduler/scheduler.cc

Issue 23796002: cc: Implement deadine scheduling disabled by default (Closed) Base URL: http://git.chromium.org/chromium/src.git@schedReadback4
Patch Set: Created 7 years, 3 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
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 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/scheduler/scheduler.h" 5 #include "cc/scheduler/scheduler.h"
6 6
7 #include <algorithm>
7 #include "base/auto_reset.h" 8 #include "base/auto_reset.h"
8 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
9 #include "base/logging.h" 10 #include "base/logging.h"
10 #include "cc/debug/traced_value.h" 11 #include "cc/debug/traced_value.h"
11 12
12 namespace cc { 13 namespace cc {
13 14
14 Scheduler::Scheduler(SchedulerClient* client, 15 Scheduler::Scheduler(SchedulerClient* client,
15 const SchedulerSettings& scheduler_settings) 16 const SchedulerSettings& scheduler_settings)
16 : settings_(scheduler_settings), 17 : settings_(scheduler_settings),
17 client_(client), 18 client_(client),
18 weak_factory_(this), 19 weak_factory_(this),
19 last_set_needs_begin_frame_(false), 20 last_set_needs_begin_frame_(false),
20 has_pending_begin_frame_(false), 21 has_pending_begin_frame_(false),
21 safe_to_expect_begin_frame_(false), 22 safe_to_expect_begin_frame_(
23 !scheduler_settings.use_begin_frame_workaround_for_crbug_249806),
22 state_machine_(scheduler_settings), 24 state_machine_(scheduler_settings),
23 inside_process_scheduled_actions_(false) { 25 inside_process_scheduled_actions_(false) {
24 DCHECK(client_); 26 DCHECK(client_);
25 DCHECK(!state_machine_.BeginFrameNeededToDrawByImplThread()); 27 DCHECK(!state_machine_.BeginFrameNeededByImplThread());
26 } 28 }
27 29
28 Scheduler::~Scheduler() { 30 Scheduler::~Scheduler() {
29 client_->SetNeedsBeginFrameOnImplThread(false); 31 client_->SetNeedsBeginFrameOnImplThread(false);
30 } 32 }
31 33
32 void Scheduler::SetCanStart() { 34 void Scheduler::SetCanStart() {
33 state_machine_.SetCanStart(); 35 state_machine_.SetCanStart();
34 ProcessScheduledActions(); 36 ProcessScheduledActions();
35 } 37 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 74
73 void Scheduler::SetMainThreadNeedsLayerTextures() { 75 void Scheduler::SetMainThreadNeedsLayerTextures() {
74 state_machine_.SetMainThreadNeedsLayerTextures(); 76 state_machine_.SetMainThreadNeedsLayerTextures();
75 ProcessScheduledActions(); 77 ProcessScheduledActions();
76 } 78 }
77 79
78 void Scheduler::FinishCommit() { 80 void Scheduler::FinishCommit() {
79 TRACE_EVENT0("cc", "Scheduler::FinishCommit"); 81 TRACE_EVENT0("cc", "Scheduler::FinishCommit");
80 state_machine_.FinishCommit(); 82 state_machine_.FinishCommit();
81 ProcessScheduledActions(); 83 ProcessScheduledActions();
84
85 if (state_machine_.ShouldTriggerBeginFrameDeadlineEarly())
86 PostBeginFrameDeadline(base::TimeTicks());
82 } 87 }
83 88
84 void Scheduler::BeginFrameAbortedByMainThread(bool did_handle) { 89 void Scheduler::BeginFrameAbortedByMainThread(bool did_handle) {
85 TRACE_EVENT0("cc", "Scheduler::BeginFrameAbortedByMainThread"); 90 TRACE_EVENT0("cc", "Scheduler::BeginFrameAbortedByMainThread");
86 state_machine_.BeginFrameAbortedByMainThread(did_handle); 91 state_machine_.BeginFrameAbortedByMainThread(did_handle);
87 ProcessScheduledActions(); 92 ProcessScheduledActions();
88 } 93 }
89 94
90 void Scheduler::DidLoseOutputSurface() { 95 void Scheduler::DidLoseOutputSurface() {
91 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 96 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
97 begin_frame_deadline_closure_.Cancel();
98 has_pending_begin_frame_ = false;
92 state_machine_.DidLoseOutputSurface(); 99 state_machine_.DidLoseOutputSurface();
93 ProcessScheduledActions(); 100 ProcessScheduledActions();
94 } 101 }
95 102
96 void Scheduler::DidCreateAndInitializeOutputSurface() { 103 void Scheduler::DidCreateAndInitializeOutputSurface() {
97 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); 104 TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
98 state_machine_.DidCreateAndInitializeOutputSurface(); 105 state_machine_.DidCreateAndInitializeOutputSurface();
106 begin_frame_deadline_closure_.Cancel();
99 has_pending_begin_frame_ = false; 107 has_pending_begin_frame_ = false;
100 last_set_needs_begin_frame_ = false; 108 last_set_needs_begin_frame_ = false;
101 safe_to_expect_begin_frame_ = false; 109 safe_to_expect_begin_frame_ =
110 !settings_.use_begin_frame_workaround_for_crbug_249806;
102 ProcessScheduledActions(); 111 ProcessScheduledActions();
103 } 112 }
104 113
105 base::TimeTicks Scheduler::AnticipatedDrawTime() { 114 base::TimeTicks Scheduler::AnticipatedDrawTime() {
106 TRACE_EVENT0("cc", "Scheduler::AnticipatedDrawTime"); 115 TRACE_EVENT0("cc", "Scheduler::AnticipatedDrawTime");
107 116
108 if (!last_set_needs_begin_frame_ || 117 if (!last_set_needs_begin_frame_ ||
109 last_begin_frame_args_.interval <= base::TimeDelta()) 118 last_begin_frame_args_.interval <= base::TimeDelta())
110 return base::TimeTicks(); 119 return base::TimeTicks();
111 120
112 // TODO(brianderson): Express this in terms of the deadline.
113 base::TimeTicks now = base::TimeTicks::Now(); 121 base::TimeTicks now = base::TimeTicks::Now();
114 int64 intervals = 1 + ((now - last_begin_frame_args_.frame_time) / 122 base::TimeTicks timebase = std::max(last_begin_frame_args_.frame_time,
115 last_begin_frame_args_.interval); 123 last_begin_frame_args_.deadline);
116 return last_begin_frame_args_.frame_time + 124 int64 intervals = 1 + ((now - timebase) / last_begin_frame_args_.interval);
117 (last_begin_frame_args_.interval * intervals); 125 return timebase + (last_begin_frame_args_.interval * intervals);
118 } 126 }
119 127
120 base::TimeTicks Scheduler::LastBeginFrameOnImplThreadTime() { 128 base::TimeTicks Scheduler::LastBeginFrameOnImplThreadTime() {
121 return last_begin_frame_args_.frame_time; 129 return last_begin_frame_args_.frame_time;
122 } 130 }
123 131
124 void Scheduler::SetupNextBeginFrameIfNeeded() { 132 void Scheduler::SetupNextBeginFrameIfNeeded() {
125 bool needs_begin_frame_to_draw = 133 bool needs_begin_frame_to_draw =
126 state_machine_.BeginFrameNeededToDrawByImplThread(); 134 state_machine_.BeginFrameNeededToDrawByImplThread();
127 // We want to avoid proactive begin frames with the synchronous compositor
128 // because every SetNeedsBeginFrame will force a redraw.
129 bool proactive_begin_frame_wanted = 135 bool proactive_begin_frame_wanted =
130 state_machine_.ProactiveBeginFrameWantedByImplThread() && 136 state_machine_.ProactiveBeginFrameWantedByImplThread();
131 !settings_.using_synchronous_renderer_compositor && 137
132 settings_.throttle_frame_production; 138 // We want to avoid proactive begin frames with the synchronous
133 bool needs_begin_frame = needs_begin_frame_to_draw || 139 // compositor because every SetNeedsBeginFrame will force a redraw.
134 proactive_begin_frame_wanted; 140 bool needs_begin_frame =
135 bool immediate_disables_needed = 141 needs_begin_frame_to_draw || proactive_begin_frame_wanted;
136 settings_.using_synchronous_renderer_compositor; 142
143 bool should_call_set_needs_begin_frame =
144 // The synchronous renderer compositor needs immediate enables/disables.
145 (settings_.using_synchronous_renderer_compositor &&
146 needs_begin_frame != last_set_needs_begin_frame_) ||
147 // Always request the BeginFrame immediately if it wasn't needed before.
148 (needs_begin_frame && !last_set_needs_begin_frame_) ||
149 // Only disable the BeginFrame after a BeginFrame where we didn't swap.
150 (!needs_begin_frame && last_set_needs_begin_frame_ &&
151 has_pending_begin_frame_ && !state_machine_.InsideBeginFrame()) ||
152 // We did not draw and swap this BeginFrame,
153 // so we need to explicitly request another BeginFrame.
154 (needs_begin_frame && has_pending_begin_frame_ &&
155 !state_machine_.InsideBeginFrame());
137 156
138 if (needs_begin_frame_to_draw) 157 if (needs_begin_frame_to_draw)
139 safe_to_expect_begin_frame_ = true; 158 safe_to_expect_begin_frame_ = true;
140 159
141 // Determine if we need BeginFrame notifications. 160 if (should_call_set_needs_begin_frame) {
142 // If we do, always request the BeginFrame immediately.
143 // If not, only disable on the next BeginFrame to avoid unnecessary toggles.
144 // The synchronous renderer compositor requires immediate disables though.
145 if ((needs_begin_frame ||
146 state_machine_.inside_begin_frame() ||
147 immediate_disables_needed) &&
148 (needs_begin_frame != last_set_needs_begin_frame_)) {
149 has_pending_begin_frame_ = false; 161 has_pending_begin_frame_ = false;
150 client_->SetNeedsBeginFrameOnImplThread(needs_begin_frame); 162 client_->SetNeedsBeginFrameOnImplThread(needs_begin_frame);
151 if (safe_to_expect_begin_frame_) 163 if (safe_to_expect_begin_frame_)
152 last_set_needs_begin_frame_ = needs_begin_frame; 164 last_set_needs_begin_frame_ = needs_begin_frame;
153 } 165 }
154
155 // Request another BeginFrame if we haven't drawn for now until we have
156 // deadlines implemented.
157 if (state_machine_.inside_begin_frame() && has_pending_begin_frame_) {
158 has_pending_begin_frame_ = false;
159 client_->SetNeedsBeginFrameOnImplThread(true);
160 return;
161 }
162 } 166 }
163 167
164 void Scheduler::BeginFrame(const BeginFrameArgs& args) { 168 void Scheduler::BeginFrame(const BeginFrameArgs& args) {
165 TRACE_EVENT0("cc", "Scheduler::BeginFrame"); 169 TRACE_EVENT0("cc", "Scheduler::BeginFrame");
166 DCHECK(!has_pending_begin_frame_); 170 DCHECK(!has_pending_begin_frame_);
167 has_pending_begin_frame_ = true; 171 has_pending_begin_frame_ = true;
168 safe_to_expect_begin_frame_ = true; 172 safe_to_expect_begin_frame_ = true;
169 last_begin_frame_args_ = args; 173 last_begin_frame_args_ = args;
170 state_machine_.DidEnterBeginFrame(args); 174 last_begin_frame_args_.deadline -= client_->DrawDurationEstimate();
175 state_machine_.OnBeginFrame(last_begin_frame_args_);
171 ProcessScheduledActions(); 176 ProcessScheduledActions();
172 state_machine_.DidLeaveBeginFrame(); 177
178 if (settings_.using_synchronous_renderer_compositor) {
179 // The synchronous renderer compositor has to make it's GL calls
180 // within this call to BeginFrame.
181 // TODO(brianderson): Have the OutputSurface initiate the deadline tasks
182 // so the sychronous renderer compoistor can take advantage of splitting
183 // up the BeginFrame and deadline as well.
184 OnBeginFrameDeadline();
185 } else if (!settings_.deadline_scheduling_enabled) {
186 // We emulate the old non-deadline scheduler here by posting the
187 // deadline task without any delay.
188 PostBeginFrameDeadline(base::TimeTicks());
189 } else if (state_machine_.ShouldTriggerBeginFrameDeadlineEarly()) {
190 // We are ready to draw a new active tree immediately.
191 PostBeginFrameDeadline(base::TimeTicks());
192 } else if (state_machine_.needs_redraw()) {
193 // We have an animation or fast input path on the impl thread that wants
194 // to draw, so don't wait too long for a new active tree.
195 PostBeginFrameDeadline(last_begin_frame_args_.deadline);
196 } else {
197 // The impl thread doesn't have anything it wants to draw and we are just
198 // waiting for a new active tree, so post the deadline for the next
199 // expected BeginFrame start.
200 // TODO(brianderson): Handle long deadlines (that are past the next frame's
201 // frame time) properly instead of using this hack.
202 PostBeginFrameDeadline(last_begin_frame_args_.frame_time +
203 last_begin_frame_args_.interval);
204 }
205 }
206
207 void Scheduler::PostBeginFrameDeadline(base::TimeTicks deadline) {
208 begin_frame_deadline_closure_.Cancel();
209 begin_frame_deadline_closure_.Reset(
210 base::Bind(&Scheduler::OnBeginFrameDeadline, weak_factory_.GetWeakPtr()));
211 client_->PostBeginFrameDeadline(begin_frame_deadline_closure_.callback(),
212 deadline);
213 }
214
215 void Scheduler::OnBeginFrameDeadline() {
216 TRACE_EVENT0("cc", "Scheduler::OnBeginFrameDeadline");
217 begin_frame_deadline_closure_.Cancel();
218 state_machine_.OnBeginFrameDeadline();
219 ProcessScheduledActions();
220 client_->DidBeginFrameDeadlineOnImplThread();
173 } 221 }
174 222
175 void Scheduler::DrawAndSwapIfPossible() { 223 void Scheduler::DrawAndSwapIfPossible() {
176 DrawSwapReadbackResult result = 224 DrawSwapReadbackResult result =
177 client_->ScheduledActionDrawAndSwapIfPossible(); 225 client_->ScheduledActionDrawAndSwapIfPossible();
178 state_machine_.DidDrawIfPossibleCompleted(result.did_draw); 226 state_machine_.DidDrawIfPossibleCompleted(result.did_draw);
179 if (result.did_swap) 227 if (result.did_swap)
180 has_pending_begin_frame_ = false; 228 has_pending_begin_frame_ = false;
181 } 229 }
182 230
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 break; 281 break;
234 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 282 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
235 client_->ScheduledActionBeginOutputSurfaceCreation(); 283 client_->ScheduledActionBeginOutputSurfaceCreation();
236 break; 284 break;
237 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: 285 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
238 client_->ScheduledActionAcquireLayerTexturesForMainThread(); 286 client_->ScheduledActionAcquireLayerTexturesForMainThread();
239 break; 287 break;
240 } 288 }
241 } while (action != SchedulerStateMachine::ACTION_NONE); 289 } while (action != SchedulerStateMachine::ACTION_NONE);
242 290
291 state_machine_.AdvanceBeginFrameStateWhenNoActionsRemain();
243 SetupNextBeginFrameIfNeeded(); 292 SetupNextBeginFrameIfNeeded();
244 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); 293 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
245 } 294 }
246 295
247 bool Scheduler::WillDrawIfNeeded() const { 296 bool Scheduler::WillDrawIfNeeded() const {
248 return !state_machine_.PendingDrawsShouldBeAborted(); 297 return !state_machine_.PendingDrawsShouldBeAborted();
249 } 298 }
250 299
251 } // namespace cc 300 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698