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

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

Issue 23503003: cc: Add readback and forced draw states to the Scheduler (Closed) Base URL: http://git.chromium.org/chromium/src.git@schedReorg3
Patch Set: rename needs_draw_and_swap_ back to needs_redraw_ 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_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 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED),
19 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE),
20 readback_state_(READBACK_STATE_IDLE),
18 commit_count_(0), 21 commit_count_(0),
19 current_frame_number_(0), 22 current_frame_number_(0),
20 last_frame_number_where_begin_frame_sent_to_main_thread_(-1), 23 last_frame_number_where_begin_frame_sent_to_main_thread_(-1),
21 last_frame_number_where_draw_was_called_(-1), 24 last_frame_number_swap_performed_(-1),
22 last_frame_number_where_update_visible_tiles_was_called_(-1), 25 last_frame_number_where_update_visible_tiles_was_called_(-1),
23 consecutive_failed_draws_(0), 26 consecutive_failed_draws_(0),
24 maximum_number_of_failed_draws_before_draw_is_forced_(3), 27 maximum_number_of_failed_draws_before_draw_is_forced_(3),
25 needs_redraw_(false), 28 needs_redraw_(false),
26 swap_used_incomplete_tile_(false), 29 swap_used_incomplete_tile_(false),
27 needs_forced_redraw_(false),
28 needs_forced_redraw_after_next_commit_(false),
29 needs_commit_(false), 30 needs_commit_(false),
30 needs_forced_commit_(false),
31 expect_immediate_begin_frame_for_main_thread_(false),
32 main_thread_needs_layer_textures_(false), 31 main_thread_needs_layer_textures_(false),
33 inside_begin_frame_(false), 32 inside_begin_frame_(false),
34 visible_(false), 33 visible_(false),
35 can_start_(false), 34 can_start_(false),
36 can_draw_(false), 35 can_draw_(false),
37 has_pending_tree_(false), 36 has_pending_tree_(false),
38 pending_tree_is_ready_for_activation_(false), 37 pending_tree_is_ready_for_activation_(false),
39 active_tree_has_been_drawn_(false), 38 active_tree_has_been_drawn_(true),
40 draw_if_possible_failed_(false), 39 draw_if_possible_failed_(false),
41 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED),
42 did_create_and_initialize_first_output_surface_(false) {} 40 did_create_and_initialize_first_output_surface_(false) {}
43 41
44 const char* SchedulerStateMachine::OutputSurfaceStateToString( 42 const char* SchedulerStateMachine::OutputSurfaceStateToString(
45 OutputSurfaceState state) { 43 OutputSurfaceState state) {
46 switch (state) { 44 switch (state) {
47 case OUTPUT_SURFACE_ACTIVE: 45 case OUTPUT_SURFACE_ACTIVE:
48 return "OUTPUT_SURFACE_ACTIVE"; 46 return "OUTPUT_SURFACE_ACTIVE";
49 case OUTPUT_SURFACE_LOST: 47 case OUTPUT_SURFACE_LOST:
50 return "OUTPUT_SURFACE_LOST"; 48 return "OUTPUT_SURFACE_LOST";
51 case OUTPUT_SURFACE_CREATING: 49 case OUTPUT_SURFACE_CREATING:
(...skipping 10 matching lines...) Expand all
62 const char* SchedulerStateMachine::CommitStateToString(CommitState state) { 60 const char* SchedulerStateMachine::CommitStateToString(CommitState state) {
63 switch (state) { 61 switch (state) {
64 case COMMIT_STATE_IDLE: 62 case COMMIT_STATE_IDLE:
65 return "COMMIT_STATE_IDLE"; 63 return "COMMIT_STATE_IDLE";
66 case COMMIT_STATE_FRAME_IN_PROGRESS: 64 case COMMIT_STATE_FRAME_IN_PROGRESS:
67 return "COMMIT_STATE_FRAME_IN_PROGRESS"; 65 return "COMMIT_STATE_FRAME_IN_PROGRESS";
68 case COMMIT_STATE_READY_TO_COMMIT: 66 case COMMIT_STATE_READY_TO_COMMIT:
69 return "COMMIT_STATE_READY_TO_COMMIT"; 67 return "COMMIT_STATE_READY_TO_COMMIT";
70 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: 68 case COMMIT_STATE_WAITING_FOR_FIRST_DRAW:
71 return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW"; 69 return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW";
72 case COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW:
73 return "COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW";
74 } 70 }
75 NOTREACHED(); 71 NOTREACHED();
76 return "???"; 72 return "???";
77 } 73 }
78 74
79 const char* SchedulerStateMachine::TextureStateToString(TextureState state) { 75 const char* SchedulerStateMachine::TextureStateToString(TextureState state) {
80 switch (state) { 76 switch (state) {
81 case LAYER_TEXTURE_STATE_UNLOCKED: 77 case LAYER_TEXTURE_STATE_UNLOCKED:
82 return "LAYER_TEXTURE_STATE_UNLOCKED"; 78 return "LAYER_TEXTURE_STATE_UNLOCKED";
83 case LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD: 79 case LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD:
84 return "LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD"; 80 return "LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD";
85 case LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD: 81 case LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD:
86 return "LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD"; 82 return "LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD";
87 } 83 }
88 NOTREACHED(); 84 NOTREACHED();
89 return "???"; 85 return "???";
90 } 86 }
91 87
88 const char* SchedulerStateMachine::SynchronousReadbackStateToString(
89 SynchronousReadbackState state) {
90 switch (state) {
91 case READBACK_STATE_IDLE:
92 return "READBACK_STATE_IDLE";
93 case READBACK_STATE_FORCED_COMMIT_REQUESTED:
94 return "READBACK_STATE_FORCED_COMMIT_REQUESTED";
95 case READBACK_STATE_FORCED_COMMIT_PENDING:
96 return "READBACK_STATE_FORCED_COMMIT_PENDING";
97 case READBACK_STATE_WAITING_FOR_ACTIVATION:
98 return "READBACK_STATE_WAITING_FOR_ACTIVATION";
99 case READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK:
100 return "READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK";
101 case READBACK_STATE_REPLACEMENT_COMMIT_PENDING:
102 return "READBACK_STATE_REPLACEMENT_COMMIT_PENDING";
103 case READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING:
104 return "READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING";
105 }
106 NOTREACHED();
107 return "???";
108 }
109
110 const char* SchedulerStateMachine::ForcedRedrawOnTimeoutStateToString(
111 ForcedRedrawOnTimeoutState state) {
112 switch (state) {
113 case FORCED_REDRAW_STATE_IDLE:
114 return "FORCED_REDRAW_STATE_IDLE";
115 case FORCED_REDRAW_STATE_WAITING_FOR_COMMIT:
116 return "FORCED_REDRAW_STATE_WAITING_FOR_COMMIT";
117 case FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION:
118 return "FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION";
119 case FORCED_REDRAW_STATE_WAITING_FOR_DRAW:
120 return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW";
121 }
122 NOTREACHED();
123 return "???";
124 }
125
92 const char* SchedulerStateMachine::ActionToString(Action action) { 126 const char* SchedulerStateMachine::ActionToString(Action action) {
93 switch (action) { 127 switch (action) {
94 case ACTION_NONE: 128 case ACTION_NONE:
95 return "ACTION_NONE"; 129 return "ACTION_NONE";
96 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: 130 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
97 return "ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD"; 131 return "ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD";
98 case ACTION_COMMIT: 132 case ACTION_COMMIT:
99 return "ACTION_COMMIT"; 133 return "ACTION_COMMIT";
100 case ACTION_UPDATE_VISIBLE_TILES: 134 case ACTION_UPDATE_VISIBLE_TILES:
101 return "ACTION_UPDATE_VISIBLE_TILES"; 135 return "ACTION_UPDATE_VISIBLE_TILES";
102 case ACTION_ACTIVATE_PENDING_TREE: 136 case ACTION_ACTIVATE_PENDING_TREE:
103 return "ACTION_ACTIVATE_PENDING_TREE"; 137 return "ACTION_ACTIVATE_PENDING_TREE";
104 case ACTION_DRAW_IF_POSSIBLE: 138 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE:
105 return "ACTION_DRAW_IF_POSSIBLE"; 139 return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE";
106 case ACTION_DRAW_FORCED: 140 case ACTION_DRAW_AND_SWAP_FORCED:
107 return "ACTION_DRAW_FORCED"; 141 return "ACTION_DRAW_AND_SWAP_FORCED";
108 case ACTION_DRAW_AND_SWAP_ABORT: 142 case ACTION_DRAW_AND_SWAP_ABORT:
109 return "ACTION_DRAW_AND_SWAP_ABORT"; 143 return "ACTION_DRAW_AND_SWAP_ABORT";
144 case ACTION_DRAW_AND_READBACK:
145 return "ACTION_DRAW_AND_READBACK";
110 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 146 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
111 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; 147 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION";
112 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: 148 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
113 return "ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD"; 149 return "ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD";
114 } 150 }
115 NOTREACHED(); 151 NOTREACHED();
116 return "???"; 152 return "???";
117 } 153 }
118 154
119 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { 155 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const {
120 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); 156 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
121 157
122 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue); 158 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue);
123 major_state->SetString("next_action", ActionToString(NextAction())); 159 major_state->SetString("next_action", ActionToString(NextAction()));
124 major_state->SetString("commit_state", CommitStateToString(commit_state_)); 160 major_state->SetString("commit_state", CommitStateToString(commit_state_));
125 major_state->SetString("texture_state_", 161 major_state->SetString("texture_state_",
126 TextureStateToString(texture_state_)); 162 TextureStateToString(texture_state_));
127 major_state->SetString("output_surface_state_", 163 major_state->SetString("output_surface_state_",
128 OutputSurfaceStateToString(output_surface_state_)); 164 OutputSurfaceStateToString(output_surface_state_));
165 major_state->SetString(
166 "forced_redraw_state",
167 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
168 major_state->SetString("readback_state",
169 SynchronousReadbackStateToString(readback_state_));
129 state->Set("major_state", major_state.release()); 170 state->Set("major_state", major_state.release());
130 171
131 scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue); 172 scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue);
132 base::TimeTicks now = base::TimeTicks::Now(); 173 base::TimeTicks now = base::TimeTicks::Now();
133 timestamps_state->SetDouble( 174 timestamps_state->SetDouble(
134 "0_interval", last_begin_frame_args_.interval.InMicroseconds() / 1000.0L); 175 "0_interval", last_begin_frame_args_.interval.InMicroseconds() / 1000.0L);
135 timestamps_state->SetDouble( 176 timestamps_state->SetDouble(
136 "1_now_to_deadline", 177 "1_now_to_deadline",
137 (last_begin_frame_args_.deadline - now).InMicroseconds() / 1000.0L); 178 (last_begin_frame_args_.deadline - now).InMicroseconds() / 1000.0L);
138 timestamps_state->SetDouble( 179 timestamps_state->SetDouble(
139 "2_frame_time_to_now", 180 "2_frame_time_to_now",
140 (last_begin_frame_args_.deadline - now).InMicroseconds() / 1000.0L); 181 (now - last_begin_frame_args_.frame_time).InMicroseconds() / 1000.0L);
141 timestamps_state->SetDouble( 182 timestamps_state->SetDouble(
142 "3_frame_time_to_deadline", 183 "3_frame_time_to_deadline",
143 (last_begin_frame_args_.deadline - last_begin_frame_args_.frame_time) 184 (last_begin_frame_args_.deadline - last_begin_frame_args_.frame_time)
144 .InMicroseconds() / 185 .InMicroseconds() /
145 1000.0L); 186 1000.0L);
146 timestamps_state->SetDouble( 187 timestamps_state->SetDouble(
147 "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L); 188 "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L);
148 timestamps_state->SetDouble( 189 timestamps_state->SetDouble(
149 "5_frame_time", 190 "5_frame_time",
150 (last_begin_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / 191 (last_begin_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() /
151 1000.0L); 192 1000.0L);
152 timestamps_state->SetDouble( 193 timestamps_state->SetDouble(
153 "6_deadline", 194 "6_deadline",
154 (last_begin_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / 195 (last_begin_frame_args_.deadline - base::TimeTicks()).InMicroseconds() /
155 1000.0L); 196 1000.0L);
156 state->Set("major_timestamps_in_ms", timestamps_state.release()); 197 state->Set("major_timestamps_in_ms", timestamps_state.release());
157 198
158 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); 199 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue);
159 minor_state->SetInteger("commit_count", commit_count_); 200 minor_state->SetInteger("commit_count", commit_count_);
160 minor_state->SetInteger("current_frame_number", current_frame_number_); 201 minor_state->SetInteger("current_frame_number", current_frame_number_);
161 minor_state->SetInteger( 202 minor_state->SetInteger(
162 "last_frame_number_where_begin_frame_sent_to_main_thread", 203 "last_frame_number_where_begin_frame_sent_to_main_thread",
163 last_frame_number_where_begin_frame_sent_to_main_thread_); 204 last_frame_number_where_begin_frame_sent_to_main_thread_);
164 minor_state->SetInteger("last_frame_number_where_draw_was_called", 205 minor_state->SetInteger("last_frame_number_where_draw_was_called",
165 last_frame_number_where_draw_was_called_); 206 last_frame_number_swap_performed_);
166 minor_state->SetInteger( 207 minor_state->SetInteger(
167 "last_frame_number_where_update_visible_tiles_was_called", 208 "last_frame_number_where_update_visible_tiles_was_called",
168 last_frame_number_where_update_visible_tiles_was_called_); 209 last_frame_number_where_update_visible_tiles_was_called_);
169 minor_state->SetInteger("consecutive_failed_draws", 210 minor_state->SetInteger("consecutive_failed_draws",
170 consecutive_failed_draws_); 211 consecutive_failed_draws_);
171 minor_state->SetInteger( 212 minor_state->SetInteger(
172 "maximum_number_of_failed_draws_before_draw_is_forced", 213 "maximum_number_of_failed_draws_before_draw_is_forced",
173 maximum_number_of_failed_draws_before_draw_is_forced_); 214 maximum_number_of_failed_draws_before_draw_is_forced_);
174 minor_state->SetBoolean("needs_redraw", needs_redraw_); 215 minor_state->SetBoolean("needs_redraw", needs_redraw_);
175 minor_state->SetBoolean("swap_used_incomplete_tile", 216 minor_state->SetBoolean("swap_used_incomplete_tile",
176 swap_used_incomplete_tile_); 217 swap_used_incomplete_tile_);
177 minor_state->SetBoolean("needs_forced_redraw", needs_forced_redraw_);
178 minor_state->SetBoolean("needs_forced_redraw_after_next_commit",
179 needs_forced_redraw_after_next_commit_);
180 minor_state->SetBoolean("needs_commit", needs_commit_); 218 minor_state->SetBoolean("needs_commit", needs_commit_);
181 minor_state->SetBoolean("needs_forced_commit", needs_forced_commit_);
182 minor_state->SetBoolean("expect_immediate_begin_frame_for_main_thread",
183 expect_immediate_begin_frame_for_main_thread_);
184 minor_state->SetBoolean("main_thread_needs_layer_textures", 219 minor_state->SetBoolean("main_thread_needs_layer_textures",
185 main_thread_needs_layer_textures_); 220 main_thread_needs_layer_textures_);
186 minor_state->SetBoolean("inside_begin_frame", inside_begin_frame_); 221 minor_state->SetBoolean("inside_begin_frame", inside_begin_frame_);
187 minor_state->SetBoolean("visible", visible_); 222 minor_state->SetBoolean("visible", visible_);
188 minor_state->SetBoolean("can_start", can_start_); 223 minor_state->SetBoolean("can_start", can_start_);
189 minor_state->SetBoolean("can_draw", can_draw_); 224 minor_state->SetBoolean("can_draw", can_draw_);
190 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); 225 minor_state->SetBoolean("has_pending_tree", has_pending_tree_);
191 minor_state->SetBoolean("pending_tree_is_ready_for_activation_", 226 minor_state->SetBoolean("pending_tree_is_ready_for_activation_",
192 pending_tree_is_ready_for_activation_); 227 pending_tree_is_ready_for_activation_);
193 minor_state->SetBoolean("active_tree_has_been_drawn_", 228 minor_state->SetBoolean("active_tree_has_been_drawn_",
194 active_tree_has_been_drawn_); 229 active_tree_has_been_drawn_);
195 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); 230 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_);
196 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", 231 minor_state->SetBoolean("did_create_and_initialize_first_output_surface",
197 did_create_and_initialize_first_output_surface_); 232 did_create_and_initialize_first_output_surface_);
198 state->Set("minor_state", minor_state.release()); 233 state->Set("minor_state", minor_state.release());
199 234
200 return state.PassAs<base::Value>(); 235 return state.PassAs<base::Value>();
201 } 236 }
202 237
203 bool SchedulerStateMachine::HasDrawnThisFrame() const { 238 bool SchedulerStateMachine::HasDrawnThisFrame() const {
204 return current_frame_number_ == last_frame_number_where_draw_was_called_; 239 return current_frame_number_ == last_frame_number_swap_performed_;
205 } 240 }
206 241
207 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { 242 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const {
208 return current_frame_number_ == 243 return current_frame_number_ ==
209 last_frame_number_where_update_visible_tiles_was_called_; 244 last_frame_number_where_update_visible_tiles_was_called_;
210 } 245 }
211 246
212 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const { 247 bool SchedulerStateMachine::HasSentBeginFrameToMainThreadThisFrame() const {
213 return current_frame_number_ == 248 return current_frame_number_ ==
214 last_frame_number_where_begin_frame_sent_to_main_thread_; 249 last_frame_number_where_begin_frame_sent_to_main_thread_;
215 } 250 }
216 251
217 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const { 252 bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
218 // These are all the cases where we normally cannot or do not want to draw 253 // These are all the cases where we normally cannot or do not want to draw
219 // but, if needs_redraw_ is true and we do not draw to make forward progress, 254 // but, if needs_redraw_ is true and we do not draw to make forward progress,
220 // we might deadlock with the main thread. 255 // we might deadlock with the main thread.
221 // This should be a superset of PendingActivationsShouldBeForced() since 256 // This should be a superset of PendingActivationsShouldBeForced() since
222 // activation of the pending tree is blocked by drawing of the active tree and 257 // activation of the pending tree is blocked by drawing of the active tree and
223 // the main thread might be blocked on activation of the most recent commit. 258 // the main thread might be blocked on activation of the most recent commit.
224 if (PendingActivationsShouldBeForced()) 259 if (PendingActivationsShouldBeForced())
225 return true; 260 return true;
226 261
227 // Additional states where we should abort draws. 262 // Additional states where we should abort draws.
228 // Note: We don't force activation in these cases because doing so would 263 // Note: We don't force activation in these cases because doing so would
229 // result in checkerboarding on resize, becoming visible, etc. 264 // result in checkerboarding on resize, becoming visible, etc.
230 if (!can_draw_) 265 if (!can_draw_)
231 return true; 266 return true;
232 if (!visible_) 267 if (!visible_)
233 return true; 268 return true;
234 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
235 return true;
236 return false; 269 return false;
237 } 270 }
238 271
239 bool SchedulerStateMachine::PendingActivationsShouldBeForced() const { 272 bool SchedulerStateMachine::PendingActivationsShouldBeForced() const {
240 // These are all the cases where, if we do not force activations to make 273 // These are all the cases where, if we do not force activations to make
241 // forward progress, we might deadlock with the main thread. 274 // forward progress, we might deadlock with the main thread.
242 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD) 275 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD)
243 return true; 276 return true;
244 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 277
245 output_surface_state_ == OUTPUT_SURFACE_CREATING || 278 // There is no output surface to trigger our activations.
246 output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) 279 if (output_surface_state_ == OUTPUT_SURFACE_LOST)
247 return true; 280 return true;
281
248 return false; 282 return false;
249 } 283 }
250 284
251 bool SchedulerStateMachine::ShouldBeginOutputSurfaceCreation() const { 285 bool SchedulerStateMachine::ShouldBeginOutputSurfaceCreation() const {
252 // Don't try to initialize too early. 286 // Don't try to initialize too early.
253 if (!can_start_) 287 if (!can_start_)
254 return false; 288 return false;
255 289
256 // We only want to start output surface initialization after the 290 // We only want to start output surface initialization after the
257 // previous commit is complete. 291 // previous commit is complete.
258 if (commit_state_ != COMMIT_STATE_IDLE) 292 if (commit_state_ != COMMIT_STATE_IDLE)
259 return false; 293 return false;
260 294
295 // We want to clear the pipline of any pending draws and activations
296 // before starting output surface initialization. This allows us to avoid
297 // weird corner cases where we abort draws or force activation while we
298 // are initializing the output surface and can potentially have a pending
299 // readback.
300 if (!active_tree_has_been_drawn_ || has_pending_tree_)
301 return false;
302
261 // We need to create the output surface if we don't have one and we haven't 303 // We need to create the output surface if we don't have one and we haven't
262 // started creating one yet. 304 // started creating one yet.
263 return output_surface_state_ == OUTPUT_SURFACE_LOST; 305 return output_surface_state_ == OUTPUT_SURFACE_LOST;
264 } 306 }
265 307
266 bool SchedulerStateMachine::ShouldDraw() const { 308 bool SchedulerStateMachine::ShouldDraw() const {
267 // We should not draw or abort draws while we are waiting for the 309 // After a readback, make sure not to draw again until we've replaced the
268 // first activation. Doing so will cause us to transition to 310 // readback commit with a real one.
269 // COMMIT_STATE_IDLE and start the 2nd commit before the 1st commit 311 if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING ||
270 // has been drawn. It will also cause us to fail readbacks when we could 312 readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING)
271 // have succeeded by waiting a little longer.
272 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
273 return false; 313 return false;
274 314
275 // When we are waiting for a forced draw, only force draw once 315 // Draw immediately for readbacks to unblock the main thread quickly.
276 // needs_forced_redraw_ is true. 316 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) {
277 if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW) 317 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
278 return needs_forced_redraw_;
279
280 // Always handle forced draws ASAP.
281 if (needs_forced_redraw_)
282 return true; 318 return true;
319 }
283 320
284 // If we need to abort draws, we should do so ASAP since the draw could 321 // If we need to abort draws, we should do so ASAP since the draw could
285 // be blocking other important actions (like output surface initialization), 322 // be blocking other important actions (like output surface initialization),
286 // from occuring. If we are waiting for the first draw, then perfom the 323 // from occuring. If we are waiting for the first draw, then perfom the
287 // aborted draw to keep things moving. If we are not waiting for the first 324 // aborted draw to keep things moving. If we are not waiting for the first
288 // draw however, we don't want to abort for no reason. 325 // draw however, we don't want to abort for no reason.
289 if (PendingDrawsShouldBeAborted()) 326 if (PendingDrawsShouldBeAborted())
290 return commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW; 327 return !active_tree_has_been_drawn_;
brianderson 2013/08/28 02:52:08 I changed this because not drawing the active tree
291 328
292 // After this line, we only want to draw once per frame. 329 // After this line, we only want to draw once per frame.
293 if (HasDrawnThisFrame()) 330 if (HasDrawnThisFrame())
294 return false; 331 return false;
295 332
296 // We currently only draw within the BeginFrame. 333 // We currently only draw within the BeginFrame.
297 if (!inside_begin_frame_) 334 if (!inside_begin_frame_)
298 return false; 335 return false;
299 336
337 // Only handle forced redraws due to timeouts on the regular deadline.
338 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
339 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
340 return true;
341 }
342
300 return needs_redraw_; 343 return needs_redraw_;
301 } 344 }
302 345
303 bool SchedulerStateMachine::ShouldAcquireLayerTexturesForMainThread() const { 346 bool SchedulerStateMachine::ShouldAcquireLayerTexturesForMainThread() const {
304 if (!main_thread_needs_layer_textures_) 347 if (!main_thread_needs_layer_textures_)
305 return false; 348 return false;
306 if (texture_state_ == LAYER_TEXTURE_STATE_UNLOCKED) 349 if (texture_state_ == LAYER_TEXTURE_STATE_UNLOCKED)
307 return true; 350 return true;
308 DCHECK_EQ(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD); 351 DCHECK_EQ(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD);
309 return false; 352 return false;
310 } 353 }
311 354
312 bool SchedulerStateMachine::ShouldActivatePendingTree() const { 355 bool SchedulerStateMachine::ShouldActivatePendingTree() const {
313 // There is nothing to activate. 356 // There is nothing to activate.
314 if (!has_pending_tree_) 357 if (!has_pending_tree_)
315 return false; 358 return false;
316 359
360 // If this is our first activation, we don't want to activate early.
361 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
362 return pending_tree_is_ready_for_activation_;
363
317 // We don't want to activate a second tree before drawing the first one. 364 // We don't want to activate a second tree before drawing the first one.
318 // Note: It is possible that there is no active tree to draw when 365 if (!active_tree_has_been_drawn_)
319 // output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION,
320 // so we don't block activation on draw in that case.
321 if (!active_tree_has_been_drawn_ &&
322 output_surface_state_ != OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
323 return false; 366 return false;
324 367
325 // If we want to force activation, do so ASAP. 368 // If we want to force activation, do so ASAP.
326 if (PendingActivationsShouldBeForced()) 369 if (PendingActivationsShouldBeForced())
327 return true; 370 return true;
328 371
329 // At this point, only activate if we are ready to activate. 372 // At this point, only activate if we are ready to activate.
330 return pending_tree_is_ready_for_activation_; 373 return pending_tree_is_ready_for_activation_;
331 } 374 }
332 375
(...skipping 26 matching lines...) Expand all
359 return false; 402 return false;
360 403
361 // Only send BeginFrame to the main thread when idle. 404 // Only send BeginFrame to the main thread when idle.
362 if (commit_state_ != COMMIT_STATE_IDLE) 405 if (commit_state_ != COMMIT_STATE_IDLE)
363 return false; 406 return false;
364 407
365 // We can't accept a commit if we have a pending tree. 408 // We can't accept a commit if we have a pending tree.
366 if (has_pending_tree_) 409 if (has_pending_tree_)
367 return false; 410 return false;
368 411
369 // We want to start forced commits ASAP. 412 // We want to handle readback commits immediately to unblock the main thread.
370 if (needs_forced_commit_) 413 // Note: This BeginFrame will correspond to the replacement commit that comes
371 return true; 414 // after the readback commit itself, so we only send the BeginFrame if a
415 // commit isn't already pending behind the readback.
416 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED)
417 return !CommitPending();
372 418
373 // We do not need commits if we are not visible, unless there's a 419 // We do not need commits if we are not visible, unless there's a
374 // request for a forced commit. 420 // request for a forced commit.
375 if (!visible_) 421 if (!visible_)
376 return false; 422 return false;
377 423
378 // We want to start the first commit after we get a new output surface ASAP. 424 // We want to start the first commit after we get a new output surface ASAP.
379 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) 425 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
380 return true; 426 return true;
381 427
428 // We need a new commit for the forced redraw. This honors the
429 // single commit per interval because the result will be swapped to screen.
430 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
431 return true;
432
382 // After this point, we only start a commit once per frame. 433 // After this point, we only start a commit once per frame.
383 if (HasSentBeginFrameToMainThreadThisFrame()) 434 if (HasSentBeginFrameToMainThreadThisFrame())
384 return false; 435 return false;
385 436
386 // We shouldn't normally accept commits if there isn't an OutputSurface. 437 // We shouldn't normally accept commits if there isn't an OutputSurface.
387 if (!HasInitializedOutputSurface()) 438 if (!HasInitializedOutputSurface())
388 return false; 439 return false;
389 440
390 return true; 441 return true;
391 } 442 }
392 443
393 bool SchedulerStateMachine::ShouldCommit() const { 444 bool SchedulerStateMachine::ShouldCommit() const {
394 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; 445 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
395 } 446 }
396 447
397 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 448 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
398 if (ShouldAcquireLayerTexturesForMainThread()) 449 if (ShouldAcquireLayerTexturesForMainThread())
399 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; 450 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD;
400 if (ShouldUpdateVisibleTiles()) 451 if (ShouldUpdateVisibleTiles())
401 return ACTION_UPDATE_VISIBLE_TILES; 452 return ACTION_UPDATE_VISIBLE_TILES;
402 if (ShouldActivatePendingTree()) 453 if (ShouldActivatePendingTree())
403 return ACTION_ACTIVATE_PENDING_TREE; 454 return ACTION_ACTIVATE_PENDING_TREE;
404 if (ShouldCommit()) 455 if (ShouldCommit())
405 return ACTION_COMMIT; 456 return ACTION_COMMIT;
406 if (ShouldDraw()) { 457 if (ShouldDraw()) {
407 if (needs_forced_redraw_) 458 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
408 return ACTION_DRAW_FORCED; 459 return ACTION_DRAW_AND_SWAP_FORCED;
460 else if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)
461 return ACTION_DRAW_AND_READBACK;
409 else if (PendingDrawsShouldBeAborted()) 462 else if (PendingDrawsShouldBeAborted())
410 return ACTION_DRAW_AND_SWAP_ABORT; 463 return ACTION_DRAW_AND_SWAP_ABORT;
411 else 464 else
412 return ACTION_DRAW_IF_POSSIBLE; 465 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
413 } 466 }
414 if (ShouldSendBeginFrameToMainThread()) 467 if (ShouldSendBeginFrameToMainThread())
415 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; 468 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD;
416 if (ShouldBeginOutputSurfaceCreation()) 469 if (ShouldBeginOutputSurfaceCreation())
417 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; 470 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
418 return ACTION_NONE; 471 return ACTION_NONE;
419 } 472 }
420 473
474 void SchedulerStateMachine::CheckInvariants() {
475 // We should never try to perform a draw for readback and forced draw due to
476 // timeout simultaneously.
477 DCHECK(!(forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW &&
478 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK));
479 }
480
421 void SchedulerStateMachine::UpdateState(Action action) { 481 void SchedulerStateMachine::UpdateState(Action action) {
422 switch (action) { 482 switch (action) {
423 case ACTION_NONE: 483 case ACTION_NONE:
424 return; 484 return;
425 485
426 case ACTION_UPDATE_VISIBLE_TILES: 486 case ACTION_UPDATE_VISIBLE_TILES:
427 last_frame_number_where_update_visible_tiles_was_called_ = 487 last_frame_number_where_update_visible_tiles_was_called_ =
428 current_frame_number_; 488 current_frame_number_;
429 return; 489 return;
430 490
431 case ACTION_ACTIVATE_PENDING_TREE: 491 case ACTION_ACTIVATE_PENDING_TREE:
432 UpdateStateOnActivation(); 492 UpdateStateOnActivation();
433 return; 493 return;
434 494
435 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: 495 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
436 DCHECK(!has_pending_tree_); 496 DCHECK(!has_pending_tree_);
437 if (!needs_forced_commit_ && 497 DCHECK(visible_ ||
438 output_surface_state_ != OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { 498 readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED ||
439 DCHECK(visible_); 499 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT ||
440 DCHECK_GT(current_frame_number_, 500 output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
441 last_frame_number_where_begin_frame_sent_to_main_thread_);
442 }
443 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; 501 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
444 needs_commit_ = false; 502 needs_commit_ = false;
445 needs_forced_commit_ = false; 503 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED)
504 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING;
446 last_frame_number_where_begin_frame_sent_to_main_thread_ = 505 last_frame_number_where_begin_frame_sent_to_main_thread_ =
447 current_frame_number_; 506 current_frame_number_;
448 return; 507 return;
449 508
450 case ACTION_COMMIT: { 509 case ACTION_COMMIT: {
451 bool commit_was_aborted = false; 510 bool commit_was_aborted = false;
452 UpdateStateOnCommit(commit_was_aborted); 511 UpdateStateOnCommit(commit_was_aborted);
453 return; 512 return;
454 } 513 }
455 514
456 case ACTION_DRAW_FORCED: 515 case ACTION_DRAW_AND_SWAP_FORCED:
457 case ACTION_DRAW_IF_POSSIBLE: { 516 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
458 bool did_swap = true; 517 bool did_swap = true;
459 UpdateStateOnDraw(did_swap); 518 UpdateStateOnDraw(did_swap);
460 return; 519 return;
461 } 520 }
462 521
463 case ACTION_DRAW_AND_SWAP_ABORT: { 522 case ACTION_DRAW_AND_SWAP_ABORT:
523 case ACTION_DRAW_AND_READBACK: {
464 bool did_swap = false; 524 bool did_swap = false;
465 UpdateStateOnDraw(did_swap); 525 UpdateStateOnDraw(did_swap);
466 return; 526 return;
467 } 527 }
468 528
469 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 529 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
470 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); 530 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE);
471 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); 531 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST);
472 output_surface_state_ = OUTPUT_SURFACE_CREATING; 532 output_surface_state_ = OUTPUT_SURFACE_CREATING;
473 return; 533 return;
474 534
475 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: 535 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
476 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; 536 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD;
477 main_thread_needs_layer_textures_ = false; 537 main_thread_needs_layer_textures_ = false;
478 return; 538 return;
479 } 539 }
480 } 540 }
481 541
482 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { 542 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) {
483 commit_count_++; 543 commit_count_++;
484 544
485 // If we are impl-side-painting but the commit was aborted, then we behave 545 // If we are impl-side-painting but the commit was aborted, then we behave
486 // mostly as if we are not impl-side-painting since there is no pending tree. 546 // mostly as if we are not impl-side-painting since there is no pending tree.
487 has_pending_tree_ = 547 has_pending_tree_ =
488 settings_.impl_side_painting && !commit_was_aborted; 548 settings_.impl_side_painting && !commit_was_aborted;
489 549
490 // Update the commit state. 550 // Update state related to readbacks.
491 if (expect_immediate_begin_frame_for_main_thread_) 551 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING) {
492 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW; 552 // Update the state if this is the readback commit.
493 else if (!commit_was_aborted) 553 readback_state_ = has_pending_tree_
554 ? READBACK_STATE_WAITING_FOR_ACTIVATION
555 : READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
556 } else if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING) {
557 // Update the state if this is the commit replacing the readback commit.
558 readback_state_ = has_pending_tree_
559 ? READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING
560 : READBACK_STATE_IDLE;
561 } else {
562 DCHECK(readback_state_ == READBACK_STATE_IDLE);
563 }
564
565 // Readbacks can interrupt output surface initialization and forced draws,
566 // so we do not want to advance those states unless readback is idle.
567 // Note: It is possible for the readback's replacement commit to be the
568 // output surface's first commit and/or the forced redraw's commit.
569 if (readback_state_ == READBACK_STATE_IDLE) {
570 // Update state related to forced draws.
571 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) {
572 forced_redraw_state_ = has_pending_tree_
573 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
574 : FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
575 }
576
577 // Update the output surface state.
578 DCHECK_NE(output_surface_state_,
579 OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
580 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) {
581 if (has_pending_tree_) {
582 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION;
583 } else {
584 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
585 needs_redraw_ = true;
586 }
587 }
588 }
589
590 // Update the commit state. We expect and wait for a draw if the commit
591 // was not aborted or if we in a readback or forced draw.
592 if (!commit_was_aborted)
593 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
594 else if (readback_state_ != READBACK_STATE_IDLE ||
595 forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE)
494 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; 596 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
495 else 597 else
496 commit_state_ = COMMIT_STATE_IDLE; 598 commit_state_ = COMMIT_STATE_IDLE;
497 599
498 // Update the output surface state.
499 DCHECK_NE(output_surface_state_,
500 OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
501 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) {
502 if (has_pending_tree_) {
503 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION;
504 } else {
505 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
506 needs_redraw_ = true;
507 }
508 }
509
510 // Update state if we have a new active tree to draw, or if the active tree 600 // Update state if we have a new active tree to draw, or if the active tree
511 // was unchanged but we need to do a readback. 601 // was unchanged but we need to do a readback or forced draw.
512 if (!has_pending_tree_ && 602 if (!has_pending_tree_ &&
513 (!commit_was_aborted || expect_immediate_begin_frame_for_main_thread_)) { 603 (!commit_was_aborted ||
604 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK ||
605 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) {
514 needs_redraw_ = true; 606 needs_redraw_ = true;
515 active_tree_has_been_drawn_ = false; 607 active_tree_has_been_drawn_ = false;
516 } 608 }
517 609
518 // This post-commit work is common to both completed and aborted commits. 610 // This post-commit work is common to both completed and aborted commits.
519 pending_tree_is_ready_for_activation_ = false; 611 pending_tree_is_ready_for_activation_ = false;
520 612
521 if (draw_if_possible_failed_) 613 if (draw_if_possible_failed_)
522 last_frame_number_where_draw_was_called_ = -1; 614 last_frame_number_swap_performed_ = -1;
523
524 if (needs_forced_redraw_after_next_commit_) {
525 needs_forced_redraw_after_next_commit_ = false;
526 needs_forced_redraw_ = true;
527 }
528 615
529 // If we are planing to draw with the new commit, lock the layer textures for 616 // If we are planing to draw with the new commit, lock the layer textures for
530 // use on the impl thread. Otherwise, leave them unlocked. 617 // use on the impl thread. Otherwise, leave them unlocked.
531 if (has_pending_tree_ || needs_redraw_ || needs_forced_redraw_) 618 if (has_pending_tree_ || needs_redraw_)
532 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD; 619 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD;
533 else 620 else
534 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; 621 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
535 } 622 }
536 623
537 void SchedulerStateMachine::UpdateStateOnActivation() { 624 void SchedulerStateMachine::UpdateStateOnActivation() {
625 // Update output surface state.
538 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) 626 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
539 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 627 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
540 628
629 // Update readback state
630 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION)
631 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
632
633 // Update forced redraw state
634 if (readback_state_ == READBACK_STATE_WAITING_FOR_ACTIVATION)
635 readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
636 else if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING)
637 readback_state_ = READBACK_STATE_IDLE;
638
541 has_pending_tree_ = false; 639 has_pending_tree_ = false;
542 pending_tree_is_ready_for_activation_ = false; 640 pending_tree_is_ready_for_activation_ = false;
543 active_tree_has_been_drawn_ = false; 641 active_tree_has_been_drawn_ = false;
544 needs_redraw_ = true; 642 needs_redraw_ = true;
545 } 643 }
546 644
547 void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) { 645 void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) {
548 if (inside_begin_frame_) 646 DCHECK(readback_state_ != READBACK_STATE_REPLACEMENT_COMMIT_PENDING &&
549 last_frame_number_where_draw_was_called_ = current_frame_number_; 647 readback_state_ != READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING)
550 if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW) { 648 << *AsValue();
551 DCHECK(expect_immediate_begin_frame_for_main_thread_); 649
650 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) {
651 // The draw correspons to a readback commit.
652 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
653 // We are blocking commits from the main thread until after this draw, so
654 // we should not have a pending tree.
655 DCHECK(!has_pending_tree_);
656 // We transition to COMMIT_STATE_FRAME_IN_PROGRESS because there is a
657 // pending BeginFrame on the main thread behind the readback request.
552 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; 658 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
553 expect_immediate_begin_frame_for_main_thread_ = false; 659 readback_state_ = READBACK_STATE_REPLACEMENT_COMMIT_PENDING;
554 } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) { 660 } else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
661 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
662 commit_state_ = COMMIT_STATE_IDLE;
663 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
664 } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW &&
665 !has_pending_tree_) {
555 commit_state_ = COMMIT_STATE_IDLE; 666 commit_state_ = COMMIT_STATE_IDLE;
556 } 667 }
668
557 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD) 669 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD)
558 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; 670 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
559 671
560 needs_redraw_ = false; 672 needs_redraw_ = false;
561 needs_forced_redraw_ = false;
562 draw_if_possible_failed_ = false; 673 draw_if_possible_failed_ = false;
563 active_tree_has_been_drawn_ = true; 674 active_tree_has_been_drawn_ = true;
564 675
565 if (did_swap) 676 if (did_swap) {
566 swap_used_incomplete_tile_ = false; 677 swap_used_incomplete_tile_ = false;
678 last_frame_number_swap_performed_ = current_frame_number_;
679 }
567 } 680 }
568 681
569 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { 682 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() {
570 DCHECK(!main_thread_needs_layer_textures_); 683 DCHECK(!main_thread_needs_layer_textures_);
571 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); 684 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
572 main_thread_needs_layer_textures_ = true; 685 main_thread_needs_layer_textures_ = true;
573 } 686 }
574 687
688 // These are the cases where we definitely (or almost definitely) have a
689 // new frame to draw and can draw.
575 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { 690 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const {
691 // The output surface is the provider of BeginFrames for the impl thread,
692 // so we are not going to get them even if we ask for them.
693 if (!HasInitializedOutputSurface())
694 return false;
695
576 // If we can't draw, don't tick until we are notified that we can draw again. 696 // If we can't draw, don't tick until we are notified that we can draw again.
577 if (!can_draw_) 697 if (!can_draw_)
578 return false; 698 return false;
579 699
580 if (needs_forced_redraw_) 700 // The forced draw respects our normal draw scheduling, so we need to
701 // request a BeginFrame on the impl thread for it.
702 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
581 return true; 703 return true;
582 704
583 if (visible_ && swap_used_incomplete_tile_) 705 // There's no need to produce frames if we are not visible.
706 if (!visible_)
707 return false;
708
709 // We need to draw a more complete frame than we did the last BeginFrame,
710 // so request another BeginFrame in anticipation that we will have
711 // additional visible tiles.
712 if (swap_used_incomplete_tile_)
584 return true; 713 return true;
585 714
586 return needs_redraw_ && visible_ && HasInitializedOutputSurface(); 715 return needs_redraw_;
587 } 716 }
588 717
718 // These are cases where we are very likely to draw soon, but might not
719 // actually have a new frame to draw when we receive the next BeginFrame.
720 // Proactively requesting the BeginFrame helps hide the round trip latency of
721 // the SetNeedsBeginFrame request that has to go to the Browser.
722 // However, this is bad for the synchronous compoisitor because we have to
723 // draw when we get the BeginFrame and could end up drawing many duplicate
724 // frames.
589 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const { 725 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const {
590 // The output surface is the provider of BeginFrames for the impl thread, 726 // The output surface is the provider of BeginFrames for the impl thread,
591 // so we are not going to get them even if we ask for them. 727 // so we are not going to get them even if we ask for them.
592 if (!HasInitializedOutputSurface()) 728 if (!HasInitializedOutputSurface())
593 return false; 729 return false;
594 730
595 // Do not be proactive when invisible. 731 // Do not be proactive when invisible.
596 if (!visible_) 732 if (!visible_)
597 return false; 733 return false;
598 734
599 // We should proactively request a BeginFrame if a commit or a tree activation 735 // We should proactively request a BeginFrame if a commit is pending
600 // is pending. 736 // because we will want to draw if the commit completes quickly.
601 return (needs_commit_ || needs_forced_commit_ || 737 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE)
602 commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_); 738 return true;
739
740 // If the pending tree activates quickly, we'll want a BeginFrame soon
741 // to draw the new active tree.
742 if (has_pending_tree_)
743 return true;
744
745 return false;
603 } 746 }
604 747
605 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { 748 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) {
606 current_frame_number_++; 749 current_frame_number_++;
607 inside_begin_frame_ = true; 750 inside_begin_frame_ = true;
608 last_begin_frame_args_ = args; 751 last_begin_frame_args_ = args;
609 } 752 }
610 753
611 void SchedulerStateMachine::DidLeaveBeginFrame() { 754 void SchedulerStateMachine::DidLeaveBeginFrame() {
612 inside_begin_frame_ = false; 755 inside_begin_frame_ = false;
613 } 756 }
614 757
615 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 758 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
616 759
617 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 760 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
618 761
619 void SchedulerStateMachine::DidSwapUseIncompleteTile() { 762 void SchedulerStateMachine::DidSwapUseIncompleteTile() {
620 swap_used_incomplete_tile_ = true; 763 swap_used_incomplete_tile_ = true;
621 } 764 }
622 765
623 void SchedulerStateMachine::SetNeedsForcedRedraw() {
624 needs_forced_redraw_ = true;
625 }
626
627 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { 766 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) {
628 draw_if_possible_failed_ = !success; 767 draw_if_possible_failed_ = !success;
629 if (draw_if_possible_failed_) { 768 if (draw_if_possible_failed_) {
630 needs_redraw_ = true; 769 needs_redraw_ = true;
631 needs_commit_ = true; 770 needs_commit_ = true;
632 consecutive_failed_draws_++; 771 consecutive_failed_draws_++;
633 if (settings_.timeout_and_draw_when_animation_checkerboards && 772 if (settings_.timeout_and_draw_when_animation_checkerboards &&
634 consecutive_failed_draws_ >= 773 consecutive_failed_draws_ >=
635 maximum_number_of_failed_draws_before_draw_is_forced_) { 774 maximum_number_of_failed_draws_before_draw_is_forced_) {
636 consecutive_failed_draws_ = 0; 775 consecutive_failed_draws_ = 0;
637 // We need to force a draw, but it doesn't make sense to do this until 776 // We need to force a draw, but it doesn't make sense to do this until
638 // we've committed and have new textures. 777 // we've committed and have new textures.
639 needs_forced_redraw_after_next_commit_ = true; 778 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
640 } 779 }
641 } else { 780 } else {
642 consecutive_failed_draws_ = 0; 781 consecutive_failed_draws_ = 0;
643 } 782 }
644 } 783 }
645 784
646 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; } 785 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; }
647 786
648 void SchedulerStateMachine::SetNeedsForcedCommit() { 787 void SchedulerStateMachine::SetNeedsForcedCommitForReadback() {
649 needs_forced_commit_ = true; 788 // If this is called in READBACK_STATE_IDLE, this is a "first" readback
650 expect_immediate_begin_frame_for_main_thread_ = true; 789 // request.
790 // If this is called in READBACK_STATE_REPLACEMENT_COMMIT_PENDING, this
791 // is a back-to-back readback request that started before the replacement
792 // commit had a chance to land.
793 DCHECK(readback_state_ == READBACK_STATE_IDLE ||
794 readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING);
795
796 // If there is already a commit in progress when we get the readback request
797 // (we are in COMMIT_STATE_FRAME_IN_PROGRESS), then we don't need to send a
798 // BeginFrame for the replacement commit, since there's already a BeginFrame
799 // behind the readback request. In that case, we can skip
800 // READBACK_STATE_FORCED_COMMIT_REQUESTED and go directly to
801 // READBACK_STATE_FORCED_COMMIT_PENDING
802 if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS)
803 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING;
804 else
805 readback_state_ = READBACK_STATE_FORCED_COMMIT_REQUESTED;
651 } 806 }
652 807
653 void SchedulerStateMachine::FinishCommit() { 808 void SchedulerStateMachine::FinishCommit() {
654 DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || 809 DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS)
655 (expect_immediate_begin_frame_for_main_thread_ &&
656 commit_state_ != COMMIT_STATE_IDLE))
657 << *AsValue(); 810 << *AsValue();
658 commit_state_ = COMMIT_STATE_READY_TO_COMMIT; 811 commit_state_ = COMMIT_STATE_READY_TO_COMMIT;
659 } 812 }
660 813
661 void SchedulerStateMachine::BeginFrameAbortedByMainThread(bool did_handle) { 814 void SchedulerStateMachine::BeginFrameAbortedByMainThread(bool did_handle) {
662 DCHECK_EQ(commit_state_, COMMIT_STATE_FRAME_IN_PROGRESS); 815 DCHECK_EQ(commit_state_, COMMIT_STATE_FRAME_IN_PROGRESS);
663 if (did_handle) { 816 if (did_handle) {
664 bool commit_was_aborted = true; 817 bool commit_was_aborted = true;
665 UpdateStateOnCommit(commit_was_aborted); 818 UpdateStateOnCommit(commit_was_aborted);
666 } else if (expect_immediate_begin_frame_for_main_thread_) { 819 } else if (readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING) {
667 expect_immediate_begin_frame_for_main_thread_ = false; 820 readback_state_ = READBACK_STATE_IDLE;
668 } else { 821 } else {
669 commit_state_ = COMMIT_STATE_IDLE; 822 commit_state_ = COMMIT_STATE_IDLE;
670 SetNeedsCommit(); 823 SetNeedsCommit();
671 } 824 }
672 } 825 }
673 826
674 void SchedulerStateMachine::DidLoseOutputSurface() { 827 void SchedulerStateMachine::DidLoseOutputSurface() {
675 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 828 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
676 output_surface_state_ == OUTPUT_SURFACE_CREATING) 829 output_surface_state_ == OUTPUT_SURFACE_CREATING)
677 return; 830 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 NOTREACHED(); 865 NOTREACHED();
713 return false; 866 return false;
714 } 867 }
715 868
716 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced( 869 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(
717 int num_draws) { 870 int num_draws) {
718 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws; 871 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws;
719 } 872 }
720 873
721 } // namespace cc 874 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | cc/scheduler/scheduler_state_machine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698