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

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

Issue 16871016: cc: Use BeginFrameArgs (Closed) Base URL: http://git.chromium.org/chromium/src.git@bfargs2
Patch Set: A bit of cleanup 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
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 10
11 namespace cc { 11 namespace cc {
12 12
13 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) 13 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
14 : settings_(settings), 14 : settings_(settings),
15 output_surface_state_(OUTPUT_SURFACE_LOST),
16 begin_frame_state_(BEGIN_FRAME_STATE_IDLE),
15 commit_state_(COMMIT_STATE_IDLE), 17 commit_state_(COMMIT_STATE_IDLE),
18 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED),
19 readback_state_(READBACK_STATE_IDLE),
20 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
16 commit_count_(0), 21 commit_count_(0),
17 current_frame_number_(0), 22 begin_frame_count_(0),
18 last_frame_number_where_draw_was_called_(-1), 23 draw_attempt_count_(0),
19 last_frame_number_where_tree_activation_attempted_(-1), 24 last_begin_frame_count_draw_was_called_(-1),
20 last_frame_number_where_check_for_completed_tile_uploads_called_(-1), 25 last_begin_frame_count_begin_frame_sent_to_main_thread_(-1),
26 last_draw_attempt_count_tree_activation_attempted_(-1),
27 last_draw_attempt_count_completed_tile_uploads_checked_(-1),
21 consecutive_failed_draws_(0), 28 consecutive_failed_draws_(0),
22 maximum_number_of_failed_draws_before_draw_is_forced_(3), 29 maximum_number_of_failed_draws_before_draw_is_forced_(3),
23 needs_redraw_(false), 30 needs_redraw_(false),
24 swap_used_incomplete_tile_(false), 31 swap_used_incomplete_tile_(false),
25 needs_forced_redraw_(false),
26 needs_forced_redraw_after_next_commit_(false),
27 needs_commit_(false), 32 needs_commit_(false),
28 needs_forced_commit_(false),
29 expect_immediate_begin_frame_for_main_thread_(false),
30 main_thread_needs_layer_textures_(false), 33 main_thread_needs_layer_textures_(false),
31 inside_begin_frame_(false), 34 active_tree_has_been_drawn_(false),
35 active_tree_is_null_(true),
32 visible_(false), 36 visible_(false),
33 can_start_(false), 37 can_start_(false),
34 can_draw_(false), 38 can_draw_(false),
35 has_pending_tree_(false), 39 has_pending_tree_(false),
36 draw_if_possible_failed_(false), 40 draw_if_possible_failed_(false),
37 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED),
38 output_surface_state_(OUTPUT_SURFACE_LOST),
39 did_create_and_initialize_first_output_surface_(false) {} 41 did_create_and_initialize_first_output_surface_(false) {}
40 42
41 std::string SchedulerStateMachine::ToString() { 43 std::string SchedulerStateMachine::ToString() {
42 std::string str; 44 std::string str;
45 base::StringAppendF(&str, "settings_.impl_side_painting = %d; ",
46 settings_.impl_side_painting);
47 base::StringAppendF(&str, "output_surface_state_ = %d; ",
48 output_surface_state_);
49 base::StringAppendF(&str, "begin_frame_state_ = %d; ", begin_frame_state_);
50 base::StringAppendF(&str, "commit_state_ = %d; ", commit_state_);
51 base::StringAppendF(&str, "texture_state_ = %d; ", texture_state_);
52 base::StringAppendF(&str, "readback_state_ = %d; ", readback_state_);
53 base::StringAppendF(&str, "forced_redraw_state_ = %d; ",
54 forced_redraw_state_);
55 base::StringAppendF(&str, "commit_count_ = %d; ", commit_count_);
56 base::StringAppendF(&str, "begin_frame_count_ = %d; ", begin_frame_count_);
57 base::StringAppendF(&str, "draw_attempt_count_ = %d; ", draw_attempt_count_);
58 base::StringAppendF(&str, "last_begin_frame_count_draw_was_called_ = %d; ",
59 last_begin_frame_count_draw_was_called_);
43 base::StringAppendF(&str, 60 base::StringAppendF(&str,
44 "settings_.impl_side_painting = %d; ", 61 "last_draw_attempt_count_tree_activation_attempted_ = %d; ",
45 settings_.impl_side_painting); 62 last_draw_attempt_count_tree_activation_attempted_);
46 base::StringAppendF(&str, "commit_state_ = %d; ", commit_state_);
47 base::StringAppendF(&str, "commit_count_ = %d; ", commit_count_);
48 base::StringAppendF(
49 &str, "current_frame_number_ = %d; ", current_frame_number_);
50 base::StringAppendF(&str, 63 base::StringAppendF(&str,
51 "last_frame_number_where_draw_was_called_ = %d; ", 64 "last_draw_attempt_count_completed_tile_uploads_checked_ = %d; ",
52 last_frame_number_where_draw_was_called_); 65 last_draw_attempt_count_completed_tile_uploads_checked_);
53 base::StringAppendF(
54 &str,
55 "last_frame_number_where_tree_activation_attempted_ = %d; ",
56 last_frame_number_where_tree_activation_attempted_);
57 base::StringAppendF(
58 &str,
59 "last_frame_number_where_check_for_completed_tile_uploads_called_ = %d; ",
60 last_frame_number_where_check_for_completed_tile_uploads_called_);
61 base::StringAppendF( 66 base::StringAppendF(
62 &str, "consecutive_failed_draws_ = %d; ", consecutive_failed_draws_); 67 &str, "consecutive_failed_draws_ = %d; ", consecutive_failed_draws_);
63 base::StringAppendF( 68 base::StringAppendF(
64 &str, 69 &str,
65 "maximum_number_of_failed_draws_before_draw_is_forced_ = %d; ", 70 "maximum_number_of_failed_draws_before_draw_is_forced_ = %d; ",
66 maximum_number_of_failed_draws_before_draw_is_forced_); 71 maximum_number_of_failed_draws_before_draw_is_forced_);
67 base::StringAppendF(&str, "needs_redraw_ = %d; ", needs_redraw_); 72 base::StringAppendF(&str, "needs_redraw_ = %d; ", needs_redraw_);
68 base::StringAppendF( 73 base::StringAppendF(
69 &str, "swap_used_incomplete_tile_ = %d; ", swap_used_incomplete_tile_); 74 &str, "swap_used_incomplete_tile_ = %d; ", swap_used_incomplete_tile_);
70 base::StringAppendF(
71 &str, "needs_forced_redraw_ = %d; ", needs_forced_redraw_);
72 base::StringAppendF(&str,
73 "needs_forced_redraw_after_next_commit_ = %d; ",
74 needs_forced_redraw_after_next_commit_);
75 base::StringAppendF(&str, "needs_commit_ = %d; ", needs_commit_); 75 base::StringAppendF(&str, "needs_commit_ = %d; ", needs_commit_);
76 base::StringAppendF(
77 &str, "needs_forced_commit_ = %d; ", needs_forced_commit_);
78 base::StringAppendF(&str,
79 "expect_immediate_begin_frame_for_main_thread_ = %d; ",
80 expect_immediate_begin_frame_for_main_thread_);
81 base::StringAppendF(&str, 76 base::StringAppendF(&str,
82 "main_thread_needs_layer_textures_ = %d; ", 77 "main_thread_needs_layer_textures_ = %d; ",
83 main_thread_needs_layer_textures_); 78 main_thread_needs_layer_textures_);
84 base::StringAppendF(&str, "inside_begin_frame_ = %d; ",
85 inside_begin_frame_);
86 base::StringAppendF(&str, "last_frame_time_ = %"PRId64"; ", 79 base::StringAppendF(&str, "last_frame_time_ = %"PRId64"; ",
87 (last_begin_frame_args_.frame_time - base::TimeTicks()) 80 (last_begin_frame_args_.frame_time - base::TimeTicks())
88 .InMilliseconds()); 81 .InMilliseconds());
89 base::StringAppendF(&str, "last_deadline_ = %"PRId64"; ", 82 base::StringAppendF(&str, "last_deadline_ = %"PRId64"; ",
90 (last_begin_frame_args_.deadline - base::TimeTicks()).InMilliseconds()); 83 (last_begin_frame_args_.deadline - base::TimeTicks()).InMilliseconds());
91 base::StringAppendF(&str, "last_interval_ = %"PRId64"; ", 84 base::StringAppendF(&str, "last_interval_ = %"PRId64"; ",
92 last_begin_frame_args_.interval.InMilliseconds()); 85 last_begin_frame_args_.interval.InMilliseconds());
93 base::StringAppendF(&str, "visible_ = %d; ", visible_); 86 base::StringAppendF(&str, "visible_ = %d; ", visible_);
94 base::StringAppendF(&str, "can_start_ = %d; ", can_start_); 87 base::StringAppendF(&str, "can_start_ = %d; ", can_start_);
95 base::StringAppendF(&str, "can_draw_ = %d; ", can_draw_); 88 base::StringAppendF(&str, "can_draw_ = %d; ", can_draw_);
96 base::StringAppendF( 89 base::StringAppendF(
97 &str, "draw_if_possible_failed_ = %d; ", draw_if_possible_failed_); 90 &str, "draw_if_possible_failed_ = %d; ", draw_if_possible_failed_);
98 base::StringAppendF(&str, "has_pending_tree_ = %d; ", has_pending_tree_); 91 base::StringAppendF(&str, "has_pending_tree_ = %d; ", has_pending_tree_);
99 base::StringAppendF(&str, "texture_state_ = %d; ", texture_state_); 92 base::StringAppendF(&str, "active_tree_has_been_drawn_ = %d; ",
100 base::StringAppendF( 93 active_tree_has_been_drawn_);
101 &str, "output_surface_state_ = %d; ", output_surface_state_); 94 base::StringAppendF(&str, "active_tree_is_null_ = %d; ",
95 active_tree_is_null_);
102 return str; 96 return str;
103 } 97 }
104 98
105 bool SchedulerStateMachine::HasDrawnThisFrame() const { 99 bool SchedulerStateMachine::HasDrawnThisFrame() const {
106 return current_frame_number_ == last_frame_number_where_draw_was_called_; 100 return begin_frame_count_ == last_begin_frame_count_draw_was_called_;
107 } 101 }
108 102
109 bool SchedulerStateMachine::HasAttemptedTreeActivationThisFrame() const { 103 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const {
110 return current_frame_number_ == 104 return begin_frame_count_ ==
111 last_frame_number_where_tree_activation_attempted_; 105 last_begin_frame_count_begin_frame_sent_to_main_thread_;
112 } 106 }
113 107
114 bool SchedulerStateMachine::HasCheckedForCompletedTileUploadsThisFrame() const { 108 bool SchedulerStateMachine::HasAttemptedTreeActivationThisDrawAttempt() const {
115 return current_frame_number_ == 109 return draw_attempt_count_ ==
116 last_frame_number_where_check_for_completed_tile_uploads_called_; 110 last_draw_attempt_count_tree_activation_attempted_;
111 }
112
113 bool SchedulerStateMachine::
114 HasCheckedForCompletedTileUploadsThisDrawAttempt() const {
115 return draw_attempt_count_ ==
116 last_draw_attempt_count_completed_tile_uploads_checked_;
117 } 117 }
118 118
119 bool SchedulerStateMachine::DrawSuspendedUntilCommit() const { 119 bool SchedulerStateMachine::DrawSuspendedUntilCommit() const {
120 if (!can_draw_) 120 if (!can_draw_)
121 return true; 121 return true;
122 if (!visible_) 122 if (!visible_)
123 return true; 123 return true;
124 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD) 124 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD)
125 return true; 125 return true;
126 return false; 126 return false;
127 } 127 }
128 128
129 bool SchedulerStateMachine::ScheduledToDraw() const { 129 bool SchedulerStateMachine::ScheduledToDraw() const {
130 if (!needs_redraw_) 130 if (!needs_redraw_)
131 return false; 131 return false;
132 if (DrawSuspendedUntilCommit()) 132 if (DrawSuspendedUntilCommit())
133 return false; 133 return false;
134 return true; 134 return true;
135 } 135 }
136 136
137 bool SchedulerStateMachine::ShouldDraw() const { 137 bool SchedulerStateMachine::ShouldDraw() const {
138 if (needs_forced_redraw_) 138 // After a readback, make sure not to draw again until we've replaced the
139 // readback commit with a real one.
140 if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING ||
141 readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING)
142 return false;
143
144 // Draw outside of the BeginFrame deadline for readbacks.
145 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) {
146 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
139 return true; 147 return true;
148 }
149
150 // If we've lost the output surface or draw is suspended, we want to be able
151 // to abort a draw and make forward progress to unblock the main thread.
152 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
153 DrawSuspendedUntilCommit()) {
154 return (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW ||
155 (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION &&
156 !active_tree_has_been_drawn_));
157 }
158
159 // Except for the cases above, do not draw outside of the BeginFrame deadline.
160 if (begin_frame_state_ != BEGIN_FRAME_STATE_INSIDE_DEADLINE)
161 return false;
162
163 // Only handle forced redraws due to timeouts on the regular deadline.
164 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
165 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
166 return true;
167 }
140 168
141 if (!ScheduledToDraw()) 169 if (!ScheduledToDraw())
142 return false; 170 return false;
143 if (!inside_begin_frame_)
144 return false;
145 if (HasDrawnThisFrame()) 171 if (HasDrawnThisFrame())
146 return false; 172 return false;
147 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 173 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
148 return false; 174 return false;
149 return true; 175 return true;
150 } 176 }
151 177
152 bool SchedulerStateMachine::ShouldAttemptTreeActivation() const { 178 bool SchedulerStateMachine::ShouldAttemptTreeActivation() const {
153 return has_pending_tree_ && inside_begin_frame_ && 179 return !HasAttemptedTreeActivationThisDrawAttempt() &&
154 !HasAttemptedTreeActivationThisFrame(); 180 has_pending_tree_ &&
181 (!can_draw_ || !visible_ ||
182 output_surface_state_ != OUTPUT_SURFACE_ACTIVE ||
183 ((active_tree_has_been_drawn_ || active_tree_is_null_) &&
184 begin_frame_state_ != BEGIN_FRAME_STATE_IDLE));
155 } 185 }
156 186
157 bool SchedulerStateMachine::ShouldCheckForCompletedTileUploads() const { 187 bool SchedulerStateMachine::ShouldCheckForCompletedTileUploads() const {
158 if (!settings_.impl_side_painting) 188 if (!settings_.impl_side_painting)
159 return false; 189 return false;
160 if (HasCheckedForCompletedTileUploadsThisFrame()) 190 if (HasCheckedForCompletedTileUploadsThisDrawAttempt())
161 return false; 191 return false;
162 192
163 return ShouldAttemptTreeActivation() || ShouldDraw() || 193 return ShouldAttemptTreeActivation() || ShouldDraw() ||
164 swap_used_incomplete_tile_; 194 swap_used_incomplete_tile_;
165 } 195 }
166 196
167 bool SchedulerStateMachine::ShouldAcquireLayerTexturesForMainThread() const { 197 bool SchedulerStateMachine::ShouldAcquireLayerTexturesForMainThread() const {
168 if (!main_thread_needs_layer_textures_) 198 if (!main_thread_needs_layer_textures_)
169 return false; 199 return false;
170 if (texture_state_ == LAYER_TEXTURE_STATE_UNLOCKED) 200 if (texture_state_ == LAYER_TEXTURE_STATE_UNLOCKED)
171 return true; 201 return true;
172 DCHECK_EQ(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD); 202 DCHECK_EQ(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD);
173 // Transfer the lock from impl thread to main thread immediately if the 203 // Transfer the lock from impl thread to main thread immediately if the
174 // impl thread is not even scheduled to draw. Guards against deadlocking. 204 // impl thread is not even scheduled to draw. Guards against deadlocking.
175 if (!ScheduledToDraw()) 205 if (!ScheduledToDraw())
176 return true; 206 return true;
177 if (!BeginFrameNeededToDrawByImplThread()) 207 if (!BeginFrameNeededToDrawByImplThread())
178 return true; 208 return true;
179 return false; 209 return false;
180 } 210 }
181 211
212 bool SchedulerStateMachine::ShouldSendBeginFrameToMainThread() const {
213 if (HasSentBeginFrameToMainThreadThisFrame())
214 return false;
215
216 // Only send BeginFrame to the main thread when idle.
217 if (commit_state_ != COMMIT_STATE_IDLE)
218 return false;
219
220 // We can't accept a commit if we have a pending tree.
221 if (has_pending_tree_)
222 return false;
223
224 // We want to handle readback commits ASAP.
225 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED)
226 return !CommitPending();
227
228 // We usually want to slave the main thread's BeginFrame to the impl thread's
229 // BeginFrame. However, if we aren't expecting a BeginFrame on the impl
230 // thread, we should send a BeginFrame to the main thread anyway to make
231 // progress.
232 // TODO(brianderson): Also allow sending BeginFrame to main thread while idle
233 // when the main thread isn't consuming user input.
234 if (begin_frame_state_ == BEGIN_FRAME_STATE_IDLE &&
235 BeginFrameNeededByImplThread())
236 return false;
237
238 // Do not send begin frame to main thread in the deadline until we have drawn.
239 // We have a train to catch!
240 if (begin_frame_state_ == BEGIN_FRAME_STATE_INSIDE_DEADLINE &&
241 !HasDrawnThisFrame())
242 return false;
243
244 // If not impl-side-painting, do not send a BeginFrame to the main thread if
245 // we haven't drawn the active tree. Otherwise, the commit overwrite the
246 // active tree before we have a chance to draw it.
247 if (!settings_.impl_side_painting &&
248 !active_tree_has_been_drawn_ &&
249 !active_tree_is_null_)
250 return false;
251
252 bool can_commit = needs_commit_ &&
253 (visible_ ||
254 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT);
255 return can_commit &&
256 (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT ||
257 output_surface_state_ == OUTPUT_SURFACE_ACTIVE);
258 }
259
182 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 260 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
183 if (ShouldAcquireLayerTexturesForMainThread()) 261 if (ShouldAcquireLayerTexturesForMainThread())
184 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; 262 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD;
185 263
186 switch (commit_state_) { 264 switch (commit_state_) {
187 case COMMIT_STATE_IDLE: 265 case COMMIT_STATE_IDLE:
188 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE && 266 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE &&
189 needs_forced_redraw_) 267 readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED)
190 return ACTION_DRAW_FORCED;
191 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE &&
192 needs_forced_commit_)
193 // TODO(enne): Should probably drop the active tree on force commit.
194 return has_pending_tree_ ? ACTION_NONE 268 return has_pending_tree_ ? ACTION_NONE
195 : ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; 269 : ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD;
196 if (output_surface_state_ == OUTPUT_SURFACE_LOST && can_start_) 270 if (output_surface_state_ == OUTPUT_SURFACE_LOST && can_start_)
197 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; 271 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
198 if (output_surface_state_ == OUTPUT_SURFACE_CREATING) 272 if (output_surface_state_ == OUTPUT_SURFACE_CREATING)
199 return ACTION_NONE; 273 return ACTION_NONE;
200 if (ShouldCheckForCompletedTileUploads()) 274 if (ShouldCheckForCompletedTileUploads())
201 return ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS; 275 return ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS;
202 if (ShouldAttemptTreeActivation()) 276 if (ShouldAttemptTreeActivation())
203 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; 277 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED;
204 if (ShouldDraw()) { 278 if (ShouldDraw())
205 return needs_forced_redraw_ ? ACTION_DRAW_FORCED 279 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
206 : ACTION_DRAW_IF_POSSIBLE; 280 if (ShouldSendBeginFrameToMainThread()) {
281 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD;
207 } 282 }
208 if (needs_commit_ &&
209 ((visible_ && output_surface_state_ == OUTPUT_SURFACE_ACTIVE)
210 || needs_forced_commit_))
211 // TODO(enne): Should probably drop the active tree on force commit.
212 return has_pending_tree_ ? ACTION_NONE
213 : ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD;
214 return ACTION_NONE; 283 return ACTION_NONE;
215 284
216 case COMMIT_STATE_FRAME_IN_PROGRESS: 285 case COMMIT_STATE_FRAME_IN_PROGRESS:
217 if (ShouldCheckForCompletedTileUploads()) 286 if (ShouldCheckForCompletedTileUploads())
218 return ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS; 287 return ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS;
219 if (ShouldAttemptTreeActivation()) 288 if (ShouldAttemptTreeActivation())
220 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; 289 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED;
290 if (ShouldDraw())
291 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
292 return ACTION_NONE;
293
294 case COMMIT_STATE_READY_TO_COMMIT:
295 return ACTION_COMMIT;
296
297 case COMMIT_STATE_WAITING_FOR_ACTIVATION: {
298 if (ShouldCheckForCompletedTileUploads())
299 return ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS;
300 if (ShouldAttemptTreeActivation())
301 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED;
221 if (ShouldDraw()) { 302 if (ShouldDraw()) {
222 return needs_forced_redraw_ ? ACTION_DRAW_FORCED 303 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
223 : ACTION_DRAW_IF_POSSIBLE; 304 DrawSuspendedUntilCommit())
305 return ACTION_DRAW_AND_SWAP_ABORT;
306 else
307 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
224 } 308 }
225 return ACTION_NONE; 309 return ACTION_NONE;
226 310 }
227 case COMMIT_STATE_READY_TO_COMMIT:
228 return ACTION_COMMIT;
229 311
230 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: { 312 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: {
231 if (ShouldCheckForCompletedTileUploads()) 313 if (ShouldCheckForCompletedTileUploads())
232 return ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS; 314 return ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS;
233 if (ShouldAttemptTreeActivation()) 315 if (ShouldAttemptTreeActivation())
234 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; 316 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED;
235 if (ShouldDraw() || output_surface_state_ == OUTPUT_SURFACE_LOST) { 317 if (ShouldDraw()) {
236 return needs_forced_redraw_ ? ACTION_DRAW_FORCED 318 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
237 : ACTION_DRAW_IF_POSSIBLE; 319 return ACTION_DRAW_AND_SWAP_FORCED;
320 else if (readback_state_ ==
321 READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)
322 return ACTION_DRAW_AND_READBACK;
323 else if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
324 DrawSuspendedUntilCommit())
325 return ACTION_DRAW_AND_SWAP_ABORT;
326 else
327 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
238 } 328 }
239 // COMMIT_STATE_WAITING_FOR_FIRST_DRAW wants to enforce a draw. If
240 // can_draw_ is false or textures are not available, proceed to the next
241 // step (similar as in COMMIT_STATE_IDLE).
242 bool can_commit = visible_ || needs_forced_commit_;
243 if (needs_commit_ && can_commit && DrawSuspendedUntilCommit())
244 return has_pending_tree_ ? ACTION_NONE
245 : ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD;
246 return ACTION_NONE; 329 return ACTION_NONE;
247 } 330 }
248
249 case COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW:
250 if (ShouldCheckForCompletedTileUploads())
251 return ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS;
252 if (ShouldAttemptTreeActivation())
253 return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED;
254 if (needs_forced_redraw_)
255 return ACTION_DRAW_FORCED;
256 return ACTION_NONE;
257 } 331 }
258 NOTREACHED(); 332 NOTREACHED();
259 return ACTION_NONE; 333 return ACTION_NONE;
260 } 334 }
261 335
262 void SchedulerStateMachine::UpdateState(Action action) { 336 void SchedulerStateMachine::UpdateState(Action action) {
263 switch (action) { 337 switch (action) {
264 case ACTION_NONE: 338 case ACTION_NONE:
265 return; 339 return;
266 340
267 case ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS: 341 case ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS:
268 last_frame_number_where_check_for_completed_tile_uploads_called_ = 342 last_draw_attempt_count_completed_tile_uploads_checked_ =
269 current_frame_number_; 343 draw_attempt_count_;
270 return; 344 return;
271 345
272 case ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: 346 case ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED:
273 last_frame_number_where_tree_activation_attempted_ = 347 last_draw_attempt_count_tree_activation_attempted_ =
274 current_frame_number_; 348 draw_attempt_count_;
275 return; 349 return;
276 350
277 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: 351 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
278 DCHECK(!has_pending_tree_); 352 DCHECK(!has_pending_tree_);
279 DCHECK(visible_ || needs_forced_commit_); 353 DCHECK(visible_ ||
354 readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED ||
355 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT);
280 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; 356 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
281 needs_commit_ = false; 357 needs_commit_ = false;
282 needs_forced_commit_ = false; 358 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED)
359 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING;
360 last_begin_frame_count_begin_frame_sent_to_main_thread_ =
361 begin_frame_count_;
283 return; 362 return;
284 363
285 case ACTION_COMMIT: 364 case ACTION_COMMIT:
286 commit_count_++; 365 commit_count_++;
287 if (expect_immediate_begin_frame_for_main_thread_) 366
288 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW; 367 if (settings_.impl_side_painting) {
289 else 368 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
369 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION;
370 else if (readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING)
371 readback_state_ = READBACK_STATE_WAITING_FOR_ACTIVATION;
372 else if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING)
373 readback_state_ = READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING;
374 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION;
375 } else {
376 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
377 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
378 else if (readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING)
379 readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
380 else if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING)
381 readback_state_ = READBACK_STATE_IDLE;
290 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; 382 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
291 // When impl-side painting, we draw on activation instead of on commit.
292 if (!settings_.impl_side_painting)
293 needs_redraw_ = true;
294 if (draw_if_possible_failed_)
295 last_frame_number_where_draw_was_called_ = -1;
296
297 if (needs_forced_redraw_after_next_commit_) {
298 needs_forced_redraw_after_next_commit_ = false;
299 needs_forced_redraw_ = true;
300 } 383 }
301 384
385 // When impl-side painting, we draw on activation instead of on commit.
386 if (!settings_.impl_side_painting) {
387 active_tree_has_been_drawn_ = false;
388 needs_redraw_ = true;
389 if (draw_if_possible_failed_)
390 last_begin_frame_count_draw_was_called_ = -1;
391 }
302 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD; 392 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD;
303 return; 393 return;
304 394
305 case ACTION_DRAW_FORCED: 395 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE:
306 case ACTION_DRAW_IF_POSSIBLE: 396 case ACTION_DRAW_AND_SWAP_FORCED:
307 needs_redraw_ = false; 397 case ACTION_DRAW_AND_READBACK:
308 needs_forced_redraw_ = false; 398 case ACTION_DRAW_AND_SWAP_ABORT:
309 draw_if_possible_failed_ = false; 399 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
310 swap_used_incomplete_tile_ = false; 400 commit_state_ = COMMIT_STATE_IDLE;
311 if (inside_begin_frame_) 401 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
312 last_frame_number_where_draw_was_called_ = current_frame_number_; 402 } else if (readback_state_ ==
313 if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW) { 403 READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) {
314 DCHECK(expect_immediate_begin_frame_for_main_thread_); 404 DCHECK(!has_pending_tree_);
315 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; 405 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
316 expect_immediate_begin_frame_for_main_thread_ = false; 406 readback_state_ = READBACK_STATE_REPLACEMENT_COMMIT_PENDING;
317 } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) { 407 } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) {
318 commit_state_ = COMMIT_STATE_IDLE; 408 commit_state_ = COMMIT_STATE_IDLE;
319 } 409 }
410 needs_redraw_ = false;
411 draw_if_possible_failed_ = false;
412 swap_used_incomplete_tile_ = false;
413 last_begin_frame_count_draw_was_called_ = begin_frame_count_;
320 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD) 414 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD)
321 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; 415 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
416 active_tree_has_been_drawn_ = true;
322 return; 417 return;
323 418
324 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 419 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
325 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); 420 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE);
326 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); 421 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST);
327 output_surface_state_ = OUTPUT_SURFACE_CREATING; 422 output_surface_state_ = OUTPUT_SURFACE_CREATING;
328 return; 423 return;
329 424
330 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: 425 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
331 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; 426 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD;
332 main_thread_needs_layer_textures_ = false; 427 main_thread_needs_layer_textures_ = false;
333 return; 428 return;
334 } 429 }
335 } 430 }
336 431
432 void SchedulerStateMachine::AdvanceBeginFrameStateWhenNoActionsRemain() {
433 switch (begin_frame_state_) {
434 case BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME:
435 begin_frame_state_ = BEGIN_FRAME_STATE_DEADLINE_PENDING;
436 break;
437 case BEGIN_FRAME_STATE_INSIDE_DEADLINE:
438 begin_frame_state_ = BEGIN_FRAME_STATE_IDLE;
439 break;
440 case BEGIN_FRAME_STATE_IDLE:
441 case BEGIN_FRAME_STATE_DEADLINE_PENDING:
442 break;
443 }
444 }
445
337 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { 446 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() {
338 DCHECK(!main_thread_needs_layer_textures_); 447 DCHECK(!main_thread_needs_layer_textures_);
339 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); 448 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
340 main_thread_needs_layer_textures_ = true; 449 main_thread_needs_layer_textures_ = true;
341 } 450 }
342 451
452 bool SchedulerStateMachine::BeginFrameNeededByImplThread() const {
453 return BeginFrameNeededToDrawByImplThread() ||
454 BeginFrameProactivelyNeededByImplThread();
455 }
456
343 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { 457 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const {
344 // If we can't draw, don't tick until we are notified that we can draw again. 458 // If we can't draw, don't tick until we are notified that we can draw again.
345 if (!can_draw_) 459 if (!can_draw_)
346 return false; 460 return false;
347 461
348 if (needs_forced_redraw_) 462 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
349 return true; 463 return true;
350 464
351 if (visible_ && swap_used_incomplete_tile_) 465 if (visible_ && swap_used_incomplete_tile_)
352 return true; 466 return true;
353 467
354 return needs_redraw_ && visible_ && 468 return needs_redraw_ && visible_ &&
355 output_surface_state_ == OUTPUT_SURFACE_ACTIVE; 469 output_surface_state_ == OUTPUT_SURFACE_ACTIVE;
356 } 470 }
357 471
358 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const { 472 bool SchedulerStateMachine::BeginFrameProactivelyNeededByImplThread() const {
359 // Do not be proactive when invisible. 473 if (settings_.using_synchronous_renderer_compositor)
474 return false;
475
476 if (!settings_.throttle_frame_production)
477 return false;
478
360 if (!visible_ || output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 479 if (!visible_ || output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
361 return false; 480 return false;
362 481
363 // We should proactively request a BeginFrame if a commit or a tree activation 482 // We should proactively request a BeginFrame if a commit or a tree activation
364 // is pending. 483 // is pending.
365 return (needs_commit_ || needs_forced_commit_ || 484 return (needs_commit_ ||
366 commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_); 485 commit_state_ != COMMIT_STATE_IDLE ||
486 has_pending_tree_);
367 } 487 }
368 488
369 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { 489 void SchedulerStateMachine::OnBeginFrame(const BeginFrameArgs& args) {
370 inside_begin_frame_ = true; 490 begin_frame_count_++;
491 draw_attempt_count_++;
371 last_begin_frame_args_ = args; 492 last_begin_frame_args_ = args;
493 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_BEGIN_FRAME;
372 } 494 }
373 495
374 void SchedulerStateMachine::DidLeaveBeginFrame() { 496 bool SchedulerStateMachine::ShouldTriggerBeginFrameDeadlineEarly() const {
375 current_frame_number_++; 497 // TODO(brianderson): This should take into account multiple commit sources.
376 inside_begin_frame_ = false; 498 return begin_frame_state_ == BEGIN_FRAME_STATE_DEADLINE_PENDING &&
499 !active_tree_has_been_drawn_;
377 } 500 }
378 501
379 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 502 bool SchedulerStateMachine::InsideBeginFrame() const {
503 return begin_frame_state_ != BEGIN_FRAME_STATE_IDLE;
504 }
505
506 void SchedulerStateMachine::OnBeginFrameDeadline() {
507 DCHECK_EQ(begin_frame_state_, BEGIN_FRAME_STATE_DEADLINE_PENDING);
508 draw_attempt_count_++;
509 begin_frame_state_ = BEGIN_FRAME_STATE_INSIDE_DEADLINE;
510 }
511
512 void SchedulerStateMachine::SetVisible(bool visible) {
513 visible_ = visible;
514 }
380 515
381 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 516 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
382 517
383 void SchedulerStateMachine::DidSwapUseIncompleteTile() { 518 void SchedulerStateMachine::DidSwapUseIncompleteTile() {
384 swap_used_incomplete_tile_ = true; 519 swap_used_incomplete_tile_ = true;
385 } 520 }
386 521
387 void SchedulerStateMachine::SetNeedsForcedRedraw() {
388 needs_forced_redraw_ = true;
389 }
390
391 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { 522 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) {
392 draw_if_possible_failed_ = !success; 523 draw_if_possible_failed_ = !success;
393 if (draw_if_possible_failed_) { 524 if (draw_if_possible_failed_) {
394 needs_redraw_ = true; 525 needs_redraw_ = true;
395 needs_commit_ = true; 526 needs_commit_ = true;
396 consecutive_failed_draws_++; 527 consecutive_failed_draws_++;
397 if (settings_.timeout_and_draw_when_animation_checkerboards && 528 if (settings_.timeout_and_draw_when_animation_checkerboards &&
398 consecutive_failed_draws_ >= 529 consecutive_failed_draws_ >=
399 maximum_number_of_failed_draws_before_draw_is_forced_) { 530 maximum_number_of_failed_draws_before_draw_is_forced_) {
400 consecutive_failed_draws_ = 0; 531 consecutive_failed_draws_ = 0;
401 // We need to force a draw, but it doesn't make sense to do this until 532 // We need to force a draw, but it doesn't make sense to do this until
402 // we've committed and have new textures. 533 // we've committed and have new textures.
403 needs_forced_redraw_after_next_commit_ = true; 534 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
404 } 535 }
405 } else { 536 } else {
406 consecutive_failed_draws_ = 0; 537 consecutive_failed_draws_ = 0;
407 } 538 }
408 } 539 }
409 540
410 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; } 541 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; }
411 542
412 void SchedulerStateMachine::SetNeedsForcedCommit() { 543 void SchedulerStateMachine::SetNeedsForcedCommitForReadback() {
413 needs_forced_commit_ = true; 544 DCHECK_EQ(readback_state_, READBACK_STATE_IDLE);
414 expect_immediate_begin_frame_for_main_thread_ = true; 545 if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS)
546 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING;
547 else
548 readback_state_ = READBACK_STATE_FORCED_COMMIT_REQUESTED;
415 } 549 }
416 550
417 void SchedulerStateMachine::FinishCommit() { 551 void SchedulerStateMachine::FinishCommit() {
418 DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || 552 DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS ||
419 (expect_immediate_begin_frame_for_main_thread_ && 553 readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING)
420 commit_state_ != COMMIT_STATE_IDLE))
421 << ToString(); 554 << ToString();
422 commit_state_ = COMMIT_STATE_READY_TO_COMMIT; 555 commit_state_ = COMMIT_STATE_READY_TO_COMMIT;
423 } 556 }
424 557
425 void SchedulerStateMachine::BeginFrameAbortedByMainThread() { 558 void SchedulerStateMachine::BeginFrameAbortedByMainThread() {
426 DCHECK_EQ(commit_state_, COMMIT_STATE_FRAME_IN_PROGRESS); 559 DCHECK_EQ(commit_state_, COMMIT_STATE_FRAME_IN_PROGRESS) << ToString();
427 if (expect_immediate_begin_frame_for_main_thread_) { 560 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED) {
428 expect_immediate_begin_frame_for_main_thread_ = false; 561 readback_state_ = READBACK_STATE_IDLE;
429 } else { 562 } else {
430 commit_state_ = COMMIT_STATE_IDLE; 563 commit_state_ = COMMIT_STATE_IDLE;
431 SetNeedsCommit(); 564 SetNeedsCommit();
432 } 565 }
433 } 566 }
434 567
435 void SchedulerStateMachine::DidLoseOutputSurface() { 568 void SchedulerStateMachine::DidLoseOutputSurface() {
436 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 569 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
437 output_surface_state_ == OUTPUT_SURFACE_CREATING) 570 output_surface_state_ == OUTPUT_SURFACE_CREATING)
438 return; 571 return;
439 output_surface_state_ = OUTPUT_SURFACE_LOST; 572 output_surface_state_ = OUTPUT_SURFACE_LOST;
440 } 573 }
441 574
442 void SchedulerStateMachine::SetHasPendingTree(bool has_pending_tree) { 575 void SchedulerStateMachine::SetHasTrees(bool has_pending_tree,
576 bool active_tree_is_null) {
577 active_tree_is_null_ = active_tree_is_null;
578 if (has_pending_tree_ && !has_pending_tree) {
579 // This is a new activation.
580 draw_attempt_count_++;
581 active_tree_has_been_drawn_ = false;
582
583 if (draw_if_possible_failed_)
584 last_begin_frame_count_draw_was_called_ = -1;
585
586 DCHECK_EQ(COMMIT_STATE_WAITING_FOR_ACTIVATION, commit_state_);
587 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) {
588 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
589 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
590 } else if (readback_state_ == READBACK_STATE_WAITING_FOR_ACTIVATION) {
591 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
592 readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
593 } else {
594 commit_state_ = COMMIT_STATE_IDLE;
595 if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING)
596 readback_state_ = READBACK_STATE_IDLE;
597 }
598 }
599
443 has_pending_tree_ = has_pending_tree; 600 has_pending_tree_ = has_pending_tree;
444 } 601 }
445 602
446 void SchedulerStateMachine::SetCanDraw(bool can) { can_draw_ = can; } 603 void SchedulerStateMachine::SetCanDraw(bool can_draw) {
604 can_draw_ = can_draw;
605 }
447 606
448 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { 607 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
449 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); 608 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
450 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 609 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
451 610
452 if (did_create_and_initialize_first_output_surface_) { 611 if (did_create_and_initialize_first_output_surface_) {
453 // TODO(boliu): See if we can remove this when impl-side painting is always 612 // TODO(boliu): See if we can remove this when impl-side painting is always
454 // on. Does anything on the main thread need to update after recreate? 613 // on. Does anything on the main thread need to update after recreate?
455 needs_commit_ = true; 614 needs_commit_ = true;
456 // If anything has requested a redraw, we don't want to actually draw 615 // If anything has requested a redraw, we don't want to actually draw
457 // when the output surface is restored until things have a chance to 616 // when the output surface is restored until things have a chance to
458 // sort themselves out with a commit. 617 // sort themselves out with a commit.
459 needs_redraw_ = false; 618 needs_redraw_ = false;
460 } 619 }
461 did_create_and_initialize_first_output_surface_ = true; 620 did_create_and_initialize_first_output_surface_ = true;
462 } 621 }
463 622
464 bool SchedulerStateMachine::HasInitializedOutputSurface() const { 623 bool SchedulerStateMachine::HasInitializedOutputSurface() const {
465 return output_surface_state_ == OUTPUT_SURFACE_ACTIVE; 624 return output_surface_state_ == OUTPUT_SURFACE_ACTIVE;
466 } 625 }
467 626
468 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced( 627 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(
469 int num_draws) { 628 int num_draws) {
470 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws; 629 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws;
471 } 630 }
472 631
473 } // namespace cc 632 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698