| 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 |