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

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: Normal functionality working. More test fixes pending. 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_(false),
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) 269 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
brianderson 2013/08/28 02:52:08 This case is no longer needed because of the Shoul
235 return true; 270 return true;
236 return false; 271 return false;
237 } 272 }
238 273
239 bool SchedulerStateMachine::PendingActivationsShouldBeForced() const { 274 bool SchedulerStateMachine::PendingActivationsShouldBeForced() const {
240 // These are all the cases where, if we do not force activations to make 275 // These are all the cases where, if we do not force activations to make
241 // forward progress, we might deadlock with the main thread. 276 // forward progress, we might deadlock with the main thread.
242 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD) 277 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD)
243 return true; 278 return true;
244 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 279 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
245 output_surface_state_ == OUTPUT_SURFACE_CREATING || 280 output_surface_state_ == OUTPUT_SURFACE_CREATING ||
246 output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) 281 output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
brianderson 2013/08/28 02:52:08 These cases are no longer needed because of the Sh
247 return true; 282 return true;
248 return false; 283 return false;
249 } 284 }
250 285
251 bool SchedulerStateMachine::ShouldBeginOutputSurfaceCreation() const { 286 bool SchedulerStateMachine::ShouldBeginOutputSurfaceCreation() const {
252 // Don't try to initialize too early. 287 // Don't try to initialize too early.
253 if (!can_start_) 288 if (!can_start_)
254 return false; 289 return false;
255 290
256 // We only want to start output surface initialization after the 291 // We only want to start output surface initialization after the
257 // previous commit is complete. 292 // previous commit is complete.
258 if (commit_state_ != COMMIT_STATE_IDLE) 293 if (commit_state_ != COMMIT_STATE_IDLE)
259 return false; 294 return false;
260 295
261 // We need to create the output surface if we don't have one and we haven't 296 // We need to create the output surface if we don't have one and we haven't
262 // started creating one yet. 297 // started creating one yet.
263 return output_surface_state_ == OUTPUT_SURFACE_LOST; 298 return output_surface_state_ == OUTPUT_SURFACE_LOST;
264 } 299 }
265 300
266 bool SchedulerStateMachine::ShouldDraw() const { 301 bool SchedulerStateMachine::ShouldDraw() const {
267 // We should not draw or abort draws while we are waiting for the 302 // We should not draw or abort draws while we are waiting for the
268 // first activation. Doing so will cause us to transition to 303 // first activation. Doing so will cause us to transition to
269 // COMMIT_STATE_IDLE and start the 2nd commit before the 1st commit 304 // COMMIT_STATE_IDLE and start the 2nd commit before the 1st commit
270 // has been drawn. It will also cause us to fail readbacks when we could 305 // has been drawn. It will also cause us to fail readbacks when we could
271 // have succeeded by waiting a little longer. 306 // have succeeded by waiting a little longer.
272 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) 307 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
brianderson 2013/08/28 02:52:08 This is no longer needed because of changes to the
273 return false; 308 return false;
274 309
275 // When we are waiting for a forced draw, only force draw once 310 // After a readback, make sure not to draw again until we've replaced the
276 // needs_forced_redraw_ is true. 311 // readback commit with a real one.
277 if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW) 312 if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING ||
278 return needs_forced_redraw_; 313 readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING)
314 return false;
279 315
280 // Always handle forced draws ASAP. 316 // Draw immediately for readbacks to unblock the main thread quickly.
281 if (needs_forced_redraw_) 317 if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) {
318 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
282 return true; 319 return true;
320 }
283 321
284 // If we need to abort draws, we should do so ASAP since the draw could 322 // 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), 323 // be blocking other important actions (like output surface initialization),
286 // from occuring. If we are waiting for the first draw, then perfom the 324 // 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 325 // 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. 326 // draw however, we don't want to abort for no reason.
289 if (PendingDrawsShouldBeAborted()) 327 if (PendingDrawsShouldBeAborted())
290 return commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW; 328 return commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
291 329
292 // After this line, we only want to draw once per frame. 330 // After this line, we only want to draw once per frame.
293 if (HasDrawnThisFrame()) 331 if (HasDrawnThisFrame())
294 return false; 332 return false;
295 333
296 // We currently only draw within the BeginFrame. 334 // We currently only draw within the BeginFrame.
297 if (!inside_begin_frame_) 335 if (!inside_begin_frame_)
298 return false; 336 return false;
299 337
338 // Only handle forced redraws due to timeouts on the regular deadline.
339 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
340 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
341 return true;
342 }
343
300 return needs_redraw_; 344 return needs_redraw_;
301 } 345 }
302 346
303 bool SchedulerStateMachine::ShouldAcquireLayerTexturesForMainThread() const { 347 bool SchedulerStateMachine::ShouldAcquireLayerTexturesForMainThread() const {
304 if (!main_thread_needs_layer_textures_) 348 if (!main_thread_needs_layer_textures_)
305 return false; 349 return false;
306 if (texture_state_ == LAYER_TEXTURE_STATE_UNLOCKED) 350 if (texture_state_ == LAYER_TEXTURE_STATE_UNLOCKED)
307 return true; 351 return true;
308 DCHECK_EQ(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD); 352 DCHECK_EQ(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD);
309 return false; 353 return false;
310 } 354 }
311 355
312 bool SchedulerStateMachine::ShouldActivatePendingTree() const { 356 bool SchedulerStateMachine::ShouldActivatePendingTree() const {
313 // There is nothing to activate. 357 // There is nothing to activate.
314 if (!has_pending_tree_) 358 if (!has_pending_tree_)
315 return false; 359 return false;
316 360
361 // If this is our first activation, we don't want to activate early.
362 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
363 return pending_tree_is_ready_for_activation_;
364
317 // We don't want to activate a second tree before drawing the first one. 365 // 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 366 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; 367 return false;
324 368
325 // If we want to force activation, do so ASAP. 369 // If we want to force activation, do so ASAP.
326 if (PendingActivationsShouldBeForced()) 370 if (PendingActivationsShouldBeForced())
327 return true; 371 return true;
328 372
329 // At this point, only activate if we are ready to activate. 373 // At this point, only activate if we are ready to activate.
330 return pending_tree_is_ready_for_activation_; 374 return pending_tree_is_ready_for_activation_;
331 } 375 }
332 376
(...skipping 26 matching lines...) Expand all
359 return false; 403 return false;
360 404
361 // Only send BeginFrame to the main thread when idle. 405 // Only send BeginFrame to the main thread when idle.
362 if (commit_state_ != COMMIT_STATE_IDLE) 406 if (commit_state_ != COMMIT_STATE_IDLE)
363 return false; 407 return false;
364 408
365 // We can't accept a commit if we have a pending tree. 409 // We can't accept a commit if we have a pending tree.
366 if (has_pending_tree_) 410 if (has_pending_tree_)
367 return false; 411 return false;
368 412
369 // We want to start forced commits ASAP. 413 // We want to handle readback commits immediately to unblock the main thread.
370 if (needs_forced_commit_) 414 // Note: This BeginFrame will correspond to the replacement commit that comes
371 return true; 415 // after the readback commit itself, so we only send the BeginFrame if a
416 // commit isn't already pending behind the readback.
417 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED)
418 return !CommitPending();
372 419
373 // We do not need commits if we are not visible, unless there's a 420 // We do not need commits if we are not visible, unless there's a
374 // request for a forced commit. 421 // request for a forced commit.
375 if (!visible_) 422 if (!visible_)
376 return false; 423 return false;
377 424
378 // We want to start the first commit after we get a new output surface ASAP. 425 // 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) 426 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT)
380 return true; 427 return true;
381 428
429 // We need a new commit for the forced redraw. This honors the
430 // single commit per interval because the result will be swapped to screen.
431 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT)
432 return true;
433
382 // After this point, we only start a commit once per frame. 434 // After this point, we only start a commit once per frame.
383 if (HasSentBeginFrameToMainThreadThisFrame()) 435 if (HasSentBeginFrameToMainThreadThisFrame())
384 return false; 436 return false;
385 437
386 // We shouldn't normally accept commits if there isn't an OutputSurface. 438 // We shouldn't normally accept commits if there isn't an OutputSurface.
387 if (!HasInitializedOutputSurface()) 439 if (!HasInitializedOutputSurface())
388 return false; 440 return false;
389 441
390 return true; 442 return true;
391 } 443 }
392 444
393 bool SchedulerStateMachine::ShouldCommit() const { 445 bool SchedulerStateMachine::ShouldCommit() const {
394 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; 446 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT;
395 } 447 }
396 448
397 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 449 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
398 if (ShouldAcquireLayerTexturesForMainThread()) 450 if (ShouldAcquireLayerTexturesForMainThread())
399 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD; 451 return ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD;
400 if (ShouldUpdateVisibleTiles()) 452 if (ShouldUpdateVisibleTiles())
401 return ACTION_UPDATE_VISIBLE_TILES; 453 return ACTION_UPDATE_VISIBLE_TILES;
402 if (ShouldActivatePendingTree()) 454 if (ShouldActivatePendingTree())
403 return ACTION_ACTIVATE_PENDING_TREE; 455 return ACTION_ACTIVATE_PENDING_TREE;
404 if (ShouldCommit()) 456 if (ShouldCommit())
405 return ACTION_COMMIT; 457 return ACTION_COMMIT;
406 if (ShouldDraw()) { 458 if (ShouldDraw()) {
407 if (needs_forced_redraw_) 459 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
408 return ACTION_DRAW_FORCED; 460 return ACTION_DRAW_AND_SWAP_FORCED;
461 else if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)
462 return ACTION_DRAW_AND_READBACK;
409 else if (PendingDrawsShouldBeAborted()) 463 else if (PendingDrawsShouldBeAborted())
410 return ACTION_DRAW_AND_SWAP_ABORT; 464 return ACTION_DRAW_AND_SWAP_ABORT;
411 else 465 else
412 return ACTION_DRAW_IF_POSSIBLE; 466 return ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
413 } 467 }
414 if (ShouldSendBeginFrameToMainThread()) 468 if (ShouldSendBeginFrameToMainThread())
415 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD; 469 return ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD;
416 if (ShouldBeginOutputSurfaceCreation()) 470 if (ShouldBeginOutputSurfaceCreation())
417 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION; 471 return ACTION_BEGIN_OUTPUT_SURFACE_CREATION;
418 return ACTION_NONE; 472 return ACTION_NONE;
419 } 473 }
420 474
475 void SchedulerStateMachine::CheckInvariants() {
476 // We should never try to perform a draw for readback and forced draw due to
477 // timeout simultaneously.
478 DCHECK(!(forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW &&
479 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK));
480 }
481
421 void SchedulerStateMachine::UpdateState(Action action) { 482 void SchedulerStateMachine::UpdateState(Action action) {
422 switch (action) { 483 switch (action) {
423 case ACTION_NONE: 484 case ACTION_NONE:
424 return; 485 return;
425 486
426 case ACTION_UPDATE_VISIBLE_TILES: 487 case ACTION_UPDATE_VISIBLE_TILES:
427 last_frame_number_where_update_visible_tiles_was_called_ = 488 last_frame_number_where_update_visible_tiles_was_called_ =
428 current_frame_number_; 489 current_frame_number_;
429 return; 490 return;
430 491
431 case ACTION_ACTIVATE_PENDING_TREE: 492 case ACTION_ACTIVATE_PENDING_TREE:
432 UpdateStateOnActivation(); 493 UpdateStateOnActivation();
433 return; 494 return;
434 495
435 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: 496 case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
436 DCHECK(!has_pending_tree_); 497 DCHECK(!has_pending_tree_);
437 if (!needs_forced_commit_ && 498 DCHECK(visible_ ||
438 output_surface_state_ != OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { 499 readback_state_ == READBACK_STATE_FORCED_COMMIT_REQUESTED ||
439 DCHECK(visible_); 500 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT ||
440 DCHECK_GT(current_frame_number_, 501 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; 502 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
444 needs_commit_ = false; 503 needs_commit_ = false;
445 needs_forced_commit_ = false;
446 last_frame_number_where_begin_frame_sent_to_main_thread_ = 504 last_frame_number_where_begin_frame_sent_to_main_thread_ =
447 current_frame_number_; 505 current_frame_number_;
448 return; 506 return;
449 507
450 case ACTION_COMMIT: { 508 case ACTION_COMMIT: {
451 bool commit_was_aborted = false; 509 bool commit_was_aborted = false;
452 UpdateStateOnCommit(commit_was_aborted); 510 UpdateStateOnCommit(commit_was_aborted);
453 return; 511 return;
454 } 512 }
455 513
456 case ACTION_DRAW_FORCED: 514 case ACTION_DRAW_AND_SWAP_FORCED:
457 case ACTION_DRAW_IF_POSSIBLE: { 515 case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: {
458 bool did_swap = true; 516 bool did_swap = true;
459 UpdateStateOnDraw(did_swap); 517 UpdateStateOnDraw(did_swap);
460 return; 518 return;
461 } 519 }
462 520
463 case ACTION_DRAW_AND_SWAP_ABORT: { 521 case ACTION_DRAW_AND_SWAP_ABORT:
522 case ACTION_DRAW_AND_READBACK: {
464 bool did_swap = false; 523 bool did_swap = false;
465 UpdateStateOnDraw(did_swap); 524 UpdateStateOnDraw(did_swap);
466 return; 525 return;
467 } 526 }
468 527
469 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: 528 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
470 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE); 529 DCHECK_EQ(commit_state_, COMMIT_STATE_IDLE);
471 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST); 530 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_LOST);
472 output_surface_state_ = OUTPUT_SURFACE_CREATING; 531 output_surface_state_ = OUTPUT_SURFACE_CREATING;
473 return; 532 return;
474 533
475 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD: 534 case ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
476 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD; 535 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD;
477 main_thread_needs_layer_textures_ = false; 536 main_thread_needs_layer_textures_ = false;
478 return; 537 return;
479 } 538 }
480 } 539 }
481 540
482 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { 541 void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) {
483 commit_count_++; 542 commit_count_++;
484 543
485 // If we are impl-side-painting but the commit was aborted, then we behave 544 // 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. 545 // mostly as if we are not impl-side-painting since there is no pending tree.
487 has_pending_tree_ = 546 has_pending_tree_ =
488 settings_.impl_side_painting && !commit_was_aborted; 547 settings_.impl_side_painting && !commit_was_aborted;
489 548
490 // Update the commit state.
491 if (expect_immediate_begin_frame_for_main_thread_)
492 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW;
493 else if (!commit_was_aborted)
494 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
495 else
496 commit_state_ = COMMIT_STATE_IDLE;
497
498 // Update the output surface state. 549 // Update the output surface state.
499 DCHECK_NE(output_surface_state_, 550 DCHECK_NE(output_surface_state_,
500 OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); 551 OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
501 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { 552 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) {
502 if (has_pending_tree_) { 553 if (has_pending_tree_) {
503 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION; 554 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION;
504 } else { 555 } else {
505 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 556 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
506 needs_redraw_ = true; 557 needs_redraw_ = true;
507 } 558 }
508 } 559 }
509 560
561 // Update state related to readbacks.
562 if (readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING) {
563 // Update the state if this is the readback commit.
564 readback_state_ = has_pending_tree_
565 ? READBACK_STATE_WAITING_FOR_ACTIVATION
566 : READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
567 } else if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING) {
568 // Update the state if this is the commit replacing the readback commit.
569 readback_state_ = has_pending_tree_
570 ? READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING
571 : READBACK_STATE_IDLE;
572 } else {
573 DCHECK(readback_state_ == READBACK_STATE_IDLE);
574 }
575
576 // Update state related to forced draws.
577 // Note: It's possible for the readback's replacement commit to be the
578 // forced redraw's commit.
579 if (readback_state_ == READBACK_STATE_IDLE &&
580 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) {
581 forced_redraw_state_ = has_pending_tree_
582 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
583 : FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
584 }
585
586 // Update the commit state. We expect and wait for a draw if the commit
587 // was not aborted or if we in a readback or forced draw.
588 if (!commit_was_aborted)
589 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
590 else if (readback_state_ != READBACK_STATE_IDLE ||
591 forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE)
592 commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW;
593 else
594 commit_state_ = COMMIT_STATE_IDLE;
595
510 // Update state if we have a new active tree to draw, or if the active tree 596 // 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. 597 // was unchanged but we need to do a readback or forced draw.
512 if (!has_pending_tree_ && 598 if (!has_pending_tree_ &&
513 (!commit_was_aborted || expect_immediate_begin_frame_for_main_thread_)) { 599 (!commit_was_aborted ||
600 readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK ||
601 forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) {
514 needs_redraw_ = true; 602 needs_redraw_ = true;
515 active_tree_has_been_drawn_ = false; 603 active_tree_has_been_drawn_ = false;
516 } 604 }
517 605
518 // This post-commit work is common to both completed and aborted commits. 606 // This post-commit work is common to both completed and aborted commits.
519 pending_tree_is_ready_for_activation_ = false; 607 pending_tree_is_ready_for_activation_ = false;
520 608
521 if (draw_if_possible_failed_) 609 if (draw_if_possible_failed_)
522 last_frame_number_where_draw_was_called_ = -1; 610 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 611
529 // If we are planing to draw with the new commit, lock the layer textures for 612 // 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. 613 // use on the impl thread. Otherwise, leave them unlocked.
531 if (has_pending_tree_ || needs_redraw_ || needs_forced_redraw_) 614 if (has_pending_tree_ || needs_redraw_)
532 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD; 615 texture_state_ = LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD;
533 else 616 else
534 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; 617 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
535 } 618 }
536 619
537 void SchedulerStateMachine::UpdateStateOnActivation() { 620 void SchedulerStateMachine::UpdateStateOnActivation() {
621 // Update output surface state.
538 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) 622 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION)
539 output_surface_state_ = OUTPUT_SURFACE_ACTIVE; 623 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
540 624
625 // Update readback state
626 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION)
627 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
628
629 // Update forced redraw state
630 if (readback_state_ == READBACK_STATE_WAITING_FOR_ACTIVATION)
631 readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
632 else if (readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_ACTIVATING)
633 readback_state_ = READBACK_STATE_IDLE;
634
541 has_pending_tree_ = false; 635 has_pending_tree_ = false;
542 pending_tree_is_ready_for_activation_ = false; 636 pending_tree_is_ready_for_activation_ = false;
543 active_tree_has_been_drawn_ = false; 637 active_tree_has_been_drawn_ = false;
544 needs_redraw_ = true; 638 needs_redraw_ = true;
545 } 639 }
546 640
547 void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) { 641 void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) {
548 if (inside_begin_frame_) 642 DCHECK(needs_redraw_);
549 last_frame_number_where_draw_was_called_ = current_frame_number_; 643
550 if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW) { 644 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
551 DCHECK(expect_immediate_begin_frame_for_main_thread_); 645 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
646 commit_state_ = COMMIT_STATE_IDLE;
647 forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
648 } else if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) {
649 // The draw correspons to a readback commit.
650 DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
651 // We are blocking commits from the main thread until after this draw, so
652 // we should not have a pending tree.
653 DCHECK(!has_pending_tree_);
654 // We transition to COMMIT_STATE_FRAME_IN_PROGRESS because there is a
655 // pending BeginFrame on the main thread behind the readback request.
552 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; 656 commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS;
553 expect_immediate_begin_frame_for_main_thread_ = false; 657 readback_state_ = READBACK_STATE_REPLACEMENT_COMMIT_PENDING;
554 } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) { 658 } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) {
555 commit_state_ = COMMIT_STATE_IDLE; 659 commit_state_ = COMMIT_STATE_IDLE;
556 } 660 }
661
557 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD) 662 if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD)
558 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; 663 texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED;
559 664
560 needs_redraw_ = false; 665 needs_redraw_ = false;
561 needs_forced_redraw_ = false;
562 draw_if_possible_failed_ = false; 666 draw_if_possible_failed_ = false;
563 active_tree_has_been_drawn_ = true; 667 active_tree_has_been_drawn_ = true;
564 668
565 if (did_swap) 669 if (did_swap) {
566 swap_used_incomplete_tile_ = false; 670 swap_used_incomplete_tile_ = false;
671 last_frame_number_swap_performed_ = current_frame_number_;
672 }
567 } 673 }
568 674
569 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { 675 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() {
570 DCHECK(!main_thread_needs_layer_textures_); 676 DCHECK(!main_thread_needs_layer_textures_);
571 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); 677 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD);
572 main_thread_needs_layer_textures_ = true; 678 main_thread_needs_layer_textures_ = true;
573 } 679 }
574 680
681 // These are the cases where we definitely (or almost definitely) have a
682 // new frame to draw and can draw.
575 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const { 683 bool SchedulerStateMachine::BeginFrameNeededToDrawByImplThread() const {
684 // The output surface is the provider of BeginFrames for the impl thread,
685 // so we are not going to get them even if we ask for them.
686 if (!HasInitializedOutputSurface())
687 return false;
688
576 // If we can't draw, don't tick until we are notified that we can draw again. 689 // If we can't draw, don't tick until we are notified that we can draw again.
577 if (!can_draw_) 690 if (!can_draw_)
578 return false; 691 return false;
579 692
580 if (needs_forced_redraw_) 693 // The forced draw respects our normal draw scheduling, so we need to
694 // request a BeginFrame on the impl thread for it.
695 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
581 return true; 696 return true;
582 697
583 if (visible_ && swap_used_incomplete_tile_) 698 // There's no need to produce frames if we are not visible.
699 if (!visible_)
700 return false;
701
702 // We need to draw a more complete frame than we did the last BeginFrame,
703 // so request another BeginFrame in anticipation that we will have
704 // additional visible tiles.
705 if (swap_used_incomplete_tile_)
584 return true; 706 return true;
585 707
586 return needs_redraw_ && visible_ && HasInitializedOutputSurface(); 708 return needs_redraw_;
587 } 709 }
588 710
711 // These are cases where we are very likely to draw soon, but might not
712 // actually have a new frame to draw when we receive the next BeginFrame.
713 // Proactively requesting the BeginFrame helps hide the round trip latency of
714 // the SetNeedsBeginFrame request that has to go to the Browser.
715 // However, this is bad for the synchronous compoisitor because we have to
716 // draw when we get the BeginFrame and could end up drawing many duplicate
717 // frames.
589 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const { 718 bool SchedulerStateMachine::ProactiveBeginFrameWantedByImplThread() const {
590 // The output surface is the provider of BeginFrames for the impl thread, 719 // 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. 720 // so we are not going to get them even if we ask for them.
592 if (!HasInitializedOutputSurface()) 721 if (!HasInitializedOutputSurface())
593 return false; 722 return false;
594 723
595 // Do not be proactive when invisible. 724 // Do not be proactive when invisible.
596 if (!visible_) 725 if (!visible_)
597 return false; 726 return false;
598 727
599 // We should proactively request a BeginFrame if a commit or a tree activation 728 // We should proactively request a BeginFrame if a commit is pending
600 // is pending. 729 // because we will want to draw if the commit completes quickly.
601 return (needs_commit_ || needs_forced_commit_ || 730 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE)
602 commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_); 731 return true;
732
733 // If the pending tree activates quickly, we'll want a BeginFrame soon
734 // to draw the new active tree.
735 if (has_pending_tree_)
736 return true;
737
738 return false;
603 } 739 }
604 740
605 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) { 741 void SchedulerStateMachine::DidEnterBeginFrame(const BeginFrameArgs& args) {
606 current_frame_number_++; 742 current_frame_number_++;
607 inside_begin_frame_ = true; 743 inside_begin_frame_ = true;
608 last_begin_frame_args_ = args; 744 last_begin_frame_args_ = args;
609 } 745 }
610 746
611 void SchedulerStateMachine::DidLeaveBeginFrame() { 747 void SchedulerStateMachine::DidLeaveBeginFrame() {
612 inside_begin_frame_ = false; 748 inside_begin_frame_ = false;
613 } 749 }
614 750
615 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } 751 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; }
616 752
617 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 753 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
618 754
619 void SchedulerStateMachine::DidSwapUseIncompleteTile() { 755 void SchedulerStateMachine::DidSwapUseIncompleteTile() {
620 swap_used_incomplete_tile_ = true; 756 swap_used_incomplete_tile_ = true;
621 } 757 }
622 758
623 void SchedulerStateMachine::SetNeedsForcedRedraw() {
624 needs_forced_redraw_ = true;
625 }
626
627 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) { 759 void SchedulerStateMachine::DidDrawIfPossibleCompleted(bool success) {
628 draw_if_possible_failed_ = !success; 760 draw_if_possible_failed_ = !success;
629 if (draw_if_possible_failed_) { 761 if (draw_if_possible_failed_) {
630 needs_redraw_ = true; 762 needs_redraw_ = true;
631 needs_commit_ = true; 763 needs_commit_ = true;
632 consecutive_failed_draws_++; 764 consecutive_failed_draws_++;
633 if (settings_.timeout_and_draw_when_animation_checkerboards && 765 if (settings_.timeout_and_draw_when_animation_checkerboards &&
634 consecutive_failed_draws_ >= 766 consecutive_failed_draws_ >=
635 maximum_number_of_failed_draws_before_draw_is_forced_) { 767 maximum_number_of_failed_draws_before_draw_is_forced_) {
636 consecutive_failed_draws_ = 0; 768 consecutive_failed_draws_ = 0;
637 // We need to force a draw, but it doesn't make sense to do this until 769 // We need to force a draw, but it doesn't make sense to do this until
638 // we've committed and have new textures. 770 // we've committed and have new textures.
639 needs_forced_redraw_after_next_commit_ = true; 771 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
640 } 772 }
641 } else { 773 } else {
642 consecutive_failed_draws_ = 0; 774 consecutive_failed_draws_ = 0;
643 } 775 }
644 } 776 }
645 777
646 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; } 778 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; }
647 779
648 void SchedulerStateMachine::SetNeedsForcedCommit() { 780 void SchedulerStateMachine::SetNeedsForcedCommitForReadback() {
649 needs_forced_commit_ = true; 781 // If this is called in READBACK_STATE_IDLE, this is a "first" readback
650 expect_immediate_begin_frame_for_main_thread_ = true; 782 // request.
783 // If this is called in READBACK_STATE_REPLACEMENT_COMMIT_PENDING, this
784 // is a back-to-back readback request that started before the replacement
785 // commit had a chance to land.
786 DCHECK(readback_state_ == READBACK_STATE_IDLE ||
787 readback_state_ == READBACK_STATE_REPLACEMENT_COMMIT_PENDING);
788
789 // If there is already a commit in progress when we get the readback request
790 // (we are in COMMIT_STATE_FRAME_IN_PROGRESS), then we don't need to send a
791 // BeginFrame for the replacement commit, since there's already a BeginFrame
792 // behind the readback request.
793 if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS)
794 readback_state_ = READBACK_STATE_FORCED_COMMIT_PENDING;
795 else
796 readback_state_ = READBACK_STATE_FORCED_COMMIT_REQUESTED;
651 } 797 }
652 798
653 void SchedulerStateMachine::FinishCommit() { 799 void SchedulerStateMachine::FinishCommit() {
654 DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || 800 DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS ||
655 (expect_immediate_begin_frame_for_main_thread_ && 801 readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING)
656 commit_state_ != COMMIT_STATE_IDLE))
657 << *AsValue(); 802 << *AsValue();
658 commit_state_ = COMMIT_STATE_READY_TO_COMMIT; 803 commit_state_ = COMMIT_STATE_READY_TO_COMMIT;
659 } 804 }
660 805
661 void SchedulerStateMachine::BeginFrameAbortedByMainThread(bool did_handle) { 806 void SchedulerStateMachine::BeginFrameAbortedByMainThread(bool did_handle) {
662 DCHECK_EQ(commit_state_, COMMIT_STATE_FRAME_IN_PROGRESS); 807 DCHECK_EQ(commit_state_, COMMIT_STATE_FRAME_IN_PROGRESS);
663 if (did_handle) { 808 if (did_handle) {
664 bool commit_was_aborted = true; 809 bool commit_was_aborted = true;
665 UpdateStateOnCommit(commit_was_aborted); 810 UpdateStateOnCommit(commit_was_aborted);
666 } else if (expect_immediate_begin_frame_for_main_thread_) { 811 } else if (readback_state_ == READBACK_STATE_FORCED_COMMIT_PENDING) {
667 expect_immediate_begin_frame_for_main_thread_ = false; 812 readback_state_ = READBACK_STATE_IDLE;
668 } else { 813 } else {
669 commit_state_ = COMMIT_STATE_IDLE; 814 commit_state_ = COMMIT_STATE_IDLE;
670 SetNeedsCommit(); 815 SetNeedsCommit();
671 } 816 }
672 } 817 }
673 818
674 void SchedulerStateMachine::DidLoseOutputSurface() { 819 void SchedulerStateMachine::DidLoseOutputSurface() {
675 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 820 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
676 output_surface_state_ == OUTPUT_SURFACE_CREATING) 821 output_surface_state_ == OUTPUT_SURFACE_CREATING)
677 return; 822 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
712 NOTREACHED(); 857 NOTREACHED();
713 return false; 858 return false;
714 } 859 }
715 860
716 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced( 861 void SchedulerStateMachine::SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(
717 int num_draws) { 862 int num_draws) {
718 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws; 863 maximum_number_of_failed_draws_before_draw_is_forced_ = num_draws;
719 } 864 }
720 865
721 } // namespace cc 866 } // 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