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

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

Issue 16871016: cc: Use BeginFrameArgs (Closed) Base URL: http://git.chromium.org/chromium/src.git@bfargs2
Patch Set: Add an --enable-deadline-scheduler commandline flag. Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 The Chromium Authors. All rights reserved. 1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4
5 #include "cc/scheduler/scheduler.h" 4 #include "cc/scheduler/scheduler.h"
6 5
7 #include <string> 6 #include <string>
8 #include <vector> 7 #include <vector>
9 8
10 #include "base/logging.h" 9 #include "base/logging.h"
11 #include "cc/test/scheduler_test_common.h" 10 #include "cc/test/scheduler_test_common.h"
12 #include "testing/gmock/include/gmock/gmock.h" 11 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
14 13
15 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \ 14 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
16 EXPECT_EQ(expected_num_actions, client.num_actions_()); \ 15 EXPECT_EQ(expected_num_actions, client.num_actions_()); \
17 ASSERT_LT(action_index, client.num_actions_()); \ 16 ASSERT_LT(action_index, client.num_actions_()); \
18 do { \ 17 do { \
19 EXPECT_STREQ(action, client.Action(action_index)); \ 18 EXPECT_STREQ(action, client.Action(action_index)); \
20 for (int i = expected_num_actions; i < client.num_actions_(); ++i) \ 19 for (int i = expected_num_actions; i < client.num_actions_(); ++i) \
21 ADD_FAILURE() << "Unexpected action: " << client.Action(i) << \ 20 ADD_FAILURE() << "Unexpected action: " << client.Action(i) << \
22 " with state:\n" << client.StateForAction(action_index); \ 21 " with state:\n" << client.StateForAction(action_index); \
23 } while (false) 22 } while (false)
24 23
25 #define EXPECT_SINGLE_ACTION(action, client) \ 24 #define EXPECT_SINGLE_ACTION(action, client) \
26 EXPECT_ACTION(action, client, 0, 1) 25 EXPECT_ACTION(action, client, 0, 1)
27 26
28 namespace cc { 27 namespace cc {
29 namespace { 28 namespace {
30 29
30 void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler) {
31 scheduler->DidCreateAndInitializeOutputSurface();
32 scheduler->SetNeedsCommit();
33 scheduler->FinishCommit();
34 scheduler->SetHasTrees(0, 0);
35 // Go through the motions to draw the commit.
36 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
37 scheduler->OnBeginFrameDeadline();
38 // We need another BeginFrame so scheduler calls SetNeedsBeginFrame(false).
39 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
40 scheduler->OnBeginFrameDeadline();
41 }
42
31 class FakeSchedulerClient : public SchedulerClient { 43 class FakeSchedulerClient : public SchedulerClient {
32 public: 44 public:
33 FakeSchedulerClient() 45 FakeSchedulerClient()
34 : needs_begin_frame_(false) { 46 : needs_begin_frame_(false) {
35 Reset(); 47 Reset();
36 } 48 }
37 49
38 void Reset() { 50 void Reset() {
39 actions_.clear(); 51 actions_.clear();
40 states_.clear(); 52 states_.clear();
(...skipping 30 matching lines...) Expand all
71 // Scheduler Implementation. 83 // Scheduler Implementation.
72 virtual void SetNeedsBeginFrameOnImplThread(bool enable) OVERRIDE { 84 virtual void SetNeedsBeginFrameOnImplThread(bool enable) OVERRIDE {
73 actions_.push_back("SetNeedsBeginFrameOnImplThread"); 85 actions_.push_back("SetNeedsBeginFrameOnImplThread");
74 states_.push_back(scheduler_->StateAsStringForTesting()); 86 states_.push_back(scheduler_->StateAsStringForTesting());
75 needs_begin_frame_ = enable; 87 needs_begin_frame_ = enable;
76 } 88 }
77 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE { 89 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {
78 actions_.push_back("ScheduledActionSendBeginFrameToMainThread"); 90 actions_.push_back("ScheduledActionSendBeginFrameToMainThread");
79 states_.push_back(scheduler_->StateAsStringForTesting()); 91 states_.push_back(scheduler_->StateAsStringForTesting());
80 } 92 }
81 virtual ScheduledActionDrawAndSwapResult 93 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible()
82 ScheduledActionDrawAndSwapIfPossible() OVERRIDE { 94 OVERRIDE {
83 actions_.push_back("ScheduledActionDrawAndSwapIfPossible"); 95 actions_.push_back("ScheduledActionDrawAndSwapIfPossible");
84 states_.push_back(scheduler_->StateAsStringForTesting()); 96 states_.push_back(scheduler_->StateAsStringForTesting());
85 num_draws_++; 97 num_draws_++;
86 return ScheduledActionDrawAndSwapResult(draw_will_happen_, 98 return DrawSwapReadbackResult(
87 draw_will_happen_ && 99 draw_will_happen_,
88 swap_will_happen_if_draw_happens_); 100 draw_will_happen_ && swap_will_happen_if_draw_happens_,
101 false);
89 } 102 }
90 virtual ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapForced() 103 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE {
91 OVERRIDE {
92 actions_.push_back("ScheduledActionDrawAndSwapForced"); 104 actions_.push_back("ScheduledActionDrawAndSwapForced");
93 states_.push_back(scheduler_->StateAsStringForTesting()); 105 states_.push_back(scheduler_->StateAsStringForTesting());
94 return ScheduledActionDrawAndSwapResult(true, 106 return DrawSwapReadbackResult(
95 swap_will_happen_if_draw_happens_); 107 true, swap_will_happen_if_draw_happens_, false);
108 }
109 virtual DrawSwapReadbackResult ScheduledActionDrawAndReadback() OVERRIDE {
110 actions_.push_back("ScheduledActionDrawAndReadback");
111 states_.push_back(scheduler_->StateAsStringForTesting());
112 return DrawSwapReadbackResult(true, false, true);
96 } 113 }
97 virtual void ScheduledActionCommit() OVERRIDE { 114 virtual void ScheduledActionCommit() OVERRIDE {
98 actions_.push_back("ScheduledActionCommit"); 115 actions_.push_back("ScheduledActionCommit");
99 states_.push_back(scheduler_->StateAsStringForTesting()); 116 states_.push_back(scheduler_->StateAsStringForTesting());
100 } 117 }
101 virtual void ScheduledActionUpdateVisibleTiles() OVERRIDE { 118 virtual void ScheduledActionUpdateVisibleTiles() OVERRIDE {
102 actions_.push_back("ScheduledActionUpdateVisibleTiles"); 119 actions_.push_back("ScheduledActionUpdateVisibleTiles");
103 states_.push_back(scheduler_->StateAsStringForTesting()); 120 states_.push_back(scheduler_->StateAsStringForTesting());
104 } 121 }
105 virtual void ScheduledActionActivatePendingTreeIfNeeded() OVERRIDE { 122 virtual void ScheduledActionActivatePendingTree() OVERRIDE {
106 actions_.push_back("ScheduledActionActivatePendingTreeIfNeeded"); 123 actions_.push_back("ScheduledActionActivatePendingTree");
107 states_.push_back(scheduler_->StateAsStringForTesting()); 124 states_.push_back(scheduler_->StateAsStringForTesting());
108 } 125 }
109 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE { 126 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {
110 actions_.push_back("ScheduledActionBeginOutputSurfaceCreation"); 127 actions_.push_back("ScheduledActionBeginOutputSurfaceCreation");
111 states_.push_back(scheduler_->StateAsStringForTesting()); 128 states_.push_back(scheduler_->StateAsStringForTesting());
112 } 129 }
113 virtual void ScheduledActionAcquireLayerTexturesForMainThread() OVERRIDE { 130 virtual void ScheduledActionAcquireLayerTexturesForMainThread() OVERRIDE {
114 actions_.push_back("ScheduledActionAcquireLayerTexturesForMainThread"); 131 actions_.push_back("ScheduledActionAcquireLayerTexturesForMainThread");
115 states_.push_back(scheduler_->StateAsStringForTesting()); 132 states_.push_back(scheduler_->StateAsStringForTesting());
116 } 133 }
117 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} 134 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {}
118 virtual base::TimeDelta DrawDurationEstimate() OVERRIDE { 135 virtual base::TimeDelta DrawDurationEstimate() OVERRIDE {
119 return base::TimeDelta(); 136 return base::TimeDelta();
120 } 137 }
121 virtual base::TimeDelta BeginFrameToCommitDurationEstimate() OVERRIDE { 138 virtual base::TimeDelta BeginFrameToCommitDurationEstimate() OVERRIDE {
122 return base::TimeDelta(); 139 return base::TimeDelta();
123 } 140 }
124 virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE { 141 virtual base::TimeDelta CommitToActivateDurationEstimate() OVERRIDE {
125 return base::TimeDelta(); 142 return base::TimeDelta();
126 } 143 }
127 144
145 virtual void PostBeginFrameDeadline(const base::Closure& closure,
146 base::TimeTicks deadline) OVERRIDE {
147 actions_.push_back("PostBeginFrameDeadlineTask");
148 states_.push_back(scheduler_->StateAsStringForTesting());
149 }
150
151 virtual void DidBeginFrameDeadlineOnImplThread() OVERRIDE {}
152
128 protected: 153 protected:
129 bool needs_begin_frame_; 154 bool needs_begin_frame_;
130 bool draw_will_happen_; 155 bool draw_will_happen_;
131 bool swap_will_happen_if_draw_happens_; 156 bool swap_will_happen_if_draw_happens_;
132 int num_draws_; 157 int num_draws_;
133 std::vector<const char*> actions_; 158 std::vector<const char*> actions_;
134 std::vector<std::string> states_; 159 std::vector<std::string> states_;
135 scoped_ptr<Scheduler> scheduler_; 160 scoped_ptr<Scheduler> scheduler_;
136 }; 161 };
137 162
(...skipping 13 matching lines...) Expand all
151 176
152 TEST(SchedulerTest, RequestCommit) { 177 TEST(SchedulerTest, RequestCommit) {
153 FakeSchedulerClient client; 178 FakeSchedulerClient client;
154 SchedulerSettings default_scheduler_settings; 179 SchedulerSettings default_scheduler_settings;
155 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 180 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
156 scheduler->SetCanStart(); 181 scheduler->SetCanStart();
157 scheduler->SetVisible(true); 182 scheduler->SetVisible(true);
158 scheduler->SetCanDraw(true); 183 scheduler->SetCanDraw(true);
159 184
160 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); 185 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
186 InitializeOutputSurfaceAndFirstCommit(scheduler);
187
188 // SetNeedsCommit should begin the frame on the next BeginFrame.
161 client.Reset(); 189 client.Reset();
162 scheduler->DidCreateAndInitializeOutputSurface(); 190 scheduler->SetNeedsCommit();
191 EXPECT_TRUE(client.needs_begin_frame());
192 client.Reset();
163 193
164 // SetNeedsCommit should begin the frame. 194 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
165 scheduler->SetNeedsCommit();
166 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); 195 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2);
167 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); 196 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
197 EXPECT_TRUE(client.needs_begin_frame());
198 client.Reset();
199
200 // If we don't swap on the deadline, we need to request another BeginFrame.
201 scheduler->OnBeginFrameDeadline();
202 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client);
168 EXPECT_TRUE(client.needs_begin_frame()); 203 EXPECT_TRUE(client.needs_begin_frame());
169 client.Reset(); 204 client.Reset();
170 205
171 // FinishCommit should commit 206 // FinishCommit should commit
172 scheduler->FinishCommit(); 207 scheduler->FinishCommit();
173 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); 208 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
174 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2);
175 EXPECT_TRUE(client.needs_begin_frame()); 209 EXPECT_TRUE(client.needs_begin_frame());
176 client.Reset(); 210 client.Reset();
177 211
178 // BeginFrame should draw. 212 // BeginFrame should prepare the draw.
179 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 213 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
180 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); 214 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client);
181 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); 215 EXPECT_TRUE(client.needs_begin_frame());
216 client.Reset();
217
218 // BeginFrame deadline should draw.
219 scheduler->OnBeginFrameDeadline();
220 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client);
221 client.Reset();
222
223 // The following BeginFrame deadline should SetNeedsBeginFrame(false) to avoid
224 // excessive toggles.
225 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
226 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client);
227 client.Reset();
228
229 scheduler->OnBeginFrameDeadline();
230 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client);
182 EXPECT_FALSE(client.needs_begin_frame()); 231 EXPECT_FALSE(client.needs_begin_frame());
183 client.Reset(); 232 client.Reset();
184 } 233 }
185 234
186 TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) { 235 TEST(SchedulerTest, RequestCommitAfterBeginFrameSentToMainThread) {
187 FakeSchedulerClient client; 236 FakeSchedulerClient client;
188 SchedulerSettings default_scheduler_settings; 237 SchedulerSettings default_scheduler_settings;
189 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 238 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
190 scheduler->SetCanStart(); 239 scheduler->SetCanStart();
191 scheduler->SetVisible(true); 240 scheduler->SetVisible(true);
192 scheduler->SetCanDraw(true); 241 scheduler->SetCanDraw(true);
193 242
194 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); 243 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
195 client.Reset(); 244 InitializeOutputSurfaceAndFirstCommit(scheduler);
196 scheduler->DidCreateAndInitializeOutputSurface();
197
198 // SetNedsCommit should begin the frame.
199 scheduler->SetNeedsCommit();
200 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2);
201 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2);
202 client.Reset(); 245 client.Reset();
203 246
204 // Now SetNeedsCommit again. Calling here means we need a second frame. 247 // SetNeddsCommit should begin the frame.
205 scheduler->SetNeedsCommit(); 248 scheduler->SetNeedsCommit();
206 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 0, 1); 249 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client);
250 client.Reset();
251 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
252 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2);
253 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
254 EXPECT_TRUE(client.needs_begin_frame());
207 client.Reset(); 255 client.Reset();
208 256
209 // Since another commit is needed, FinishCommit should commit, 257 // Now SetNeedsCommit again. Calling here means we need a second commit.
210 // then begin another frame. 258 scheduler->SetNeedsCommit();
259 EXPECT_EQ(client.num_actions_(), 0);
260 client.Reset();
261
262 // Finish the first commit.
211 scheduler->FinishCommit(); 263 scheduler->FinishCommit();
212 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2); 264 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2);
213 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); 265 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
266 client.Reset();
267 scheduler->OnBeginFrameDeadline();
268 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client);
214 client.Reset(); 269 client.Reset();
215 270
216 // Tick should draw but then begin another frame. 271 // Since another commit is needed, the next BeginFrame should initiate
272 // the second commit.
217 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 273 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
218 EXPECT_TRUE(client.needs_begin_frame()); 274 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2);
219 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); 275 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
220 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 1, 2);
221 client.Reset(); 276 client.Reset();
222 277
223 // Go back to quiescent state and verify we no longer request BeginFrames. 278 // Finishing the commit before the deadline should post a new deadline task
279 // to trigger the deadline early.
224 scheduler->FinishCommit(); 280 scheduler->FinishCommit();
281 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2);
282 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
283 client.Reset();
284 scheduler->OnBeginFrameDeadline();
285 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client);
286 EXPECT_TRUE(client.needs_begin_frame());
287
288 // On the next BeginFrame, go back to quiescent state and verify we no longer
289 // request BeginFrames.
225 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 290 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
291 scheduler->OnBeginFrameDeadline();
226 EXPECT_FALSE(client.needs_begin_frame()); 292 EXPECT_FALSE(client.needs_begin_frame());
293 client.Reset();
227 } 294 }
228 295
229 TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) { 296 TEST(SchedulerTest, TextureAcquisitionCausesCommitInsteadOfDraw) {
230 FakeSchedulerClient client; 297 FakeSchedulerClient client;
231 SchedulerSettings default_scheduler_settings; 298 SchedulerSettings default_scheduler_settings;
232 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 299 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
233 scheduler->SetCanStart(); 300 scheduler->SetCanStart();
234 scheduler->SetVisible(true); 301 scheduler->SetVisible(true);
235 scheduler->SetCanDraw(true); 302 scheduler->SetCanDraw(true);
236 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); 303 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
237 304
305 InitializeOutputSurfaceAndFirstCommit(scheduler);
238 client.Reset(); 306 client.Reset();
239 scheduler->DidCreateAndInitializeOutputSurface();
240 scheduler->SetNeedsRedraw(); 307 scheduler->SetNeedsRedraw();
241 EXPECT_TRUE(scheduler->RedrawPending()); 308 EXPECT_TRUE(scheduler->RedrawPending());
242 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); 309 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client);
243 EXPECT_TRUE(client.needs_begin_frame()); 310 EXPECT_TRUE(client.needs_begin_frame());
244 311
245 client.Reset(); 312 client.Reset();
246 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 313 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
247 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); 314 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client);
248 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); 315
316 client.Reset();
317 scheduler->OnBeginFrameDeadline();
318 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client);
249 EXPECT_FALSE(scheduler->RedrawPending()); 319 EXPECT_FALSE(scheduler->RedrawPending());
250 EXPECT_FALSE(client.needs_begin_frame());
251 320
252 client.Reset(); 321 client.Reset();
253 scheduler->SetMainThreadNeedsLayerTextures(); 322 scheduler->SetMainThreadNeedsLayerTextures();
254 EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", 323 EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread",
255 client); 324 client);
256 325
257 // We should request a BeginFrame in anticipation of a draw. 326 // We should request a BeginFrame in anticipation of a draw.
258 client.Reset(); 327 client.Reset();
259 scheduler->SetNeedsRedraw(); 328 scheduler->SetNeedsRedraw();
260 EXPECT_TRUE(scheduler->RedrawPending()); 329 EXPECT_TRUE(scheduler->RedrawPending());
261 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); 330 EXPECT_EQ(0, client.num_actions_());
262 EXPECT_TRUE(client.needs_begin_frame());
263 331
264 // No draw happens since the textures are acquired by the main thread. 332 // No draw happens since the textures are acquired by the main thread.
265 client.Reset(); 333 client.Reset();
266 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 334 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
335 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client);
336
337 client.Reset();
338 scheduler->OnBeginFrameDeadline();
267 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client); 339 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client);
268 EXPECT_TRUE(scheduler->RedrawPending()); 340 EXPECT_TRUE(scheduler->RedrawPending());
269 EXPECT_TRUE(client.needs_begin_frame()); 341 EXPECT_TRUE(client.needs_begin_frame());
270 342
343 client.Reset();
271 scheduler->SetNeedsCommit(); 344 scheduler->SetNeedsCommit();
272 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 0, 2); 345 EXPECT_EQ(0, client.num_actions_());
273 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 1, 2); 346
274 EXPECT_TRUE(client.needs_begin_frame()); 347 client.Reset();
348 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
349 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2);
350 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
275 351
276 // Commit will release the texture. 352 // Commit will release the texture.
277 client.Reset(); 353 client.Reset();
278 scheduler->FinishCommit(); 354 scheduler->FinishCommit();
279 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); 355 EXPECT_ACTION("ScheduledActionCommit", client, 0, 2);
356 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
280 EXPECT_TRUE(scheduler->RedrawPending()); 357 EXPECT_TRUE(scheduler->RedrawPending());
281 EXPECT_TRUE(client.needs_begin_frame());
282 358
283 // Now we can draw again after the commit happens. 359 // Now we can draw again after the commit happens.
284 client.Reset(); 360 client.Reset();
361 scheduler->OnBeginFrameDeadline();
362 EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client);
363 EXPECT_FALSE(scheduler->RedrawPending());
364
365 // SetNeedsBeginFrame(false) should be deferred to the end of the next
366 // BeginFrame to avoid excessive toggling.
367 EXPECT_TRUE(client.needs_begin_frame());
285 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 368 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
286 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2); 369 scheduler->OnBeginFrameDeadline();
287 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2);
288 EXPECT_FALSE(scheduler->RedrawPending());
289 EXPECT_FALSE(client.needs_begin_frame()); 370 EXPECT_FALSE(client.needs_begin_frame());
290 client.Reset();
291 } 371 }
292 372
293 TEST(SchedulerTest, TextureAcquisitionCollision) { 373 TEST(SchedulerTest, TextureAcquisitionCollision) {
294 FakeSchedulerClient client; 374 FakeSchedulerClient client;
295 SchedulerSettings default_scheduler_settings; 375 SchedulerSettings default_scheduler_settings;
296 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 376 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
297 scheduler->SetCanStart(); 377 scheduler->SetCanStart();
298 scheduler->SetVisible(true); 378 scheduler->SetVisible(true);
299 scheduler->SetCanDraw(true); 379 scheduler->SetCanDraw(true);
300 380
301 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); 381 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
382 InitializeOutputSurfaceAndFirstCommit(scheduler);
383
302 client.Reset(); 384 client.Reset();
303 scheduler->DidCreateAndInitializeOutputSurface();
304
305 scheduler->SetNeedsCommit(); 385 scheduler->SetNeedsCommit();
306 scheduler->SetMainThreadNeedsLayerTextures(); 386 scheduler->SetMainThreadNeedsLayerTextures();
307 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 4); 387 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 0, 2);
308 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 4); 388 EXPECT_ACTION(
309 EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", 389 "ScheduledActionAcquireLayerTexturesForMainThread", client, 1, 2);
310 client, 390
311 2,
312 4);
313 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 3, 4);
314 client.Reset(); 391 client.Reset();
392 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
393 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2);
394 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
395
396 client.Reset();
397 scheduler->OnBeginFrameDeadline();
398 EXPECT_SINGLE_ACTION("SetNeedsBeginFrameOnImplThread", client);
315 399
316 // Although the compositor cannot draw because textures are locked by main 400 // Although the compositor cannot draw because textures are locked by main
317 // thread, we continue requesting SetNeedsBeginFrame in anticipation of the 401 // thread, we continue requesting SetNeedsBeginFrame in anticipation of the
318 // unlock. 402 // unlock.
319 EXPECT_TRUE(client.needs_begin_frame()); 403 EXPECT_TRUE(client.needs_begin_frame());
320 404
321 // Trigger the commit 405 // Trigger the commit
322 scheduler->FinishCommit(); 406 scheduler->FinishCommit();
323 EXPECT_TRUE(client.needs_begin_frame()); 407 EXPECT_TRUE(client.needs_begin_frame());
324 client.Reset();
325 408
326 // Between commit and draw, texture acquisition for main thread delayed, 409 // Between commit and draw, texture acquisition for main thread delayed,
327 // and main thread blocks. 410 // and main thread blocks.
411 client.Reset();
328 scheduler->SetMainThreadNeedsLayerTextures(); 412 scheduler->SetMainThreadNeedsLayerTextures();
329 EXPECT_EQ(0, client.num_actions_()); 413 EXPECT_EQ(0, client.num_actions_());
330 client.Reset();
331 414
332 // No implicit commit is expected. 415 // No implicit commit is expected.
416 client.Reset();
333 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 417 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
334 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 3); 418 EXPECT_SINGLE_ACTION("PostBeginFrameDeadlineTask", client);
335 EXPECT_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", 419
336 client,
337 1,
338 3);
339 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 2, 3);
340 client.Reset(); 420 client.Reset();
421 scheduler->OnBeginFrameDeadline();
422 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 2);
423 EXPECT_ACTION(
424 "ScheduledActionAcquireLayerTexturesForMainThread", client, 1, 2);
341 425
342 // Compositor not scheduled to draw because textures are locked by main 426 // Although the compositor is not scheduled to draw because textures are
343 // thread. 427 // locked by main thread, we proactively request the begin frame.
344 EXPECT_FALSE(client.needs_begin_frame()); 428 EXPECT_TRUE(client.needs_begin_frame());
345 429
346 // Needs an explicit commit from the main thread. 430 // Needs an explicit commit from the main thread.
431 client.Reset();
347 scheduler->SetNeedsCommit(); 432 scheduler->SetNeedsCommit();
433 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
348 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); 434 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2);
349 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); 435 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
350 client.Reset(); 436 client.Reset();
351 437
352 // Trigger the commit 438 // Trigger the commit
353 scheduler->FinishCommit(); 439 scheduler->FinishCommit();
354 EXPECT_TRUE(client.needs_begin_frame()); 440 EXPECT_TRUE(client.needs_begin_frame());
355 } 441 }
356 442
357 TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) { 443 TEST(SchedulerTest, VisibilitySwitchWithTextureAcquisition) {
358 FakeSchedulerClient client; 444 FakeSchedulerClient client;
359 SchedulerSettings default_scheduler_settings; 445 SchedulerSettings default_scheduler_settings;
360 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 446 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
361 scheduler->SetCanStart(); 447 scheduler->SetCanStart();
362 scheduler->SetVisible(true); 448 scheduler->SetVisible(true);
363 scheduler->SetCanDraw(true); 449 scheduler->SetCanDraw(true);
364 450
365 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client); 451 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client);
366 client.Reset(); 452 client.Reset();
367 scheduler->DidCreateAndInitializeOutputSurface(); 453 scheduler->DidCreateAndInitializeOutputSurface();
368 454
369 scheduler->SetNeedsCommit(); 455 scheduler->SetNeedsCommit();
456 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
457 scheduler->OnBeginFrameDeadline();
370 scheduler->FinishCommit(); 458 scheduler->FinishCommit();
371 scheduler->SetMainThreadNeedsLayerTextures(); 459 scheduler->SetMainThreadNeedsLayerTextures();
372 scheduler->SetNeedsCommit(); 460 scheduler->SetNeedsCommit();
373 client.Reset(); 461 client.Reset();
374 // Verify that pending texture acquisition fires when visibility 462 // Verify that pending texture acquisition fires when visibility
375 // is lost in order to avoid a deadlock. 463 // is lost in order to avoid a deadlock.
376 scheduler->SetVisible(false); 464 scheduler->SetVisible(false);
377 EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread", 465 EXPECT_SINGLE_ACTION("ScheduledActionAcquireLayerTexturesForMainThread",
378 client); 466 client);
379 client.Reset();
380 467
381 // Already sent a begin frame on this current frame, so wait. 468 // Already sent a begin frame on this current frame, so wait.
469 client.Reset();
382 scheduler->SetVisible(true); 470 scheduler->SetVisible(true);
383 EXPECT_EQ(0, client.num_actions_()); 471 EXPECT_EQ(0, client.num_actions_());
384 client.Reset(); 472 EXPECT_TRUE(client.needs_begin_frame());
385 473
386 // Regaining visibility with textures acquired by main thread while 474 // Regaining visibility with textures acquired by main thread while
387 // compositor is waiting for first draw should result in a request 475 // compositor is waiting for first draw should result in a request
388 // for a new frame in order to escape a deadlock. 476 // for a new frame in order to escape a deadlock.
477 client.Reset();
389 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 478 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
390 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2); 479 EXPECT_ACTION("ScheduledActionSendBeginFrameToMainThread", client, 0, 2);
391 EXPECT_ACTION("SetNeedsBeginFrameOnImplThread", client, 1, 2); 480 EXPECT_ACTION("PostBeginFrameDeadlineTask", client, 1, 2);
392 } 481 }
393 482
394 class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient { 483 class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient {
395 public: 484 public:
396 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {} 485 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {}
397 virtual ScheduledActionDrawAndSwapResult 486 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible()
398 ScheduledActionDrawAndSwapIfPossible() OVERRIDE { 487 OVERRIDE {
399 // Only SetNeedsRedraw the first time this is called 488 // Only SetNeedsRedraw the first time this is called
400 if (!num_draws_) 489 if (!num_draws_)
401 scheduler_->SetNeedsRedraw(); 490 scheduler_->SetNeedsRedraw();
402 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); 491 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
403 } 492 }
404 493
405 virtual ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapForced() 494 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE {
406 OVERRIDE {
407 NOTREACHED(); 495 NOTREACHED();
408 return ScheduledActionDrawAndSwapResult(true, true); 496 return DrawSwapReadbackResult(true, true, false);
409 } 497 }
410 498
411 virtual void ScheduledActionCommit() OVERRIDE {} 499 virtual void ScheduledActionCommit() OVERRIDE {}
412 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {} 500 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {}
413 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} 501 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {}
414 }; 502 };
415 503
416 // Tests for two different situations: 504 // Tests for two different situations:
417 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside 505 // 1. the scheduler dropping SetNeedsRedraw requests that happen inside
418 // a ScheduledActionDrawAndSwap 506 // a ScheduledActionDrawAndSwap
419 // 2. the scheduler drawing twice inside a single tick 507 // 2. the scheduler drawing twice inside a single tick
420 TEST(SchedulerTest, RequestRedrawInsideDraw) { 508 TEST(SchedulerTest, RequestRedrawInsideDraw) {
421 SchedulerClientThatsetNeedsDrawInsideDraw client; 509 SchedulerClientThatsetNeedsDrawInsideDraw client;
422 SchedulerSettings default_scheduler_settings; 510 SchedulerSettings default_scheduler_settings;
423 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 511 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
424 scheduler->SetCanStart(); 512 scheduler->SetCanStart();
425 scheduler->SetVisible(true); 513 scheduler->SetVisible(true);
426 scheduler->SetCanDraw(true); 514 scheduler->SetCanDraw(true);
427 scheduler->DidCreateAndInitializeOutputSurface(); 515 InitializeOutputSurfaceAndFirstCommit(scheduler);
516 client.Reset();
428 517
429 scheduler->SetNeedsRedraw(); 518 scheduler->SetNeedsRedraw();
430 EXPECT_TRUE(scheduler->RedrawPending()); 519 EXPECT_TRUE(scheduler->RedrawPending());
431 EXPECT_TRUE(client.needs_begin_frame()); 520 EXPECT_TRUE(client.needs_begin_frame());
432 EXPECT_EQ(0, client.num_draws()); 521 EXPECT_EQ(0, client.num_draws());
433 522
434 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 523 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
524 scheduler->OnBeginFrameDeadline();
435 EXPECT_EQ(1, client.num_draws()); 525 EXPECT_EQ(1, client.num_draws());
436 EXPECT_TRUE(scheduler->RedrawPending()); 526 EXPECT_TRUE(scheduler->RedrawPending());
437 EXPECT_TRUE(client.needs_begin_frame()); 527 EXPECT_TRUE(client.needs_begin_frame());
438 528
439 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 529 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
530 scheduler->OnBeginFrameDeadline();
440 EXPECT_EQ(2, client.num_draws()); 531 EXPECT_EQ(2, client.num_draws());
441 EXPECT_FALSE(scheduler->RedrawPending()); 532 EXPECT_FALSE(scheduler->RedrawPending());
533 EXPECT_TRUE(client.needs_begin_frame());
534
535 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
536 scheduler->OnBeginFrameDeadline();
442 EXPECT_FALSE(client.needs_begin_frame()); 537 EXPECT_FALSE(client.needs_begin_frame());
443 } 538 }
444 539
445 // Test that requesting redraw inside a failed draw doesn't lose the request. 540 // Test that requesting redraw inside a failed draw doesn't lose the request.
446 TEST(SchedulerTest, RequestRedrawInsideFailedDraw) { 541 TEST(SchedulerTest, RequestRedrawInsideFailedDraw) {
447 SchedulerClientThatsetNeedsDrawInsideDraw client; 542 SchedulerClientThatsetNeedsDrawInsideDraw client;
448 SchedulerSettings default_scheduler_settings; 543 SchedulerSettings default_scheduler_settings;
449 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 544 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
450 scheduler->SetCanStart(); 545 scheduler->SetCanStart();
451 scheduler->SetVisible(true); 546 scheduler->SetVisible(true);
452 scheduler->SetCanDraw(true); 547 scheduler->SetCanDraw(true);
453 scheduler->DidCreateAndInitializeOutputSurface(); 548 InitializeOutputSurfaceAndFirstCommit(scheduler);
549 client.Reset();
454 550
455 client.SetDrawWillHappen(false); 551 client.SetDrawWillHappen(false);
456 552
457 scheduler->SetNeedsRedraw(); 553 scheduler->SetNeedsRedraw();
458 EXPECT_TRUE(scheduler->RedrawPending()); 554 EXPECT_TRUE(scheduler->RedrawPending());
459 EXPECT_TRUE(client.needs_begin_frame()); 555 EXPECT_TRUE(client.needs_begin_frame());
460 EXPECT_EQ(0, client.num_draws()); 556 EXPECT_EQ(0, client.num_draws());
461 557
462 // Fail the draw. 558 // Fail the draw.
463 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 559 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
560 scheduler->OnBeginFrameDeadline();
464 EXPECT_EQ(1, client.num_draws()); 561 EXPECT_EQ(1, client.num_draws());
465 562
466 // We have a commit pending and the draw failed, and we didn't lose the redraw 563 // We have a commit pending and the draw failed, and we didn't lose the redraw
467 // request. 564 // request.
468 EXPECT_TRUE(scheduler->CommitPending()); 565 EXPECT_TRUE(scheduler->CommitPending());
469 EXPECT_TRUE(scheduler->RedrawPending()); 566 EXPECT_TRUE(scheduler->RedrawPending());
470 EXPECT_TRUE(client.needs_begin_frame()); 567 EXPECT_TRUE(client.needs_begin_frame());
471 568
472 // Fail the draw again. 569 // Fail the draw again.
473 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 570 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
571 scheduler->OnBeginFrameDeadline();
474 EXPECT_EQ(2, client.num_draws()); 572 EXPECT_EQ(2, client.num_draws());
475 EXPECT_TRUE(scheduler->CommitPending()); 573 EXPECT_TRUE(scheduler->CommitPending());
476 EXPECT_TRUE(scheduler->RedrawPending()); 574 EXPECT_TRUE(scheduler->RedrawPending());
477 EXPECT_TRUE(client.needs_begin_frame()); 575 EXPECT_TRUE(client.needs_begin_frame());
478 576
479 // Draw successfully. 577 // Draw successfully.
480 client.SetDrawWillHappen(true); 578 client.SetDrawWillHappen(true);
481 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 579 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
580 scheduler->OnBeginFrameDeadline();
482 EXPECT_EQ(3, client.num_draws()); 581 EXPECT_EQ(3, client.num_draws());
483 EXPECT_TRUE(scheduler->CommitPending()); 582 EXPECT_TRUE(scheduler->CommitPending());
484 EXPECT_FALSE(scheduler->RedrawPending()); 583 EXPECT_FALSE(scheduler->RedrawPending());
485 EXPECT_TRUE(client.needs_begin_frame()); 584 EXPECT_TRUE(client.needs_begin_frame());
486 } 585 }
487 586
488 class SchedulerClientThatsetNeedsCommitInsideDraw : public FakeSchedulerClient { 587 class SchedulerClientThatSetNeedsCommitInsideDraw : public FakeSchedulerClient {
489 public: 588 public:
589 SchedulerClientThatSetNeedsCommitInsideDraw()
590 : set_needs_commit_on_next_draw_(false) {}
591
490 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {} 592 virtual void ScheduledActionSendBeginFrameToMainThread() OVERRIDE {}
491 virtual ScheduledActionDrawAndSwapResult 593 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible()
492 ScheduledActionDrawAndSwapIfPossible() OVERRIDE { 594 OVERRIDE {
493 // Only SetNeedsCommit the first time this is called 595 // Only SetNeedsCommit the first time this is called
494 if (!num_draws_) 596 if (set_needs_commit_on_next_draw_) {
495 scheduler_->SetNeedsCommit(); 597 scheduler_->SetNeedsCommit();
598 set_needs_commit_on_next_draw_ = false;
599 }
496 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); 600 return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible();
497 } 601 }
498 602
499 virtual ScheduledActionDrawAndSwapResult ScheduledActionDrawAndSwapForced() 603 virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE {
500 OVERRIDE {
501 NOTREACHED(); 604 NOTREACHED();
502 return ScheduledActionDrawAndSwapResult(true, true); 605 return DrawSwapReadbackResult(true, true, false);
503 } 606 }
504 607
505 virtual void ScheduledActionCommit() OVERRIDE {} 608 virtual void ScheduledActionCommit() OVERRIDE {}
506 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {} 609 virtual void ScheduledActionBeginOutputSurfaceCreation() OVERRIDE {}
507 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {} 610 virtual void DidAnticipatedDrawTimeChange(base::TimeTicks) OVERRIDE {}
611
612 void SetNeedsCommitOnNextDraw() { set_needs_commit_on_next_draw_ = true; }
613
614 private:
615 bool set_needs_commit_on_next_draw_;
508 }; 616 };
509 617
510 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that 618 // Tests for the scheduler infinite-looping on SetNeedsCommit requests that
511 // happen inside a ScheduledActionDrawAndSwap 619 // happen inside a ScheduledActionDrawAndSwap
512 TEST(SchedulerTest, RequestCommitInsideDraw) { 620 TEST(SchedulerTest, RequestCommitInsideDraw) {
513 SchedulerClientThatsetNeedsCommitInsideDraw client; 621 SchedulerClientThatSetNeedsCommitInsideDraw client;
514 SchedulerSettings default_scheduler_settings; 622 SchedulerSettings default_scheduler_settings;
515 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 623 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
516 scheduler->SetCanStart(); 624 scheduler->SetCanStart();
517 scheduler->SetVisible(true); 625 scheduler->SetVisible(true);
518 scheduler->SetCanDraw(true); 626 scheduler->SetCanDraw(true);
519 scheduler->DidCreateAndInitializeOutputSurface(); 627 InitializeOutputSurfaceAndFirstCommit(scheduler);
628 client.Reset();
520 629
630 EXPECT_FALSE(client.needs_begin_frame());
521 scheduler->SetNeedsRedraw(); 631 scheduler->SetNeedsRedraw();
522 EXPECT_TRUE(scheduler->RedrawPending()); 632 EXPECT_TRUE(scheduler->RedrawPending());
523 EXPECT_EQ(0, client.num_draws()); 633 EXPECT_EQ(0, client.num_draws());
524 EXPECT_TRUE(client.needs_begin_frame()); 634 EXPECT_TRUE(client.needs_begin_frame());
525 635
526 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 636 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
637 client.SetNeedsCommitOnNextDraw();
638 scheduler->OnBeginFrameDeadline();
527 EXPECT_EQ(1, client.num_draws()); 639 EXPECT_EQ(1, client.num_draws());
528 EXPECT_TRUE(scheduler->CommitPending()); 640 EXPECT_TRUE(scheduler->CommitPending());
529 EXPECT_TRUE(client.needs_begin_frame()); 641 EXPECT_TRUE(client.needs_begin_frame());
530 scheduler->FinishCommit(); 642 scheduler->FinishCommit();
531 643
532 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 644 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
533 EXPECT_EQ(2, client.num_draws());; 645 scheduler->OnBeginFrameDeadline();
646 EXPECT_EQ(2, client.num_draws());
647
534 EXPECT_FALSE(scheduler->RedrawPending()); 648 EXPECT_FALSE(scheduler->RedrawPending());
535 EXPECT_FALSE(scheduler->CommitPending()); 649 EXPECT_FALSE(scheduler->CommitPending());
650 EXPECT_TRUE(client.needs_begin_frame());
651
652 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
653 scheduler->OnBeginFrameDeadline();
536 EXPECT_FALSE(client.needs_begin_frame()); 654 EXPECT_FALSE(client.needs_begin_frame());
537 } 655 }
538 656
539 // Tests that when a draw fails then the pending commit should not be dropped. 657 // Tests that when a draw fails then the pending commit should not be dropped.
540 TEST(SchedulerTest, RequestCommitInsideFailedDraw) { 658 TEST(SchedulerTest, RequestCommitInsideFailedDraw) {
541 SchedulerClientThatsetNeedsDrawInsideDraw client; 659 SchedulerClientThatsetNeedsDrawInsideDraw client;
542 SchedulerSettings default_scheduler_settings; 660 SchedulerSettings default_scheduler_settings;
543 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 661 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
544 scheduler->SetCanStart(); 662 scheduler->SetCanStart();
545 scheduler->SetVisible(true); 663 scheduler->SetVisible(true);
546 scheduler->SetCanDraw(true); 664 scheduler->SetCanDraw(true);
547 scheduler->DidCreateAndInitializeOutputSurface(); 665 InitializeOutputSurfaceAndFirstCommit(scheduler);
666 client.Reset();
548 667
549 client.SetDrawWillHappen(false); 668 client.SetDrawWillHappen(false);
550 669
551 scheduler->SetNeedsRedraw(); 670 scheduler->SetNeedsRedraw();
552 EXPECT_TRUE(scheduler->RedrawPending()); 671 EXPECT_TRUE(scheduler->RedrawPending());
553 EXPECT_TRUE(client.needs_begin_frame()); 672 EXPECT_TRUE(client.needs_begin_frame());
554 EXPECT_EQ(0, client.num_draws()); 673 EXPECT_EQ(0, client.num_draws());
555 674
556 // Fail the draw. 675 // Fail the draw.
557 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 676 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
677 scheduler->OnBeginFrameDeadline();
558 EXPECT_EQ(1, client.num_draws()); 678 EXPECT_EQ(1, client.num_draws());
559 679
560 // We have a commit pending and the draw failed, and we didn't lose the commit 680 // We have a commit pending and the draw failed, and we didn't lose the commit
561 // request. 681 // request.
562 EXPECT_TRUE(scheduler->CommitPending()); 682 EXPECT_TRUE(scheduler->CommitPending());
563 EXPECT_TRUE(scheduler->RedrawPending()); 683 EXPECT_TRUE(scheduler->RedrawPending());
564 EXPECT_TRUE(client.needs_begin_frame()); 684 EXPECT_TRUE(client.needs_begin_frame());
565 685
566 // Fail the draw again. 686 // Fail the draw again.
567 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 687 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
688 scheduler->OnBeginFrameDeadline();
568 EXPECT_EQ(2, client.num_draws()); 689 EXPECT_EQ(2, client.num_draws());
569 EXPECT_TRUE(scheduler->CommitPending()); 690 EXPECT_TRUE(scheduler->CommitPending());
570 EXPECT_TRUE(scheduler->RedrawPending()); 691 EXPECT_TRUE(scheduler->RedrawPending());
571 EXPECT_TRUE(client.needs_begin_frame()); 692 EXPECT_TRUE(client.needs_begin_frame());
572 693
573 // Draw successfully. 694 // Draw successfully.
574 client.SetDrawWillHappen(true); 695 client.SetDrawWillHappen(true);
575 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 696 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
697 scheduler->OnBeginFrameDeadline();
576 EXPECT_EQ(3, client.num_draws()); 698 EXPECT_EQ(3, client.num_draws());
577 EXPECT_TRUE(scheduler->CommitPending()); 699 EXPECT_TRUE(scheduler->CommitPending());
578 EXPECT_FALSE(scheduler->RedrawPending()); 700 EXPECT_FALSE(scheduler->RedrawPending());
579 EXPECT_TRUE(client.needs_begin_frame()); 701 EXPECT_TRUE(client.needs_begin_frame());
580 } 702 }
581 703
582 TEST(SchedulerTest, NoSwapWhenDrawFails) { 704 TEST(SchedulerTest, NoSwapWhenDrawFails) {
583 SchedulerClientThatsetNeedsCommitInsideDraw client; 705 SchedulerClientThatSetNeedsCommitInsideDraw client;
584 SchedulerSettings default_scheduler_settings; 706 SchedulerSettings default_scheduler_settings;
585 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 707 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
586 scheduler->SetCanStart(); 708 scheduler->SetCanStart();
587 scheduler->SetVisible(true); 709 scheduler->SetVisible(true);
588 scheduler->SetCanDraw(true); 710 scheduler->SetCanDraw(true);
589 scheduler->DidCreateAndInitializeOutputSurface(); 711 InitializeOutputSurfaceAndFirstCommit(scheduler);
712 client.Reset();
590 713
591 scheduler->SetNeedsRedraw(); 714 scheduler->SetNeedsRedraw();
592 EXPECT_TRUE(scheduler->RedrawPending()); 715 EXPECT_TRUE(scheduler->RedrawPending());
593 EXPECT_TRUE(client.needs_begin_frame()); 716 EXPECT_TRUE(client.needs_begin_frame());
594 EXPECT_EQ(0, client.num_draws()); 717 EXPECT_EQ(0, client.num_draws());
595 718
596 // Draw successfully, this starts a new frame. 719 // Draw successfully, this starts a new frame.
597 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 720 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
721 scheduler->OnBeginFrameDeadline();
598 EXPECT_EQ(1, client.num_draws()); 722 EXPECT_EQ(1, client.num_draws());
599 723
600 scheduler->SetNeedsRedraw(); 724 scheduler->SetNeedsRedraw();
601 EXPECT_TRUE(scheduler->RedrawPending()); 725 EXPECT_TRUE(scheduler->RedrawPending());
602 EXPECT_TRUE(client.needs_begin_frame()); 726 EXPECT_TRUE(client.needs_begin_frame());
603 727
604 // Fail to draw, this should not start a frame. 728 // Fail to draw, this should not start a frame.
605 client.SetDrawWillHappen(false); 729 client.SetDrawWillHappen(false);
606 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting()); 730 scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
731 scheduler->OnBeginFrameDeadline();
607 EXPECT_EQ(2, client.num_draws()); 732 EXPECT_EQ(2, client.num_draws());
608 } 733 }
609 734
610 TEST(SchedulerTest, NoSwapWhenSwapFailsDuringForcedCommit) { 735 TEST(SchedulerTest, NoSwapWhenSwapFailsDuringForcedCommit) {
611 FakeSchedulerClient client; 736 FakeSchedulerClient client;
612 SchedulerSettings default_scheduler_settings; 737 SchedulerSettings default_scheduler_settings;
613 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings); 738 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
614 739
615 // Tell the client that it will fail to swap. 740 // Tell the client that it will fail to swap.
616 client.SetDrawWillHappen(true); 741 client.SetDrawWillHappen(true);
617 client.SetSwapWillHappenIfDrawHappens(false); 742 client.SetSwapWillHappenIfDrawHappens(false);
618 743
619 // Get the compositor to do a ScheduledActionDrawAndSwapForced. 744 // Get the compositor to do a ScheduledActionDrawAndReadback.
620 scheduler->SetCanDraw(true); 745 scheduler->SetCanDraw(true);
621 scheduler->SetNeedsRedraw(); 746 scheduler->SetNeedsRedraw();
622 scheduler->SetNeedsForcedRedraw(); 747 scheduler->SetNeedsForcedCommitForReadback();
623 EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndSwapForced")); 748 scheduler->FinishCommit();
749 EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback"));
750 }
751
752 TEST(SchedulerTest, BackToBackReadbackAllowed) {
753 // Some clients call readbacks twice in a row before the replacement
754 // commit comes in. Make sure it is allowed.
755 FakeSchedulerClient client;
756 SchedulerSettings default_scheduler_settings;
757 Scheduler* scheduler = client.CreateScheduler(default_scheduler_settings);
758
759 // Get the compositor to do 2 ScheduledActionDrawAndReadbacks before
760 // the replacement commit comes in.
761 scheduler->SetCanDraw(true);
762 scheduler->SetNeedsRedraw();
763 scheduler->SetNeedsForcedCommitForReadback();
764 scheduler->FinishCommit();
765 EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback"));
766
767 client.Reset();
768 scheduler->SetNeedsForcedCommitForReadback();
769 scheduler->FinishCommit();
770 EXPECT_TRUE(client.HasAction("ScheduledActionDrawAndReadback"));
771
772 // The replacement commit comes in after 2 readbacks.
773 client.Reset();
774 scheduler->FinishCommit();
624 } 775 }
625 776
626 } // namespace 777 } // namespace
627 } // namespace cc 778 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698