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

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

Issue 554973002: Disable scheduler deadline task on battery power in Windows (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 6 years, 2 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
« no previous file with comments | « cc/scheduler/scheduler_state_machine.cc ('k') | cc/test/scheduler_test_common.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "cc/scheduler/scheduler.h" 4 #include "cc/scheduler/scheduler.h"
5 5
6 #include <string> 6 #include <string>
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/memory/scoped_vector.h" 11 #include "base/memory/scoped_vector.h"
12 #include "base/message_loop/message_loop.h" 12 #include "base/message_loop/message_loop.h"
13 #include "base/power_monitor/power_monitor.h"
14 #include "base/power_monitor/power_monitor_source.h"
13 #include "base/run_loop.h" 15 #include "base/run_loop.h"
14 #include "base/time/time.h" 16 #include "base/time/time.h"
15 #include "cc/test/begin_frame_args_test.h" 17 #include "cc/test/begin_frame_args_test.h"
16 #include "cc/test/ordered_simple_task_runner.h" 18 #include "cc/test/ordered_simple_task_runner.h"
17 #include "cc/test/scheduler_test_common.h" 19 #include "cc/test/scheduler_test_common.h"
18 #include "testing/gmock/include/gmock/gmock.h" 20 #include "testing/gmock/include/gmock/gmock.h"
19 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
20 22
21 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \ 23 #define EXPECT_ACTION(action, client, action_index, expected_num_actions) \
22 do { \ 24 do { \
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 virtual void OnNeedsBeginFramesChange(bool needs_begin_frames) override { 58 virtual void OnNeedsBeginFramesChange(bool needs_begin_frames) override {
57 if (needs_begin_frames) { 59 if (needs_begin_frames) {
58 client_->actions_.push_back("SetNeedsBeginFrames(true)"); 60 client_->actions_.push_back("SetNeedsBeginFrames(true)");
59 } else { 61 } else {
60 client_->actions_.push_back("SetNeedsBeginFrames(false)"); 62 client_->actions_.push_back("SetNeedsBeginFrames(false)");
61 } 63 }
62 client_->states_.push_back(client_->scheduler_->AsValue()); 64 client_->states_.push_back(client_->scheduler_->AsValue());
63 } 65 }
64 }; 66 };
65 67
68 class FakePowerMonitorSource : public base::PowerMonitorSource {
69 public:
70 FakePowerMonitorSource() {}
71 virtual ~FakePowerMonitorSource() {}
72 void GeneratePowerStateEvent(bool on_battery_power) {
73 on_battery_power_impl_ = on_battery_power;
74 ProcessPowerEvent(POWER_STATE_EVENT);
75 base::MessageLoop::current()->RunUntilIdle();
76 }
77 virtual bool IsOnBatteryPowerImpl() override {
78 return on_battery_power_impl_;
79 }
80
81 private:
82 bool on_battery_power_impl_;
83 };
84
66 FakeSchedulerClient() 85 FakeSchedulerClient()
67 : automatic_swap_ack_(true), 86 : automatic_swap_ack_(true),
68 swap_contains_incomplete_tile_(false), 87 swap_contains_incomplete_tile_(false),
69 redraw_will_happen_if_update_visible_tiles_happens_(false), 88 redraw_will_happen_if_update_visible_tiles_happens_(false),
70 now_src_(TestNowSource::Create()), 89 now_src_(TestNowSource::Create()),
71 fake_frame_source_(this) { 90 task_runner_(new OrderedSimpleTaskRunner(now_src_, true)),
91 fake_frame_source_(this),
92 fake_power_monitor_source_(new FakePowerMonitorSource),
93 power_monitor_(make_scoped_ptr<base::PowerMonitorSource>(
94 fake_power_monitor_source_)),
95 scheduler_(nullptr) {
96 // A bunch of tests require Now() to be > BeginFrameArgs::DefaultInterval()
97 now_src_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
98 // Fail if we need to run 100 tasks in a row.
99 task_runner_->SetRunTaskLimit(100);
72 Reset(); 100 Reset();
73 } 101 }
74 102
75 void Reset() { 103 void Reset() {
76 actions_.clear(); 104 actions_.clear();
77 states_.clear(); 105 states_.clear();
78 draw_will_happen_ = true; 106 draw_will_happen_ = true;
79 swap_will_happen_if_draw_happens_ = true; 107 swap_will_happen_if_draw_happens_ = true;
80 num_draws_ = 0; 108 num_draws_ = 0;
81 log_anticipated_draw_time_change_ = false; 109 log_anticipated_draw_time_change_ = false;
82 } 110 }
83 111
84 TestScheduler* CreateScheduler(const SchedulerSettings& settings) { 112 TestScheduler* CreateScheduler(const SchedulerSettings& settings) {
85 scheduler_ = TestScheduler::Create(now_src_, this, settings, 0); 113 scheduler_ = TestScheduler::Create(
114 now_src_, this, settings, 0, task_runner_, &power_monitor_);
86 DCHECK(scheduler_); 115 DCHECK(scheduler_);
87 // Fail if we need to run 100 tasks in a row.
88 task_runner().SetRunTaskLimit(100);
89 return scheduler_.get(); 116 return scheduler_.get();
90 } 117 }
91 118
92 // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it 119 // Most tests don't care about DidAnticipatedDrawTimeChange, so only record it
93 // for tests that do. 120 // for tests that do.
94 void set_log_anticipated_draw_time_change(bool log) { 121 void set_log_anticipated_draw_time_change(bool log) {
95 log_anticipated_draw_time_change_ = log; 122 log_anticipated_draw_time_change_ = log;
96 } 123 }
97 bool needs_begin_frames() { return fake_frame_source_.NeedsBeginFrames(); } 124 bool needs_begin_frames() { return fake_frame_source_.NeedsBeginFrames(); }
98 int num_draws() const { return num_draws_; } 125 int num_draws() const { return num_draws_; }
99 int num_actions_() const { return static_cast<int>(actions_.size()); } 126 int num_actions_() const { return static_cast<int>(actions_.size()); }
100 const char* Action(int i) const { return actions_[i]; } 127 const char* Action(int i) const { return actions_[i]; }
101 std::string StateForAction(int i) const { return states_[i]->ToString(); } 128 std::string StateForAction(int i) const { return states_[i]->ToString(); }
102 base::TimeTicks posted_begin_impl_frame_deadline() const { 129 base::TimeTicks posted_begin_impl_frame_deadline() const {
103 return posted_begin_impl_frame_deadline_; 130 return posted_begin_impl_frame_deadline_;
104 } 131 }
105 132
106 bool ExternalBeginFrame() { 133 bool ExternalBeginFrame() {
107 return scheduler_->settings().begin_frame_scheduling_enabled && 134 return scheduler_->settings().begin_frame_scheduling_enabled &&
108 scheduler_->settings().throttle_frame_production; 135 scheduler_->settings().throttle_frame_production;
109 } 136 }
110 virtual FakeBeginFrameSource* ExternalBeginFrameSource() override { 137 virtual FakeBeginFrameSource* ExternalBeginFrameSource() override {
111 return &fake_frame_source_; 138 return &fake_frame_source_;
112 } 139 }
113 140
141 base::PowerMonitor* PowerMonitor() { return &power_monitor_; }
142
143 FakePowerMonitorSource* PowerMonitorSource() {
144 return fake_power_monitor_source_;
145 }
146
114 void AdvanceFrame() { 147 void AdvanceFrame() {
115 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), 148 TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
116 "FakeSchedulerClient::AdvanceFrame"); 149 "FakeSchedulerClient::AdvanceFrame");
117 // EXPECT_TRUE(needs_begin_frames()); 150 // EXPECT_TRUE(needs_begin_frames());
118 if (ExternalBeginFrame()) { 151 if (ExternalBeginFrame()) {
119 // Creep the time forward so that any BeginFrameArgs is not equal to the 152 // Creep the time forward so that any BeginFrameArgs is not equal to the
120 // last one otherwise we violate the BeginFrameSource contract. 153 // last one otherwise we violate the BeginFrameSource contract.
121 now_src_->AdvanceNowMicroseconds(1); 154 now_src_->AdvanceNowMicroseconds(1);
122 fake_frame_source_.TestOnBeginFrame( 155 fake_frame_source_.TestOnBeginFrame(
123 CreateBeginFrameArgsForTesting(now_src_)); 156 CreateBeginFrameArgsForTesting(now_src_));
124 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); 157 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
125 } 158 }
126 159
127 EXPECT_TRUE(task_runner().RunTasksWhile(ImplFrameDeadlinePending(false))); 160 EXPECT_TRUE(task_runner().RunTasksWhile(ImplFrameDeadlinePending(false)));
128 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending()); 161 EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
129 } 162 }
130 163
131 OrderedSimpleTaskRunner& task_runner() { return scheduler_->task_runner(); } 164 OrderedSimpleTaskRunner& task_runner() { return *task_runner_; }
132 TestNowSource* now_src() { return now_src_.get(); } 165 TestNowSource* now_src() { return now_src_.get(); }
133 166
134 int ActionIndex(const char* action) const { 167 int ActionIndex(const char* action) const {
135 for (size_t i = 0; i < actions_.size(); i++) 168 for (size_t i = 0; i < actions_.size(); i++)
136 if (!strcmp(actions_[i], action)) 169 if (!strcmp(actions_[i], action))
137 return i; 170 return i;
138 return -1; 171 return -1;
139 } 172 }
140 173
141 void SetSwapContainsIncompleteTile(bool contain) { 174 void SetSwapContainsIncompleteTile(bool contain) {
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 bool draw_will_happen_; 283 bool draw_will_happen_;
251 bool swap_will_happen_if_draw_happens_; 284 bool swap_will_happen_if_draw_happens_;
252 bool automatic_swap_ack_; 285 bool automatic_swap_ack_;
253 int num_draws_; 286 int num_draws_;
254 bool log_anticipated_draw_time_change_; 287 bool log_anticipated_draw_time_change_;
255 bool swap_contains_incomplete_tile_; 288 bool swap_contains_incomplete_tile_;
256 bool redraw_will_happen_if_update_visible_tiles_happens_; 289 bool redraw_will_happen_if_update_visible_tiles_happens_;
257 base::TimeTicks posted_begin_impl_frame_deadline_; 290 base::TimeTicks posted_begin_impl_frame_deadline_;
258 std::vector<const char*> actions_; 291 std::vector<const char*> actions_;
259 std::vector<scoped_refptr<base::debug::ConvertableToTraceFormat>> states_; 292 std::vector<scoped_refptr<base::debug::ConvertableToTraceFormat>> states_;
293 scoped_refptr<TestNowSource> now_src_;
294 scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
295 FakeBeginFrameSourceForFakeSchedulerClient fake_frame_source_;
296 FakePowerMonitorSource* fake_power_monitor_source_;
297 base::PowerMonitor power_monitor_;
260 scoped_ptr<TestScheduler> scheduler_; 298 scoped_ptr<TestScheduler> scheduler_;
261 scoped_refptr<TestNowSource> now_src_;
262 FakeBeginFrameSourceForFakeSchedulerClient fake_frame_source_;
263 }; 299 };
264 300
265 void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler, 301 void InitializeOutputSurfaceAndFirstCommit(Scheduler* scheduler,
266 FakeSchedulerClient* client) { 302 FakeSchedulerClient* client) {
267 TRACE_EVENT0("cc", 303 TRACE_EVENT0("cc",
268 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit"); 304 "SchedulerUnitTest::InitializeOutputSurfaceAndFirstCommit");
269 305
270 scheduler->DidCreateAndInitializeOutputSurface(); 306 scheduler->DidCreateAndInitializeOutputSurface();
271 scheduler->SetNeedsCommit(); 307 scheduler->SetNeedsCommit();
272 scheduler->NotifyBeginMainFrameStarted(); 308 scheduler->NotifyBeginMainFrameStarted();
(...skipping 1687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1960 scheduler->NotifyReadyToCommit(); 1996 scheduler->NotifyReadyToCommit();
1961 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client); 1997 EXPECT_SINGLE_ACTION("ScheduledActionCommit", client);
1962 1998
1963 client.Reset(); 1999 client.Reset();
1964 scheduler->SetVisible(false); 2000 scheduler->SetVisible(false);
1965 // Sync tree should be forced to activate. 2001 // Sync tree should be forced to activate.
1966 EXPECT_ACTION("SetNeedsBeginFrames(false)", client, 0, 2); 2002 EXPECT_ACTION("SetNeedsBeginFrames(false)", client, 0, 2);
1967 EXPECT_ACTION("ScheduledActionActivateSyncTree", client, 1, 2); 2003 EXPECT_ACTION("ScheduledActionActivateSyncTree", client, 1, 2);
1968 } 2004 }
1969 2005
2006 TEST(SchedulerTest, SchedulerPowerMonitoring) {
2007 FakeSchedulerClient client;
2008 SchedulerSettings settings;
2009 settings.disable_hi_res_timer_tasks_on_battery = true;
2010 TestScheduler* scheduler = client.CreateScheduler(settings);
2011
2012 base::TimeTicks before_deadline, after_deadline;
2013
2014 scheduler->SetCanStart();
2015 scheduler->SetVisible(true);
2016 scheduler->SetCanDraw(true);
2017
2018 InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
2019
2020 scheduler->SetNeedsCommit();
2021 scheduler->SetNeedsRedraw();
2022 client.Reset();
2023
2024 // On non-battery power
2025 EXPECT_FALSE(client.PowerMonitor()->IsOnBatteryPower());
2026
2027 client.AdvanceFrame();
2028 client.Reset();
2029
2030 before_deadline = client.now_src()->Now();
2031 EXPECT_TRUE(client.task_runner().RunTasksWhile(
2032 client.ImplFrameDeadlinePending(true)));
2033 after_deadline = client.now_src()->Now();
2034
2035 // We post a non-zero deadline task when not on battery
2036 EXPECT_LT(before_deadline, after_deadline);
2037
2038 // Switch to battery power
2039 client.PowerMonitorSource()->GeneratePowerStateEvent(true);
2040 EXPECT_TRUE(client.PowerMonitor()->IsOnBatteryPower());
2041
2042 client.AdvanceFrame();
2043 scheduler->SetNeedsCommit();
2044 scheduler->SetNeedsRedraw();
2045 client.Reset();
2046
2047 before_deadline = client.now_src()->Now();
2048 EXPECT_TRUE(client.task_runner().RunTasksWhile(
2049 client.ImplFrameDeadlinePending(true)));
2050 after_deadline = client.now_src()->Now();
2051
2052 // We post a zero deadline task when on battery
2053 EXPECT_EQ(before_deadline, after_deadline);
2054
2055 // Switch to non-battery power
2056 client.PowerMonitorSource()->GeneratePowerStateEvent(false);
2057 EXPECT_FALSE(client.PowerMonitor()->IsOnBatteryPower());
2058
2059 client.AdvanceFrame();
2060 scheduler->SetNeedsCommit();
2061 scheduler->SetNeedsRedraw();
2062 client.Reset();
2063
2064 // Same as before
2065 before_deadline = client.now_src()->Now();
2066 EXPECT_TRUE(client.task_runner().RunTasksWhile(
2067 client.ImplFrameDeadlinePending(true)));
2068 after_deadline = client.now_src()->Now();
2069 }
2070
2071 TEST(SchedulerTest,
2072 SimulateWindowsLowResolutionTimerOnBattery_PrioritizeImplLatencyOff) {
2073 FakeSchedulerClient client;
2074 SchedulerSettings settings;
2075 TestScheduler* scheduler = client.CreateScheduler(settings);
2076
2077 scheduler->SetCanStart();
2078 scheduler->SetVisible(true);
2079 scheduler->SetCanDraw(true);
2080
2081 InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
2082
2083 // Set needs commit so that the scheduler tries to wait for the main thread
2084 scheduler->SetNeedsCommit();
2085 // Set needs redraw so that the scheduler doesn't wait too long
2086 scheduler->SetNeedsRedraw();
2087 client.Reset();
2088
2089 // Switch to battery power
2090 client.PowerMonitorSource()->GeneratePowerStateEvent(true);
2091 EXPECT_TRUE(client.PowerMonitor()->IsOnBatteryPower());
2092
2093 client.AdvanceFrame();
2094 scheduler->SetNeedsCommit();
2095 scheduler->SetNeedsRedraw();
2096 client.Reset();
2097
2098 // Disable auto-advancing of now_src
2099 client.task_runner().SetAutoAdvanceNowToPendingTasks(false);
2100
2101 // Deadline task is pending
2102 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
2103 client.task_runner().RunPendingTasks();
2104 // Deadline task is still pending
2105 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
2106
2107 // Advance now by 15 ms - same as windows low res timer
2108 client.now_src()->AdvanceNowMicroseconds(15000);
2109 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
2110 client.task_runner().RunPendingTasks();
2111 // Deadline task finally completes
2112 EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
2113 }
2114
2115 TEST(SchedulerTest,
2116 SimulateWindowsLowResolutionTimerOnBattery_PrioritizeImplLatencyOn) {
2117 FakeSchedulerClient client;
2118 SchedulerSettings settings;
2119 settings.disable_hi_res_timer_tasks_on_battery = true;
2120 TestScheduler* scheduler = client.CreateScheduler(settings);
2121
2122 scheduler->SetCanStart();
2123 scheduler->SetVisible(true);
2124 scheduler->SetCanDraw(true);
2125
2126 InitializeOutputSurfaceAndFirstCommit(scheduler, &client);
2127
2128 // Set needs commit so that the scheduler tries to wait for the main thread
2129 scheduler->SetNeedsCommit();
2130 // Set needs redraw so that the scheduler doesn't wait too long
2131 scheduler->SetNeedsRedraw();
2132 client.Reset();
2133
2134 // Switch to battery power
2135 client.PowerMonitorSource()->GeneratePowerStateEvent(true);
2136 EXPECT_TRUE(client.PowerMonitor()->IsOnBatteryPower());
2137
2138 client.AdvanceFrame();
2139 scheduler->SetNeedsCommit();
2140 scheduler->SetNeedsRedraw();
2141 client.Reset();
2142
2143 // Disable auto-advancing of now_src
2144 client.task_runner().SetAutoAdvanceNowToPendingTasks(false);
2145
2146 // Deadline task is pending
2147 EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
2148 client.task_runner().RunPendingTasks();
2149 // Deadline task runs immediately
2150 EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
2151 }
2152
1970 } // namespace 2153 } // namespace
1971 } // namespace cc 2154 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.cc ('k') | cc/test/scheduler_test_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698