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

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

Issue 22926024: cc: Control activation from the Scheduler (Closed) Base URL: http://git.chromium.org/chromium/src.git@schedOutputSurface4
Patch Set: remove hacks, address comments, force activation to prevent deadlock Created 7 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
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_state_machine.h" 5 #include "cc/scheduler/scheduler_state_machine.h"
6 6
7 #include "base/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/values.h" 10 #include "base/values.h"
11 11
12 namespace cc { 12 namespace cc {
13 13
14 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) 14 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
15 : settings_(settings), 15 : settings_(settings),
16 output_surface_state_(OUTPUT_SURFACE_LOST), 16 output_surface_state_(OUTPUT_SURFACE_LOST),
17 commit_state_(COMMIT_STATE_IDLE), 17 commit_state_(COMMIT_STATE_IDLE),
18 commit_count_(0), 18 commit_count_(0),
19 current_frame_number_(0), 19 current_frame_number_(0),
20 last_frame_number_where_begin_frame_sent_to_main_thread_(-1), 20 last_frame_number_where_begin_frame_sent_to_main_thread_(-1),
21 last_frame_number_where_draw_was_called_(-1), 21 last_frame_number_where_draw_was_called_(-1),
22 last_frame_number_where_tree_activation_attempted_(-1),
23 last_frame_number_where_update_visible_tiles_was_called_(-1), 22 last_frame_number_where_update_visible_tiles_was_called_(-1),
24 consecutive_failed_draws_(0), 23 consecutive_failed_draws_(0),
25 maximum_number_of_failed_draws_before_draw_is_forced_(3), 24 maximum_number_of_failed_draws_before_draw_is_forced_(3),
26 needs_redraw_(false), 25 needs_redraw_(false),
27 swap_used_incomplete_tile_(false), 26 swap_used_incomplete_tile_(false),
28 needs_forced_redraw_(false), 27 needs_forced_redraw_(false),
29 needs_forced_redraw_after_next_commit_(false), 28 needs_forced_redraw_after_next_commit_(false),
30 needs_commit_(false), 29 needs_commit_(false),
31 needs_forced_commit_(false), 30 needs_forced_commit_(false),
32 expect_immediate_begin_frame_for_main_thread_(false), 31 expect_immediate_begin_frame_for_main_thread_(false),
33 main_thread_needs_layer_textures_(false), 32 main_thread_needs_layer_textures_(false),
34 inside_begin_frame_(false), 33 inside_begin_frame_(false),
35 visible_(false), 34 visible_(false),
36 can_start_(false), 35 can_start_(false),
37 can_draw_(false), 36 can_draw_(false),
38 has_pending_tree_(false), 37 has_pending_tree_(false),
38 pending_tree_is_ready_for_activation_(false),
39 active_tree_has_been_drawn_(false),
39 draw_if_possible_failed_(false), 40 draw_if_possible_failed_(false),
40 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), 41 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED),
41 did_create_and_initialize_first_output_surface_(false) {} 42 did_create_and_initialize_first_output_surface_(false) {}
42 43
43 const char* SchedulerStateMachine::OutputSurfaceStateToString( 44 const char* SchedulerStateMachine::OutputSurfaceStateToString(
44 OutputSurfaceState state) { 45 OutputSurfaceState state) {
45 switch (state) { 46 switch (state) {
46 case OUTPUT_SURFACE_ACTIVE: 47 case OUTPUT_SURFACE_ACTIVE:
47 return "OUTPUT_SURFACE_ACTIVE"; 48 return "OUTPUT_SURFACE_ACTIVE";
48 case OUTPUT_SURFACE_LOST: 49 case OUTPUT_SURFACE_LOST:
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 const char* SchedulerStateMachine::ActionToString(Action action) { 92 const char* SchedulerStateMachine::ActionToString(Action action) {
92 switch (action) { 93 switch (action) {
93 case ACTION_NONE: 94 case ACTION_NONE:
94 return "ACTION_NONE"; 95 return "ACTION_NONE";
95 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: 96 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
96 return "ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD"; 97 return "ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD";
97 case ACTION_COMMIT: 98 case ACTION_COMMIT:
98 return "ACTION_COMMIT"; 99 return "ACTION_COMMIT";
99 case ACTION_UPDATE_VISIBLE_TILES: 100 case ACTION_UPDATE_VISIBLE_TILES:
100 return "ACTION_UPDATE_VISIBLE_TILES"; 101 return "ACTION_UPDATE_VISIBLE_TILES";
101 case ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: 102 case ACTION_ACTIVATE_PENDING_TREE:
102 return "ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED"; 103 return "ACTION_ACTIVATE_PENDING_TREE";
103 case ACTION_DRAW_IF_POSSIBLE: 104 case ACTION_DRAW_IF_POSSIBLE:
104 return "ACTION_DRAW_IF_POSSIBLE"; 105 return "ACTION_DRAW_IF_POSSIBLE";
105 case ACTION_DRAW_FORCED: 106 case ACTION_DRAW_FORCED:
106 return "ACTION_DRAW_FORCED"; 107 return "ACTION_DRAW_FORCED";
107 case ACTION_DRAW_AND_SWAP_ABORT: 108 case ACTION_DRAW_AND_SWAP_ABORT:
108 return "ACTION_DRAW_AND_SWAP_ABORT"; 109 return "ACTION_DRAW_AND_SWAP_ABORT";
109 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 110 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
110 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; 111 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION";
111 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: 112 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
112 return "ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD"; 113 return "ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD";
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 state->Set("major_timestamps_in_ms", timestamps_state.release()); 156 state->Set("major_timestamps_in_ms", timestamps_state.release());
156 157
157 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); 158 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue);
158 minor_state->SetInteger("commit_count", commit_count_); 159 minor_state->SetInteger("commit_count", commit_count_);
159 minor_state->SetInteger("current_frame_number", current_frame_number_); 160 minor_state->SetInteger("current_frame_number", current_frame_number_);
160 minor_state->SetInteger( 161 minor_state->SetInteger(
161 "last_frame_number_where_begin_frame_sent_to_main_thread", 162 "last_frame_number_where_begin_frame_sent_to_main_thread",
162 last_frame_number_where_begin_frame_sent_to_main_thread_); 163 last_frame_number_where_begin_frame_sent_to_main_thread_);
163 minor_state->SetInteger("last_frame_number_where_draw_was_called", 164 minor_state->SetInteger("last_frame_number_where_draw_was_called",
164 last_frame_number_where_draw_was_called_); 165 last_frame_number_where_draw_was_called_);
165 minor_state->SetInteger("last_frame_number_where_tree_activation_attempted",
166 last_frame_number_where_tree_activation_attempted_);
167 minor_state->SetInteger( 166 minor_state->SetInteger(
168 "last_frame_number_where_update_visible_tiles_was_called", 167 "last_frame_number_where_update_visible_tiles_was_called",
169 last_frame_number_where_update_visible_tiles_was_called_); 168 last_frame_number_where_update_visible_tiles_was_called_);
170 minor_state->SetInteger("consecutive_failed_draws", 169 minor_state->SetInteger("consecutive_failed_draws",
171 consecutive_failed_draws_); 170 consecutive_failed_draws_);
172 minor_state->SetInteger( 171 minor_state->SetInteger(
173 "maximum_number_of_failed_draws_before_draw_is_forced", 172 "maximum_number_of_failed_draws_before_draw_is_forced",
174 maximum_number_of_failed_draws_before_draw_is_forced_); 173 maximum_number_of_failed_draws_before_draw_is_forced_);
175 minor_state->SetBoolean("needs_redraw", needs_redraw_); 174 minor_state->SetBoolean("needs_redraw", needs_redraw_);
176 minor_state->SetBoolean("swap_used_incomplete_tile", 175 minor_state->SetBoolean("swap_used_incomplete_tile",
177 swap_used_incomplete_tile_); 176 swap_used_incomplete_tile_);
178 minor_state->SetBoolean("needs_forced_redraw", needs_forced_redraw_); 177 minor_state->SetBoolean("needs_forced_redraw", needs_forced_redraw_);
179 minor_state->SetBoolean("needs_forced_redraw_after_next_commit", 178 minor_state->SetBoolean("needs_forced_redraw_after_next_commit",
180 needs_forced_redraw_after_next_commit_); 179 needs_forced_redraw_after_next_commit_);
181 minor_state->SetBoolean("needs_commit", needs_commit_); 180 minor_state->SetBoolean("needs_commit", needs_commit_);
182 minor_state->SetBoolean("needs_forced_commit", needs_forced_commit_); 181 minor_state->SetBoolean("needs_forced_commit", needs_forced_commit_);
183 minor_state->SetBoolean("expect_immediate_begin_frame_for_main_thread", 182 minor_state->SetBoolean("expect_immediate_begin_frame_for_main_thread",
184 expect_immediate_begin_frame_for_main_thread_); 183 expect_immediate_begin_frame_for_main_thread_);
185 minor_state->SetBoolean("main_thread_needs_layer_textures", 184 minor_state->SetBoolean("main_thread_needs_layer_textures",
186 main_thread_needs_layer_textures_); 185 main_thread_needs_layer_textures_);
187 minor_state->SetBoolean("inside_begin_frame", inside_begin_frame_); 186 minor_state->SetBoolean("inside_begin_frame", inside_begin_frame_);
188 minor_state->SetBoolean("visible", visible_); 187 minor_state->SetBoolean("visible", visible_);
189 minor_state->SetBoolean("can_start", can_start_); 188 minor_state->SetBoolean("can_start", can_start_);
190 minor_state->SetBoolean("can_draw", can_draw_); 189 minor_state->SetBoolean("can_draw", can_draw_);
191 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); 190 minor_state->SetBoolean("has_pending_tree", has_pending_tree_);
191 minor_state->SetBoolean("pending_tree_is_ready_for_activation_",
192 pending_tree_is_ready_for_activation_);
193 minor_state->SetBoolean("active_tree_has_been_drawn_",
194 active_tree_has_been_drawn_);
192 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); 195 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_);
193 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", 196 minor_state->SetBoolean("did_create_and_initialize_first_output_surface",
194 did_create_and_initialize_first_output_surface_); 197 did_create_and_initialize_first_output_surface_);
195 state->Set("minor_state", minor_state.release()); 198 state->Set("minor_state", minor_state.release());
196 199
197 return state.PassAs<base::Value>(); 200 return state.PassAs<base::Value>();
198 } 201 }
199 202
200 bool SchedulerStateMachine::HasDrawnThisFrame() const { 203 bool SchedulerStateMachine::HasDrawnThisFrame() const {
201 return current_frame_number_ == last_frame_number_where_draw_was_called_; 204 return current_frame_number_ == last_frame_number_where_draw_was_called_;
202 } 205 }
203 206
204 bool SchedulerStateMachine::HasAttemptedTreeActivationThisFrame() const {
205 return current_frame_number_ ==
206 last_frame_number_where_tree_activation_attempted_;
207 }
208
209 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { 207 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const {
210 return current_frame_number_ == 208 return current_frame_number_ ==
211 last_frame_number_where_update_visible_tiles_was_called_; 209 last_frame_number_where_update_visible_tiles_was_called_;
212 } 210 }
213 211
214 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const { 212 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const {
215 return current_frame_number_ == 213 return current_frame_number_ ==
216 last_frame_number_where_begin_frame_sent_to_main_thread_; 214 last_frame_number_where_begin_frame_sent_to_main_thread_;
217 } 215 }
218 216
(...skipping 18 matching lines...) Expand all
237 OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); 235 OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
238 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { 236 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) {
239 if (commit_results_in_pending_tree) { 237 if (commit_results_in_pending_tree) {
240 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION; 238 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION;
241 } else { 239 } else {
242 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 240 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
243 needs_redraw_ = true; 241 needs_redraw_ = true;
244 } 242 }
245 } 243 }
246 244
247 // if we don't have to wait for activation, update needs_redraw now. 245 // Update state if we have a new active tree to draw.
248 if (!commit_results_in_pending_tree) { 246 if (!commit_results_in_pending_tree &&
249 if (!commit_was_aborted) 247 (!commit_was_aborted || expect_immediate_begin_frame_for_main_thread_)) {
250 needs_redraw_ = true; 248 needs_redraw_ = true;
251 if (expect_immediate_begin_frame_for_main_thread_) 249 active_tree_has_been_drawn_ = false;
252 needs_redraw_ = true;
253 } 250 }
254 251
255 // This post-commit work is common to both completed and aborted commits. 252 // This post-commit work is common to both completed and aborted commits.
256 if (draw_if_possible_failed_) 253 if (draw_if_possible_failed_)
257 last_frame_number_where_draw_was_called_ = -1; 254 last_frame_number_where_draw_was_called_ = -1;
258 255
259 if (needs_forced_redraw_after_next_commit_) { 256 if (needs_forced_redraw_after_next_commit_) {
260 needs_forced_redraw_after_next_commit_ = false; 257 needs_forced_redraw_after_next_commit_ = false;
261 needs_forced_redraw_ = true; 258 needs_forced_redraw_ = true;
262 } 259 }
263 260
264 // If we are planing to draw with the new commit, lock the layer textures for 261 // If we are planing to draw with the new commit, lock the layer textures for
265 // use on the impl thread. Otherwise, leave them unlocked. 262 // use on the impl thread. Otherwise, leave them unlocked.
266 if (commit_results_in_pending_tree || needs_redraw_ || needs_forced_redraw_) 263 if (commit_results_in_pending_tree || needs_redraw_ || needs_forced_redraw_)
267 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD; 264 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD;
268 else 265 else
269 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; 266 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
270 } 267 }
271 268
272 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 269 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
273 // These are all the cases where, if we do not abort draws to make 270 // These are all the cases where, if we do not abort draws to make
274 // forward progress, we might deadlock with the main thread. 271 // forward progress, we might deadlock with the main thread.
272 // This should be a superset of PendingActivationsShouldBeForced().
273 if (PendingActivationsShouldBeForced())
274 return true;
275
276 // Additional states where we should abort draws.
277 // Note: We don't force activation in these cases because doing so would
278 // result in checkerboarding on resize, becoming visible, etc.
275 if (!can_draw_) 279 if (!can_draw_)
276 return true; 280 return true;
277 if (!visible_) 281 if (!visible_)
278 return true; 282 return true;
279 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 283 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
280 return true;
281 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD)
282 return true; 284 return true;
283 return false; 285 return false;
284 } 286 }
285 287
288 bool SchedulerStateMachine::PendingActivationsShouldBeForced() const {
289 // These are all the cases where, if we do not force activations to make
290 // forward progress, we might deadlock with the main thread.
291 // This should be a subset PendingDrawsShouldBeAborted().
292 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD)
293 return true;
294 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
295 output_surface_state_ == OUTPUT_SURFACE_CREATING ||
296 output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
297 return true;
298 return false;
299 }
300
286 bool SchedulerStateMachine::ShouldDraw() const { 301 bool SchedulerStateMachine::ShouldDraw() const {
287 // Always handle forced draws ASAP. 302 // Always handle forced draws ASAP.
288 if (needs_forced_redraw_) 303 if (needs_forced_redraw_)
289 return true; 304 return true;
290 305
291 // If we are going to abort draws, we should do so ASAP. 306 // If we are going to abort draws, we should do so ASAP.
292 if (PendingDrawsShouldBeAborted()) { 307 if (PendingDrawsShouldBeAborted())
293 // TODO(brianderson): Remove the !has_pending_tree_ condition once 308 return commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
294 // the Scheduler controls activation. It's dangerous for us to rely on
295 // an eventual activation if we've lost the output surface.
296 return commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW &&
297 !has_pending_tree_;
298 }
299 309
300 // After this line, we only want to draw once per frame. 310 // After this line, we only want to draw once per frame.
301 if (HasDrawnThisFrame()) 311 if (HasDrawnThisFrame())
302 return false; 312 return false;
303 313
304 // We currently only draw within the BeginFrame. 314 // We currently only draw within the BeginFrame.
305 if (!inside_begin_frame_) 315 if (!inside_begin_frame_)
306 return false; 316 return false;
307 317
308 return needs_redraw_; 318 return needs_redraw_;
309 } 319 }
310 320
311 bool SchedulerStateMachine::ShouldAttemptTreeActivation() const { 321 bool SchedulerStateMachine::ShouldActivatePendingTree() const {
312 return has_pending_tree_ && inside_begin_frame_ && 322 // There is nothing to activate.
313 !HasAttemptedTreeActivationThisFrame(); 323 if (!has_pending_tree_)
324 return false;
325
326 // We don't want to activate a second tree before drawing the first one.
327 // Note: It is possible that there is no active tree to draw when
328 // output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION,
329 // so we don't block activation on draw in that case.
330 if (!active_tree_has_been_drawn_ &&
331 output_surface_state_ != OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
332 return false;
333
334 // If we want to force activation, do so ASAP.
335 if (PendingActivationsShouldBeForced())
336 return true;
337
338 // At this point, only activate if we are ready to activate.
339 return pending_tree_is_ready_for_activation_;
314 } 340 }
315 341
316 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const { 342 bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const {
317 if (!settings_.impl_side_painting) 343 if (!settings_.impl_side_painting)
318 return false; 344 return false;
319 if (HasUpdatedVisibleTilesThisFrame()) 345 if (HasUpdatedVisibleTilesThisFrame())
320 return false; 346 return false;
321 347
322 return ShouldAttemptTreeActivation() || ShouldDraw() || 348 return ShouldActivatePendingTree() || ShouldDraw() ||
323 swap_used_incomplete_tile_; 349 swap_used_incomplete_tile_;
324 } 350 }
325 351
326 bool SchedulerStateMachine::ShouldSendBeginFrameToMainThread() const { 352 bool SchedulerStateMachine::ShouldSendBeginFrameToMainThread() const {
327 if (!needs_commit_) 353 if (!needs_commit_)
328 return false; 354 return false;
329 355
330 // Only send BeginFrame to the main thread when idle. 356 // Only send BeginFrame to the main thread when idle.
331 if (commit_state_ != COMMIT_STATE_IDLE) 357 if (commit_state_ != COMMIT_STATE_IDLE)
332 return false; 358 return false;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
381 needs_forced_commit_) 407 needs_forced_commit_)
382 // TODO(enne): Should probably drop the active tree on force commit. 408 // TODO(enne): Should probably drop the active tree on force commit.
383 return has_pending_tree_ ? ACTION_NONE 409 return has_pending_tree_ ? ACTION_NONE
384 : ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; 410 : ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD;
385 if (output_surface_state_ == OUTPUT_SURFACE_LOST && can_start_) 411 if (output_surface_state_ == OUTPUT_SURFACE_LOST && can_start_)
386 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; 412 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
387 if (output_surface_state_ == OUTPUT_SURFACE_CREATING) 413 if (output_surface_state_ == OUTPUT_SURFACE_CREATING)
388 return ACTION_NONE; 414 return ACTION_NONE;
389 if (ShouldUpdateVisibleTiles()) 415 if (ShouldUpdateVisibleTiles())
390 return ACTION_UPDATE_VISIBLE_TILES; 416 return ACTION_UPDATE_VISIBLE_TILES;
391 if (ShouldAttemptTreeActivation()) 417 if (ShouldActivatePendingTree())
392 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; 418 return ACTION_ACTIVATE_PENDING_TREE;
393 if (ShouldDraw()) { 419 if (ShouldDraw()) {
394 return needs_forced_redraw_ ? ACTION_DRAW_FORCED 420 return needs_forced_redraw_ ? ACTION_DRAW_FORCED
395 : ACTION_DRAW_IF_POSSIBLE; 421 : ACTION_DRAW_IF_POSSIBLE;
396 } 422 }
397 if (ShouldSendBeginFrameToMainThread()) 423 if (ShouldSendBeginFrameToMainThread())
398 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; 424 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD;
399 return ACTION_NONE; 425 return ACTION_NONE;
400 } 426 }
401 case COMMIT_STATE_FRAME_IN_PROGRESS: 427 case COMMIT_STATE_FRAME_IN_PROGRESS:
402 if (ShouldUpdateVisibleTiles()) 428 if (ShouldUpdateVisibleTiles())
403 return ACTION_UPDATE_VISIBLE_TILES; 429 return ACTION_UPDATE_VISIBLE_TILES;
404 if (ShouldAttemptTreeActivation()) 430 if (ShouldActivatePendingTree())
405 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; 431 return ACTION_ACTIVATE_PENDING_TREE;
406 if (ShouldDraw()) { 432 if (ShouldDraw()) {
407 return needs_forced_redraw_ ? ACTION_DRAW_FORCED 433 return needs_forced_redraw_ ? ACTION_DRAW_FORCED
408 : ACTION_DRAW_IF_POSSIBLE; 434 : ACTION_DRAW_IF_POSSIBLE;
409 } 435 }
410 return ACTION_NONE; 436 return ACTION_NONE;
411 437
412 case COMMIT_STATE_READY_TO_COMMIT: 438 case COMMIT_STATE_READY_TO_COMMIT:
413 return ACTION_COMMIT; 439 return ACTION_COMMIT;
414 440
415 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: { 441 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: {
416 if (ShouldUpdateVisibleTiles()) 442 if (ShouldUpdateVisibleTiles())
417 return ACTION_UPDATE_VISIBLE_TILES; 443 return ACTION_UPDATE_VISIBLE_TILES;
418 if (ShouldAttemptTreeActivation()) 444 if (ShouldActivatePendingTree())
419 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; 445 return ACTION_ACTIVATE_PENDING_TREE;
420 if (ShouldDraw()) { 446 if (ShouldDraw()) {
421 if (needs_forced_redraw_) 447 if (needs_forced_redraw_)
422 return ACTION_DRAW_FORCED; 448 return ACTION_DRAW_FORCED;
423 else if (PendingDrawsShouldBeAborted()) 449 else if (PendingDrawsShouldBeAborted())
424 return ACTION_DRAW_AND_SWAP_ABORT; 450 return ACTION_DRAW_AND_SWAP_ABORT;
425 else 451 else
426 return ACTION_DRAW_IF_POSSIBLE; 452 return ACTION_DRAW_IF_POSSIBLE;
427 } 453 }
428 return ACTION_NONE; 454 return ACTION_NONE;
429 } 455 }
430 456
431 case COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW: 457 case COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW:
432 if (ShouldUpdateVisibleTiles()) 458 if (ShouldUpdateVisibleTiles())
433 return ACTION_UPDATE_VISIBLE_TILES; 459 return ACTION_UPDATE_VISIBLE_TILES;
434 if (ShouldAttemptTreeActivation()) 460 if (ShouldActivatePendingTree())
435 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; 461 return ACTION_ACTIVATE_PENDING_TREE;
436 if (needs_forced_redraw_) 462 if (needs_forced_redraw_)
437 return ACTION_DRAW_FORCED; 463 return ACTION_DRAW_FORCED;
438 return ACTION_NONE; 464 return ACTION_NONE;
439 } 465 }
440 NOTREACHED(); 466 NOTREACHED();
441 return ACTION_NONE; 467 return ACTION_NONE;
442 } 468 }
443 469
444 void SchedulerStateMachine::UpdateState(Action action) { 470 void SchedulerStateMachine::UpdateState(Action action) {
445 switch (action) { 471 switch (action) {
446 case ACTION_NONE: 472 case ACTION_NONE:
447 return; 473 return;
448 474
449 case ACTION_UPDATE_VISIBLE_TILES: 475 case ACTION_UPDATE_VISIBLE_TILES:
450 last_frame_number_where_update_visible_tiles_was_called_ = 476 last_frame_number_where_update_visible_tiles_was_called_ =
451 current_frame_number_; 477 current_frame_number_;
452 return; 478 return;
453 479
454 case ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: 480 case ACTION_ACTIVATE_PENDING_TREE:
455 last_frame_number_where_tree_activation_attempted_ =
456 current_frame_number_;
457 return; 481 return;
458 482
459 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: 483 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
460 DCHECK(!has_pending_tree_); 484 DCHECK(!has_pending_tree_);
461 if (!needs_forced_commit_ && 485 if (!needs_forced_commit_ &&
462 output_surface_state_ != OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { 486 output_surface_state_ != OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) {
463 DCHECK(visible_); 487 DCHECK(visible_);
464 DCHECK_GT(current_frame_number_, 488 DCHECK_GT(current_frame_number_,
465 last_frame_number_where_begin_frame_sent_to_main_thread_); 489 last_frame_number_where_begin_frame_sent_to_main_thread_);
466 } 490 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 expect_immediate_begin_frame_for_main_thread_ = false; 536 expect_immediate_begin_frame_for_main_thread_ = false;
513 } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) { 537 } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) {
514 commit_state_ = COMMIT_STATE_IDLE; 538 commit_state_ = COMMIT_STATE_IDLE;
515 } 539 }
516 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD) 540 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD)
517 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; 541 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
518 542
519 needs_redraw_ = false; 543 needs_redraw_ = false;
520 needs_forced_redraw_ = false; 544 needs_forced_redraw_ = false;
521 draw_if_possible_failed_ = false; 545 draw_if_possible_failed_ = false;
546 active_tree_has_been_drawn_ = true;
522 547
523 if (did_swap) 548 if (did_swap)
524 swap_used_incomplete_tile_ = false; 549 swap_used_incomplete_tile_ = false;
525 } 550 }
526 551
527 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { 552 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() {
528 DCHECK(!main_thread_needs_layer_textures_); 553 DCHECK(!main_thread_needs_layer_textures_);
529 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); 554 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
530 main_thread_needs_layer_textures_ = true; 555 main_thread_needs_layer_textures_ = true;
531 } 556 }
532 557
533 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { 558 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const {
534 // TODO(brianderson): Remove this hack once the Scheduler controls activation.
535 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
536 return true;
537
538 // If we can't draw, don't tick until we are notified that we can draw again. 559 // If we can't draw, don't tick until we are notified that we can draw again.
539 if (!can_draw_) 560 if (!can_draw_)
540 return false; 561 return false;
541 562
542 if (needs_forced_redraw_) 563 if (needs_forced_redraw_)
543 return true; 564 return true;
544 565
545 if (visible_ && swap_used_incomplete_tile_) 566 if (visible_ && swap_used_incomplete_tile_)
546 return true; 567 return true;
547 568
548 return needs_redraw_ && visible_ && HasInitializedOutputSurface(); 569 return needs_redraw_ && visible_ && HasInitializedOutputSurface();
549 } 570 }
550 571
551 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const { 572 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const {
552 // Do not be proactive when invisible. 573 // Do not be proactive when invisible.
553 if (!visible_ || output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 574 if (!visible_ || !HasInitializedOutputSurface())
554 return false; 575 return false;
555 576
556 // We should proactively request a BeginFrame if a commit or a tree activation 577 // We should proactively request a BeginFrame if a commit or a tree activation
557 // is pending. 578 // is pending.
558 return (needs_commit_ || needs_forced_commit_ || 579 return (needs_commit_ || needs_forced_commit_ ||
559 commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_); 580 commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_);
560 } 581 }
561 582
562 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { 583 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) {
563 current_frame_number_++; 584 current_frame_number_++;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 } 650 }
630 651
631 void SchedulerStateMachine::DidLoseOutputSurface() { 652 void SchedulerStateMachine::DidLoseOutputSurface() {
632 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 653 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
633 output_surface_state_ == OUTPUT_SURFACE_CREATING) 654 output_surface_state_ == OUTPUT_SURFACE_CREATING)
634 return; 655 return;
635 output_surface_state_ = OUTPUT_SURFACE_LOST; 656 output_surface_state_ = OUTPUT_SURFACE_LOST;
636 needs_redraw_ = false; 657 needs_redraw_ = false;
637 } 658 }
638 659
660 void SchedulerStateMachine::NotifyReadyToActivate() {
661 if (has_pending_tree_)
662 pending_tree_is_ready_for_activation_ = true;
663 }
664
639 void SchedulerStateMachine::SetHasPendingTree(bool has_pending_tree) { 665 void SchedulerStateMachine::SetHasPendingTree(bool has_pending_tree) {
640 if (has_pending_tree_ && !has_pending_tree) { 666 if (has_pending_tree_ && !has_pending_tree) {
641 // There is a new active tree. 667 // There is a new active tree.
642 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) 668 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
643 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 669 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
644 670
671 pending_tree_is_ready_for_activation_ = false;
672 active_tree_has_been_drawn_ = false;
645 needs_redraw_ = true; 673 needs_redraw_ = true;
674 } else if (!has_pending_tree_ && has_pending_tree) {
675 // There is a new pending tree.
676 pending_tree_is_ready_for_activation_ = false;
646 } 677 }
647 has_pending_tree_ = has_pending_tree; 678 has_pending_tree_ = has_pending_tree;
648 } 679 }
649 680
650 void SchedulerStateMachine::SetCanDraw(bool can) { can_draw_ = can; } 681 void SchedulerStateMachine::SetCanDraw(bool can) { can_draw_ = can; }
651 682
652 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { 683 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
653 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); 684 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
654 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; 685 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT;
655 686
(...skipping 19 matching lines...) Expand all
675 NOTREACHED(); 706 NOTREACHED();
676 return false; 707 return false;
677 } 708 }
678 709
679 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced( 710 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(
680 int num_draws) { 711 int num_draws) {
681 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws; 712 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws;
682 } 713 }
683 714
684 } // namespace cc 715 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698