OLD | NEW |
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.h" | 5 #include "cc/scheduler/scheduler.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 statements; \ | 44 statements; \ |
45 } | 45 } |
46 | 46 |
47 namespace cc { | 47 namespace cc { |
48 namespace { | 48 namespace { |
49 | 49 |
50 class FakeSchedulerClient : public SchedulerClient { | 50 class FakeSchedulerClient : public SchedulerClient { |
51 public: | 51 public: |
52 FakeSchedulerClient() | 52 FakeSchedulerClient() |
53 : automatic_swap_ack_(true), | 53 : automatic_swap_ack_(true), |
54 begin_frame_is_sent_to_children_(false), | |
55 scheduler_(nullptr) { | 54 scheduler_(nullptr) { |
56 Reset(); | 55 Reset(); |
57 } | 56 } |
58 | 57 |
59 void Reset() { | 58 void Reset() { |
60 actions_.clear(); | 59 actions_.clear(); |
61 states_.clear(); | 60 states_.clear(); |
62 draw_will_happen_ = true; | 61 draw_will_happen_ = true; |
63 swap_will_happen_if_draw_happens_ = true; | 62 swap_will_happen_if_draw_happens_ = true; |
64 num_draws_ = 0; | 63 num_draws_ = 0; |
65 log_anticipated_draw_time_change_ = false; | 64 log_anticipated_draw_time_change_ = false; |
66 begin_frame_is_sent_to_children_ = false; | |
67 } | 65 } |
68 | 66 |
69 void set_scheduler(TestScheduler* scheduler) { scheduler_ = scheduler; } | 67 void set_scheduler(TestScheduler* scheduler) { scheduler_ = scheduler; } |
70 | |
71 // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it | 68 // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it |
72 // for tests that do. | 69 // for tests that do. |
73 void set_log_anticipated_draw_time_change(bool log) { | 70 void set_log_anticipated_draw_time_change(bool log) { |
74 log_anticipated_draw_time_change_ = log; | 71 log_anticipated_draw_time_change_ = log; |
75 } | 72 } |
76 bool needs_begin_frames() { | 73 bool needs_begin_frames() { |
77 return scheduler_->frame_source().NeedsBeginFrames(); | 74 return scheduler_->frame_source().NeedsBeginFrames(); |
78 } | 75 } |
79 int num_draws() const { return num_draws_; } | 76 int num_draws() const { return num_draws_; } |
80 int num_actions_() const { return static_cast<int>(actions_.size()); } | 77 int num_actions_() const { return static_cast<int>(actions_.size()); } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 base::TimeDelta DrawDurationEstimate() override { return base::TimeDelta(); } | 147 base::TimeDelta DrawDurationEstimate() override { return base::TimeDelta(); } |
151 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { | 148 base::TimeDelta BeginMainFrameToCommitDurationEstimate() override { |
152 return base::TimeDelta(); | 149 return base::TimeDelta(); |
153 } | 150 } |
154 base::TimeDelta CommitToActivateDurationEstimate() override { | 151 base::TimeDelta CommitToActivateDurationEstimate() override { |
155 return base::TimeDelta(); | 152 return base::TimeDelta(); |
156 } | 153 } |
157 | 154 |
158 void DidBeginImplFrameDeadline() override {} | 155 void DidBeginImplFrameDeadline() override {} |
159 | 156 |
160 void SendBeginFramesToChildren(const BeginFrameArgs& args) override { | |
161 begin_frame_is_sent_to_children_ = true; | |
162 } | |
163 | |
164 base::Callback<bool(void)> ImplFrameDeadlinePending(bool state) { | 157 base::Callback<bool(void)> ImplFrameDeadlinePending(bool state) { |
165 return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback, | 158 return base::Bind(&FakeSchedulerClient::ImplFrameDeadlinePendingCallback, |
166 base::Unretained(this), | 159 base::Unretained(this), |
167 state); | 160 state); |
168 } | 161 } |
169 | 162 |
170 bool begin_frame_is_sent_to_children() const { | |
171 return begin_frame_is_sent_to_children_; | |
172 } | |
173 | |
174 void PushAction(const char* description) { | 163 void PushAction(const char* description) { |
175 actions_.push_back(description); | 164 actions_.push_back(description); |
176 states_.push_back(scheduler_->AsValue()); | 165 states_.push_back(scheduler_->AsValue()); |
177 } | 166 } |
178 | 167 |
179 protected: | 168 protected: |
180 bool ImplFrameDeadlinePendingCallback(bool state) { | 169 bool ImplFrameDeadlinePendingCallback(bool state) { |
181 return scheduler_->BeginImplFrameDeadlinePending() == state; | 170 return scheduler_->BeginImplFrameDeadlinePending() == state; |
182 } | 171 } |
183 | 172 |
184 bool draw_will_happen_; | 173 bool draw_will_happen_; |
185 bool swap_will_happen_if_draw_happens_; | 174 bool swap_will_happen_if_draw_happens_; |
186 bool automatic_swap_ack_; | 175 bool automatic_swap_ack_; |
187 int num_draws_; | 176 int num_draws_; |
188 bool log_anticipated_draw_time_change_; | 177 bool log_anticipated_draw_time_change_; |
189 bool begin_frame_is_sent_to_children_; | |
190 base::TimeTicks posted_begin_impl_frame_deadline_; | 178 base::TimeTicks posted_begin_impl_frame_deadline_; |
191 std::vector<const char*> actions_; | 179 std::vector<const char*> actions_; |
192 std::vector<scoped_refptr<base::debug::ConvertableToTraceFormat>> states_; | 180 std::vector<scoped_refptr<base::debug::ConvertableToTraceFormat>> states_; |
193 TestScheduler* scheduler_; | 181 TestScheduler* scheduler_; |
194 }; | 182 }; |
195 | 183 |
| 184 class FakeProxyBeginFrameSource : public ProxyBeginFrameSource { |
| 185 public: |
| 186 FakeProxyBeginFrameSource() : begin_frame_is_sent_to_children_(false) {} |
| 187 ~FakeProxyBeginFrameSource() override {} |
| 188 |
| 189 bool begin_frame_is_sent_to_children() { |
| 190 return begin_frame_is_sent_to_children_; |
| 191 } |
| 192 |
| 193 void BeginFrames(const BeginFrameArgs& args) override { |
| 194 begin_frame_is_sent_to_children_ = true; |
| 195 } |
| 196 |
| 197 private: |
| 198 bool begin_frame_is_sent_to_children_; |
| 199 }; |
196 class FakePowerMonitorSource : public base::PowerMonitorSource { | 200 class FakePowerMonitorSource : public base::PowerMonitorSource { |
197 public: | 201 public: |
198 FakePowerMonitorSource() {} | 202 FakePowerMonitorSource() {} |
199 ~FakePowerMonitorSource() override {} | 203 ~FakePowerMonitorSource() override {} |
200 void GeneratePowerStateEvent(bool on_battery_power) { | 204 void GeneratePowerStateEvent(bool on_battery_power) { |
201 on_battery_power_impl_ = on_battery_power; | 205 on_battery_power_impl_ = on_battery_power; |
202 ProcessPowerEvent(POWER_STATE_EVENT); | 206 ProcessPowerEvent(POWER_STATE_EVENT); |
203 base::MessageLoop::current()->RunUntilIdle(); | 207 base::MessageLoop::current()->RunUntilIdle(); |
204 } | 208 } |
205 bool IsOnBatteryPowerImpl() override { return on_battery_power_impl_; } | 209 bool IsOnBatteryPowerImpl() override { return on_battery_power_impl_; } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 | 253 |
250 protected: | 254 protected: |
251 TestScheduler* CreateScheduler() { | 255 TestScheduler* CreateScheduler() { |
252 scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source; | 256 scoped_ptr<FakeExternalBeginFrameSource> fake_external_begin_frame_source; |
253 if (scheduler_settings_.use_external_begin_frame_source) { | 257 if (scheduler_settings_.use_external_begin_frame_source) { |
254 fake_external_begin_frame_source.reset( | 258 fake_external_begin_frame_source.reset( |
255 new FakeExternalBeginFrameSource(client_.get())); | 259 new FakeExternalBeginFrameSource(client_.get())); |
256 fake_external_begin_frame_source_ = | 260 fake_external_begin_frame_source_ = |
257 fake_external_begin_frame_source.get(); | 261 fake_external_begin_frame_source.get(); |
258 } | 262 } |
| 263 |
| 264 if (scheduler_settings_.forward_begin_frames_to_children) { |
| 265 fake_proxy_begin_frame_source_.reset(new FakeProxyBeginFrameSource); |
| 266 } |
259 scheduler_ = TestScheduler::Create( | 267 scheduler_ = TestScheduler::Create( |
260 now_src_, client_.get(), scheduler_settings_, 0, task_runner_, | 268 now_src_, client_.get(), scheduler_settings_, 0, task_runner_, |
261 &power_monitor_, fake_external_begin_frame_source.Pass()); | 269 &power_monitor_, fake_external_begin_frame_source.Pass(), |
| 270 fake_proxy_begin_frame_source_.get()); |
262 DCHECK(scheduler_); | 271 DCHECK(scheduler_); |
263 client_->set_scheduler(scheduler_.get()); | 272 client_->set_scheduler(scheduler_.get()); |
264 return scheduler_.get(); | 273 return scheduler_.get(); |
265 } | 274 } |
266 | 275 |
267 void CreateSchedulerAndInitSurface() { | 276 void CreateSchedulerAndInitSurface() { |
268 CreateScheduler(); | 277 CreateScheduler(); |
269 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit()); | 278 EXPECT_SCOPED(InitializeOutputSurfaceAndFirstCommit()); |
270 } | 279 } |
271 | 280 |
272 void SetUpScheduler(bool initSurface) { | 281 void SetUpScheduler(bool initSurface) { |
273 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface); | 282 SetUpScheduler(make_scoped_ptr(new FakeSchedulerClient), initSurface); |
274 } | 283 } |
275 | 284 |
276 void SetUpScheduler(scoped_ptr<FakeSchedulerClient> client, | 285 void SetUpScheduler(scoped_ptr<FakeSchedulerClient> client, |
277 bool initSurface) { | 286 bool initSurface) { |
278 client_ = client.Pass(); | 287 client_ = client.Pass(); |
279 if (initSurface) | 288 if (initSurface) |
280 CreateSchedulerAndInitSurface(); | 289 CreateSchedulerAndInitSurface(); |
281 else | 290 else |
282 CreateScheduler(); | 291 CreateScheduler(); |
283 } | 292 } |
284 | 293 |
| 294 bool begin_frame_is_sent_to_children() const { |
| 295 return fake_proxy_begin_frame_source_->begin_frame_is_sent_to_children(); |
| 296 } |
| 297 |
285 OrderedSimpleTaskRunner& task_runner() { return *task_runner_; } | 298 OrderedSimpleTaskRunner& task_runner() { return *task_runner_; } |
286 TestNowSource* now_src() { return now_src_.get(); } | 299 TestNowSource* now_src() { return now_src_.get(); } |
287 | 300 |
288 // As this function contains EXPECT macros, to allow debugging it should be | 301 // As this function contains EXPECT macros, to allow debugging it should be |
289 // called inside EXPECT_SCOPED like so; | 302 // called inside EXPECT_SCOPED like so; |
290 // EXPECT_SCOPED(client.InitializeOutputSurfaceAndFirstCommit(scheduler)); | 303 // EXPECT_SCOPED(client.InitializeOutputSurfaceAndFirstCommit(scheduler)); |
291 void InitializeOutputSurfaceAndFirstCommit() { | 304 void InitializeOutputSurfaceAndFirstCommit() { |
292 TRACE_EVENT0("cc", | 305 TRACE_EVENT0("cc", |
293 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit"); | 306 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit"); |
294 DCHECK(scheduler_); | 307 DCHECK(scheduler_); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 bool throttle_frame_production); | 415 bool throttle_frame_production); |
403 void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency( | 416 void DidLoseOutputSurfaceAfterBeginFrameStartedWithHighLatency( |
404 bool impl_side_painting); | 417 bool impl_side_painting); |
405 void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting); | 418 void DidLoseOutputSurfaceAfterReadyToCommit(bool impl_side_painting); |
406 | 419 |
407 scoped_refptr<TestNowSource> now_src_; | 420 scoped_refptr<TestNowSource> now_src_; |
408 scoped_refptr<OrderedSimpleTaskRunner> task_runner_; | 421 scoped_refptr<OrderedSimpleTaskRunner> task_runner_; |
409 FakeExternalBeginFrameSource* fake_external_begin_frame_source_; | 422 FakeExternalBeginFrameSource* fake_external_begin_frame_source_; |
410 FakePowerMonitorSource* fake_power_monitor_source_; | 423 FakePowerMonitorSource* fake_power_monitor_source_; |
411 base::PowerMonitor power_monitor_; | 424 base::PowerMonitor power_monitor_; |
| 425 scoped_ptr<FakeProxyBeginFrameSource> fake_proxy_begin_frame_source_; |
412 SchedulerSettings scheduler_settings_; | 426 SchedulerSettings scheduler_settings_; |
413 scoped_ptr<FakeSchedulerClient> client_; | 427 scoped_ptr<FakeSchedulerClient> client_; |
414 scoped_ptr<TestScheduler> scheduler_; | 428 scoped_ptr<TestScheduler> scheduler_; |
415 }; | 429 }; |
416 | 430 |
417 TEST_F(SchedulerTest, InitializeOutputSurfaceDoesNotBeginImplFrame) { | 431 TEST_F(SchedulerTest, InitializeOutputSurfaceDoesNotBeginImplFrame) { |
418 scheduler_settings_.use_external_begin_frame_source = true; | 432 scheduler_settings_.use_external_begin_frame_source = true; |
419 SetUpScheduler(false); | 433 SetUpScheduler(false); |
420 scheduler_->SetCanStart(); | 434 scheduler_->SetCanStart(); |
421 scheduler_->SetVisible(true); | 435 scheduler_->SetVisible(true); |
422 scheduler_->SetCanDraw(true); | 436 scheduler_->SetCanDraw(true); |
423 | 437 |
424 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_); | 438 EXPECT_SINGLE_ACTION("ScheduledActionBeginOutputSurfaceCreation", client_); |
425 client_->Reset(); | 439 client_->Reset(); |
426 scheduler_->DidCreateAndInitializeOutputSurface(); | 440 scheduler_->DidCreateAndInitializeOutputSurface(); |
427 EXPECT_NO_ACTION(client_); | 441 EXPECT_NO_ACTION(client_); |
428 } | 442 } |
429 | 443 |
430 TEST_F(SchedulerTest, SendBeginFramesToChildren) { | 444 TEST_F(SchedulerTest, SendBeginFramesToChildren) { |
431 scheduler_settings_.use_external_begin_frame_source = true; | 445 scheduler_settings_.use_external_begin_frame_source = true; |
432 scheduler_settings_.forward_begin_frames_to_children = true; | 446 scheduler_settings_.forward_begin_frames_to_children = true; |
433 SetUpScheduler(true); | 447 SetUpScheduler(true); |
434 | 448 |
435 EXPECT_FALSE(client_->begin_frame_is_sent_to_children()); | 449 EXPECT_FALSE(begin_frame_is_sent_to_children()); |
436 scheduler_->SetNeedsCommit(); | 450 scheduler_->SetNeedsCommit(); |
437 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 451 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
438 EXPECT_TRUE(client_->needs_begin_frames()); | 452 EXPECT_TRUE(client_->needs_begin_frames()); |
439 | 453 |
440 scheduler_->SetChildrenNeedBeginFrames(true); | 454 scheduler_->SetChildrenNeedBeginFrames(true); |
441 | 455 |
442 client_->Reset(); | 456 client_->Reset(); |
443 EXPECT_SCOPED(AdvanceFrame()); | 457 EXPECT_SCOPED(AdvanceFrame()); |
444 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); | 458 EXPECT_TRUE(begin_frame_is_sent_to_children()); |
445 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 459 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
446 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); | 460 EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); |
447 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); | 461 EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); |
448 EXPECT_TRUE(client_->needs_begin_frames()); | 462 EXPECT_TRUE(client_->needs_begin_frames()); |
449 } | 463 } |
450 | 464 |
451 TEST_F(SchedulerTest, SendBeginFramesToChildrenWithoutCommit) { | 465 TEST_F(SchedulerTest, SendBeginFramesToChildrenWithoutCommit) { |
452 scheduler_settings_.use_external_begin_frame_source = true; | 466 scheduler_settings_.use_external_begin_frame_source = true; |
453 scheduler_settings_.forward_begin_frames_to_children = true; | 467 scheduler_settings_.forward_begin_frames_to_children = true; |
454 SetUpScheduler(true); | 468 SetUpScheduler(true); |
455 | 469 |
456 EXPECT_FALSE(client_->needs_begin_frames()); | 470 EXPECT_FALSE(client_->needs_begin_frames()); |
457 scheduler_->SetChildrenNeedBeginFrames(true); | 471 scheduler_->SetChildrenNeedBeginFrames(true); |
458 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 472 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
459 EXPECT_TRUE(client_->needs_begin_frames()); | 473 EXPECT_TRUE(client_->needs_begin_frames()); |
460 | 474 |
461 client_->Reset(); | 475 client_->Reset(); |
462 EXPECT_SCOPED(AdvanceFrame()); | 476 EXPECT_SCOPED(AdvanceFrame()); |
463 EXPECT_TRUE(client_->begin_frame_is_sent_to_children()); | 477 EXPECT_TRUE(begin_frame_is_sent_to_children()); |
464 } | 478 } |
465 | 479 |
466 TEST_F(SchedulerTest, RequestCommit) { | 480 TEST_F(SchedulerTest, RequestCommit) { |
467 scheduler_settings_.use_external_begin_frame_source = true; | 481 scheduler_settings_.use_external_begin_frame_source = true; |
468 SetUpScheduler(true); | 482 SetUpScheduler(true); |
469 | 483 |
470 // SetNeedsCommit should begin the frame on the next BeginImplFrame. | 484 // SetNeedsCommit should begin the frame on the next BeginImplFrame. |
471 scheduler_->SetNeedsCommit(); | 485 scheduler_->SetNeedsCommit(); |
472 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); | 486 EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_); |
473 client_->Reset(); | 487 client_->Reset(); |
(...skipping 1797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2271 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); | 2285 EXPECT_ACTION("ScheduledActionAnimate", client_, 1, 2); |
2272 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); | 2286 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); |
2273 EXPECT_TRUE(client_->needs_begin_frames()); | 2287 EXPECT_TRUE(client_->needs_begin_frames()); |
2274 client_->Reset(); | 2288 client_->Reset(); |
2275 task_runner().RunPendingTasks(); // Run posted deadline. | 2289 task_runner().RunPendingTasks(); // Run posted deadline. |
2276 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); | 2290 EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); |
2277 } | 2291 } |
2278 | 2292 |
2279 } // namespace | 2293 } // namespace |
2280 } // namespace cc | 2294 } // namespace cc |
OLD | NEW |