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

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

Issue 16871016: cc: Use BeginFrameArgs (Closed) Base URL: http://git.chromium.org/chromium/src.git@bfargs2
Patch Set: fix some tests; needs rebase; Created 7 years, 5 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/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.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 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 "base/strings/stringprintf.h"
8 #include <algorithm>
7 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
8 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event.h"
9 #include "base/logging.h" 11 #include "base/logging.h"
10 12
11 namespace cc { 13 namespace cc {
12 14
13 Scheduler::Scheduler(SchedulerClient* client, 15 Scheduler::Scheduler(SchedulerClient* client,
14 const SchedulerSettings& scheduler_settings) 16 const SchedulerSettings& scheduler_settings)
15 : settings_(scheduler_settings), 17 : settings_(scheduler_settings),
16 client_(client), 18 client_(client),
(...skipping 19 matching lines...) Expand all
36 void Scheduler::SetVisible(bool visible) { 38 void Scheduler::SetVisible(bool visible) {
37 state_machine_.SetVisible(visible); 39 state_machine_.SetVisible(visible);
38 ProcessScheduledActions(); 40 ProcessScheduledActions();
39 } 41 }
40 42
41 void Scheduler::SetCanDraw(bool can_draw) { 43 void Scheduler::SetCanDraw(bool can_draw) {
42 state_machine_.SetCanDraw(can_draw); 44 state_machine_.SetCanDraw(can_draw);
43 ProcessScheduledActions(); 45 ProcessScheduledActions();
44 } 46 }
45 47
46 void Scheduler::SetHasPendingTree(bool has_pending_tree) { 48 void Scheduler::SetHasTrees(bool has_pending_tree, bool active_tree_is_null) {
47 state_machine_.SetHasPendingTree(has_pending_tree); 49 state_machine_.SetHasTrees(has_pending_tree, active_tree_is_null);
48 ProcessScheduledActions(); 50 ProcessScheduledActions();
51
52 if (state_machine_.ShouldTriggerBeginFrameDeadlineEarly())
53 PostBeginFrameDeadline(base::TimeTicks());
49 } 54 }
50 55
51 void Scheduler::SetNeedsCommit() { 56 void Scheduler::SetNeedsCommit() {
52 state_machine_.SetNeedsCommit(); 57 state_machine_.SetNeedsCommit();
53 ProcessScheduledActions(); 58 ProcessScheduledActions();
54 } 59 }
55 60
56 void Scheduler::SetNeedsForcedCommit() { 61 void Scheduler::SetNeedsForcedCommit() {
57 state_machine_.SetNeedsCommit(); 62 state_machine_.SetNeedsCommit();
58 state_machine_.SetNeedsForcedCommit(); 63 state_machine_.SetNeedsForcedCommit();
(...skipping 17 matching lines...) Expand all
76 81
77 void Scheduler::SetMainThreadNeedsLayerTextures() { 82 void Scheduler::SetMainThreadNeedsLayerTextures() {
78 state_machine_.SetMainThreadNeedsLayerTextures(); 83 state_machine_.SetMainThreadNeedsLayerTextures();
79 ProcessScheduledActions(); 84 ProcessScheduledActions();
80 } 85 }
81 86
82 void Scheduler::FinishCommit() { 87 void Scheduler::FinishCommit() {
83 TRACE_EVENT0("cc", "Scheduler::FinishCommit"); 88 TRACE_EVENT0("cc", "Scheduler::FinishCommit");
84 state_machine_.FinishCommit(); 89 state_machine_.FinishCommit();
85 ProcessScheduledActions(); 90 ProcessScheduledActions();
91
92 if (state_machine_.ShouldTriggerBeginFrameDeadlineEarly())
93 PostBeginFrameDeadline(base::TimeTicks());
86 } 94 }
87 95
88 void Scheduler::BeginFrameAbortedByMainThread() { 96 void Scheduler::BeginFrameAbortedByMainThread() {
89 TRACE_EVENT0("cc", "Scheduler::BeginFrameAbortedByMainThread"); 97 TRACE_EVENT0("cc", "Scheduler::BeginFrameAbortedByMainThread");
90 state_machine_.BeginFrameAbortedByMainThread(); 98 state_machine_.BeginFrameAbortedByMainThread();
91 ProcessScheduledActions(); 99 ProcessScheduledActions();
92 } 100 }
93 101
94 void Scheduler::DidLoseOutputSurface() { 102 void Scheduler::DidLoseOutputSurface() {
95 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); 103 TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
(...skipping 10 matching lines...) Expand all
106 ProcessScheduledActions(); 114 ProcessScheduledActions();
107 } 115 }
108 116
109 base::TimeTicks Scheduler::AnticipatedDrawTime() { 117 base::TimeTicks Scheduler::AnticipatedDrawTime() {
110 TRACE_EVENT0("cc", "Scheduler::AnticipatedDrawTime"); 118 TRACE_EVENT0("cc", "Scheduler::AnticipatedDrawTime");
111 119
112 if (!last_set_needs_begin_frame_ || 120 if (!last_set_needs_begin_frame_ ||
113 last_begin_frame_args_.interval <= base::TimeDelta()) 121 last_begin_frame_args_.interval <= base::TimeDelta())
114 return base::TimeTicks(); 122 return base::TimeTicks();
115 123
116 // TODO(brianderson): Express this in terms of the deadline.
117 base::TimeTicks now = base::TimeTicks::Now(); 124 base::TimeTicks now = base::TimeTicks::Now();
118 int64 intervals = 1 + ((now - last_begin_frame_args_.frame_time) / 125 base::TimeTicks timebase = std::max(last_begin_frame_args_.frame_time,
119 last_begin_frame_args_.interval); 126 last_begin_frame_args_.deadline);
120 return last_begin_frame_args_.frame_time + 127 int64 intervals = 1 + ((now - timebase) / last_begin_frame_args_.interval);
121 (last_begin_frame_args_.interval * intervals); 128 return timebase + (last_begin_frame_args_.interval * intervals);
122 } 129 }
123 130
124 base::TimeTicks Scheduler::LastBeginFrameOnImplThreadTime() { 131 base::TimeTicks Scheduler::LastBeginFrameOnImplThreadTime() {
125 return last_begin_frame_args_.frame_time; 132 return last_begin_frame_args_.frame_time;
126 } 133 }
127 134
128 void Scheduler::SetupNextBeginFrameIfNeeded() { 135 void Scheduler::SetupNextBeginFrameIfNeeded() {
129 bool needs_begin_frame_to_draw = 136 bool needs_begin_frame_to_draw =
130 state_machine_.BeginFrameNeededToDrawByImplThread(); 137 state_machine_.BeginFrameNeededToDrawByImplThread();
131 // We want to avoid proactive begin frames with the synchronous compositor
132 // because every SetNeedsBeginFrame will force a redraw.
133 bool proactive_begin_frame_wanted = 138 bool proactive_begin_frame_wanted =
134 state_machine_.ProactiveBeginFrameWantedByImplThread() && 139 state_machine_.ProactiveBeginFrameWantedByImplThread();
135 !settings_.using_synchronous_renderer_compositor; 140
141 // We want to avoid proactive begin frames with the synchronous
142 // compositor because every SetNeedsBeginFrame will force a redraw.s
136 bool needs_begin_frame = needs_begin_frame_to_draw || 143 bool needs_begin_frame = needs_begin_frame_to_draw ||
137 proactive_begin_frame_wanted; 144 proactive_begin_frame_wanted;
138 bool immediate_disables_needed = 145
139 settings_.using_synchronous_renderer_compositor; 146 bool should_call_set_needs_begin_frame =
147 // The synchronous renderer compositor needs immediate enables/disables.
148 (settings_.using_synchronous_renderer_compositor &&
149 needs_begin_frame != last_set_needs_begin_frame_) ||
150 // Always request the BeginFrame immediately if it wasn't needed before.
151 (needs_begin_frame && !last_set_needs_begin_frame_) ||
152 // Only disable the BeginFrame after a BeginFrame where we didn't swap.
153 (!needs_begin_frame && last_set_needs_begin_frame_ &&
154 has_pending_begin_frame_ && !state_machine_.InsideBeginFrame()) ||
155 // We did not draw and swap this BeginFrame,
156 // so we need to explicitly request another BeginFrame.
157 (needs_begin_frame && has_pending_begin_frame_ &&
158 state_machine_.InsideBeginFrame());
140 159
141 if (needs_begin_frame_to_draw) 160 if (needs_begin_frame_to_draw)
142 safe_to_expect_begin_frame_ = true; 161 safe_to_expect_begin_frame_ = true;
143 162
144 // Determine if we need BeginFrame notifications. 163 if (should_call_set_needs_begin_frame) {
145 // If we do, always request the BeginFrame immediately.
146 // If not, only disable on the next BeginFrame to avoid unnecessary toggles.
147 // The synchronous renderer compositor requires immediate disables though.
148 if ((needs_begin_frame ||
149 state_machine_.inside_begin_frame() ||
150 immediate_disables_needed) &&
151 (needs_begin_frame != last_set_needs_begin_frame_)) {
152 has_pending_begin_frame_ = false; 164 has_pending_begin_frame_ = false;
153 client_->SetNeedsBeginFrameOnImplThread(needs_begin_frame); 165 client_->SetNeedsBeginFrameOnImplThread(needs_begin_frame);
154 if (safe_to_expect_begin_frame_) 166 if (safe_to_expect_begin_frame_)
155 last_set_needs_begin_frame_ = needs_begin_frame; 167 last_set_needs_begin_frame_ = needs_begin_frame;
156 } 168 }
157
158 // Request another BeginFrame if we haven't drawn for now until we have
159 // deadlines implemented.
160 if (state_machine_.inside_begin_frame() && has_pending_begin_frame_) {
161 has_pending_begin_frame_ = false;
162 client_->SetNeedsBeginFrameOnImplThread(true);
163 return;
164 }
165 } 169 }
166 170
167 void Scheduler::BeginFrame(const BeginFrameArgs& args) { 171 void Scheduler::BeginFrame(const BeginFrameArgs& args) {
168 TRACE_EVENT0("cc", "Scheduler::BeginFrame"); 172 TRACE_EVENT0("cc", "Scheduler::BeginFrame");
169 DCHECK(!has_pending_begin_frame_); 173 DCHECK(!has_pending_begin_frame_);
174 if (has_pending_begin_frame_) {
175 // TODO(brianderson): Fix contention with background ticking.
176 begin_frame_deadline_closure_.Cancel();
177 OnBeginFrameDeadline();
178 }
170 has_pending_begin_frame_ = true; 179 has_pending_begin_frame_ = true;
171 safe_to_expect_begin_frame_ = true; 180 safe_to_expect_begin_frame_ = true;
172 last_begin_frame_args_ = args; 181 last_begin_frame_args_ = args;
173 state_machine_.DidEnterBeginFrame(args); 182 last_begin_frame_args_.AdjustDeadline(-client_->DrawDurationEstimate());
183 state_machine_.OnBeginFrame(last_begin_frame_args_);
174 ProcessScheduledActions(); 184 ProcessScheduledActions();
175 state_machine_.DidLeaveBeginFrame(); 185
186 if (state_machine_.ShouldTriggerBeginFrameDeadlineEarly())
187 PostBeginFrameDeadline(base::TimeTicks());
188 else
189 PostBeginFrameDeadline(last_begin_frame_args_.deadline);
190 }
191
192 void Scheduler::PostBeginFrameDeadline(base::TimeTicks deadline) {
193 begin_frame_deadline_closure_.Cancel();
194 begin_frame_deadline_closure_.Reset(
195 base::Bind(&Scheduler::OnBeginFrameDeadline, weak_factory_.GetWeakPtr()));
196 client_->PostBeginFrameDeadline(
197 begin_frame_deadline_closure_.callback(), deadline);
198 }
199
200 void Scheduler::OnBeginFrameDeadline() {
201 TRACE_EVENT0("cc", "Scheduler::OnBeginFrameDeadline");
202 begin_frame_deadline_closure_.Cancel();
203 state_machine_.OnBeginFrameDeadline();
204 ProcessScheduledActions();
205 client_->DidFinishBeginFrameOnImplThread();
176 } 206 }
177 207
178 void Scheduler::DrawAndSwapIfPossible() { 208 void Scheduler::DrawAndSwapIfPossible() {
179 ScheduledActionDrawAndSwapResult result = 209 ScheduledActionDrawAndSwapResult result =
180 client_->ScheduledActionDrawAndSwapIfPossible(); 210 client_->ScheduledActionDrawAndSwapIfPossible();
181 state_machine_.DidDrawIfPossibleCompleted(result.did_draw); 211 state_machine_.DidDrawIfPossibleCompleted(result.did_draw);
182 if (result.did_swap) 212 if (result.did_swap)
183 has_pending_begin_frame_ = false; 213 has_pending_begin_frame_ = false;
184 } 214 }
185 215
186 void Scheduler::DrawAndSwapForced() { 216 void Scheduler::DrawAndSwapForced() {
187 ScheduledActionDrawAndSwapResult result = 217 ScheduledActionDrawAndSwapResult result =
188 client_->ScheduledActionDrawAndSwapForced(); 218 client_->ScheduledActionDrawAndSwapForced();
189 if (result.did_swap) 219 if (result.did_swap)
190 has_pending_begin_frame_ = false; 220 has_pending_begin_frame_ = false;
191 } 221 }
192 222
193 void Scheduler::ProcessScheduledActions() { 223 void Scheduler::ProcessScheduledActions() {
194 // We do not allow ProcessScheduledActions to be recursive. 224 // We do not allow ProcessScheduledActions to be recursive.
195 // The top-level call will iteratively execute the next action for us anyway. 225 // The top-level call will iteratively execute the next action for us anyway.
196 if (inside_process_scheduled_actions_) 226 if (inside_process_scheduled_actions_)
197 return; 227 return;
198 228
199 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true); 229 base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true);
200 230
201 SchedulerStateMachine::Action action = state_machine_.NextAction(); 231 SchedulerStateMachine::Action action;
202 while (action != SchedulerStateMachine::ACTION_NONE) { 232 do {
233 std::string str;
234 base::StringAppendF(&str, "SchedulerStateMachine : ticks %s",
235 state_machine_.ToString().c_str());
236 TRACE_EVENT0("cc", str.c_str());
Sami 2013/07/02 10:28:06 Can we trace strings like this nowadays? I remembe
danakj 2013/07/02 13:24:24 I believe there are COPY versions of the macros to
237
238 //TRACE_EVENT1("cc", "SchedulerStateMachine",
Sami 2013/07/02 10:28:06 We could also uncomment this and put it to the dis
239 // "state", state_machine_.ToString());
240 action = state_machine_.NextAction();
203 state_machine_.UpdateState(action); 241 state_machine_.UpdateState(action);
204 switch (action) { 242 switch (action) {
205 case SchedulerStateMachine::ACTION_NONE: 243 case SchedulerStateMachine::ACTION_NONE:
206 break; 244 break;
207 case SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: 245 case SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
208 client_->ScheduledActionSendBeginFrameToMainThread(); 246 client_->ScheduledActionSendBeginFrameToMainThread();
209 break; 247 break;
210 case SchedulerStateMachine::ACTION_COMMIT: 248 case SchedulerStateMachine::ACTION_COMMIT:
211 client_->ScheduledActionCommit(); 249 client_->ScheduledActionCommit();
212 break; 250 break;
213 case SchedulerStateMachine::ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS: 251 case SchedulerStateMachine::ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS:
214 client_->ScheduledActionCheckForCompletedTileUploads(); 252 client_->ScheduledActionCheckForCompletedTileUploads();
215 break; 253 break;
216 case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: 254 case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED:
217 client_->ScheduledActionActivatePendingTreeIfNeeded(); 255 client_->ScheduledActionActivatePendingTreeIfNeeded();
218 break; 256 break;
219 case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: 257 case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE:
220 DrawAndSwapIfPossible(); 258 DrawAndSwapIfPossible();
221 break; 259 break;
222 case SchedulerStateMachine::ACTION_DRAW_FORCED: 260 case SchedulerStateMachine::ACTION_DRAW_FORCED:
223 DrawAndSwapForced(); 261 DrawAndSwapForced();
224 break; 262 break;
225 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 263 case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
226 client_->ScheduledActionBeginOutputSurfaceCreation(); 264 client_->ScheduledActionBeginOutputSurfaceCreation();
227 break; 265 break;
228 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: 266 case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
229 client_->ScheduledActionAcquireLayerTexturesForMainThread(); 267 client_->ScheduledActionAcquireLayerTexturesForMainThread();
230 break; 268 break;
231 } 269 }
232 action = state_machine_.NextAction(); 270 } while (action != SchedulerStateMachine::ACTION_NONE);
233 }
234 271
235 SetupNextBeginFrameIfNeeded(); 272 SetupNextBeginFrameIfNeeded();
236 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); 273 client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
237 } 274 }
238 275
239 bool Scheduler::WillDrawIfNeeded() const { 276 bool Scheduler::WillDrawIfNeeded() const {
240 return !state_machine_.DrawSuspendedUntilCommit(); 277 return !state_machine_.DrawSuspendedUntilCommit();
241 } 278 }
242 279
243 } // namespace cc 280 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler.h ('k') | cc/scheduler/scheduler_state_machine.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698