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/frame_rate_controller.h" | 5 #include "cc/scheduler/frame_rate_controller.h" |
6 | 6 |
| 7 #include "base/test/test_simple_task_runner.h" |
7 #include "cc/test/scheduler_test_common.h" | 8 #include "cc/test/scheduler_test_common.h" |
8 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
9 | 10 |
10 namespace cc { | 11 namespace cc { |
11 namespace { | 12 namespace { |
12 | 13 |
13 class FakeFrameRateControllerClient : public cc::FrameRateControllerClient { | 14 class FakeFrameRateControllerClient : public cc::FrameRateControllerClient { |
14 public: | 15 public: |
15 FakeFrameRateControllerClient() { Reset(); } | 16 FakeFrameRateControllerClient() { Reset(); } |
16 | 17 |
17 void Reset() { began_frame_ = false; } | 18 void Reset() { began_frame_ = false; } |
18 bool BeganFrame() const { return began_frame_; } | 19 bool BeganFrame() const { return began_frame_; } |
19 | 20 |
20 virtual void FrameRateControllerTick(bool throttled) OVERRIDE { | 21 virtual void FrameRateControllerTick(bool throttled) OVERRIDE { |
21 began_frame_ = !throttled; | 22 began_frame_ = !throttled; |
22 } | 23 } |
23 | 24 |
24 protected: | 25 protected: |
25 bool began_frame_; | 26 bool began_frame_; |
26 }; | 27 }; |
27 | 28 |
28 TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) { | 29 TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) { |
29 FakeThread thread; | 30 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
| 31 new base::TestSimpleTaskRunner; |
30 FakeFrameRateControllerClient client; | 32 FakeFrameRateControllerClient client; |
31 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( | 33 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( |
32 base::Time::kMicrosecondsPerSecond / 60); | 34 base::Time::kMicrosecondsPerSecond / 60); |
33 scoped_refptr<FakeDelayBasedTimeSource> time_source = | 35 scoped_refptr<FakeDelayBasedTimeSource> time_source = |
34 FakeDelayBasedTimeSource::Create(interval, &thread); | 36 FakeDelayBasedTimeSource::Create(interval, task_runner.get()); |
35 FrameRateController controller(time_source); | 37 FrameRateController controller(time_source); |
36 | 38 |
37 controller.SetClient(&client); | 39 controller.SetClient(&client); |
38 controller.SetActive(true); | 40 controller.SetActive(true); |
39 | 41 |
40 base::TimeTicks elapsed; // Muck around with time a bit | 42 base::TimeTicks elapsed; // Muck around with time a bit |
41 | 43 |
42 // Trigger one frame, make sure the BeginFrame callback is called | 44 // Trigger one frame, make sure the BeginFrame callback is called |
43 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 45 elapsed += task_runner->NextPendingTaskDelay(); |
44 time_source->SetNow(elapsed); | 46 time_source->SetNow(elapsed); |
45 thread.RunPendingTask(); | 47 task_runner->RunPendingTasks(); |
46 EXPECT_TRUE(client.BeganFrame()); | 48 EXPECT_TRUE(client.BeganFrame()); |
47 client.Reset(); | 49 client.Reset(); |
48 | 50 |
49 // Tell the controller we drew | 51 // Tell the controller we drew |
50 controller.DidSwapBuffers(); | 52 controller.DidSwapBuffers(); |
51 | 53 |
52 // Tell the controller the frame ended 5ms later | 54 // Tell the controller the frame ended 5ms later |
53 time_source->SetNow(time_source->Now() + | 55 time_source->SetNow(time_source->Now() + |
54 base::TimeDelta::FromMilliseconds(5)); | 56 base::TimeDelta::FromMilliseconds(5)); |
55 controller.DidSwapBuffersComplete(); | 57 controller.DidSwapBuffersComplete(); |
56 | 58 |
57 // Trigger another frame, make sure BeginFrame runs again | 59 // Trigger another frame, make sure BeginFrame runs again |
58 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 60 elapsed += task_runner->NextPendingTaskDelay(); |
59 // Sanity check that previous code didn't move time backward. | 61 // Sanity check that previous code didn't move time backward. |
60 EXPECT_GE(elapsed, time_source->Now()); | 62 EXPECT_GE(elapsed, time_source->Now()); |
61 time_source->SetNow(elapsed); | 63 time_source->SetNow(elapsed); |
62 thread.RunPendingTask(); | 64 task_runner->RunPendingTasks(); |
63 EXPECT_TRUE(client.BeganFrame()); | 65 EXPECT_TRUE(client.BeganFrame()); |
64 } | 66 } |
65 | 67 |
66 TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { | 68 TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { |
67 FakeThread thread; | 69 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
| 70 new base::TestSimpleTaskRunner; |
68 FakeFrameRateControllerClient client; | 71 FakeFrameRateControllerClient client; |
69 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( | 72 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( |
70 base::Time::kMicrosecondsPerSecond / 60); | 73 base::Time::kMicrosecondsPerSecond / 60); |
71 scoped_refptr<FakeDelayBasedTimeSource> time_source = | 74 scoped_refptr<FakeDelayBasedTimeSource> time_source = |
72 FakeDelayBasedTimeSource::Create(interval, &thread); | 75 FakeDelayBasedTimeSource::Create(interval, task_runner.get()); |
73 FrameRateController controller(time_source); | 76 FrameRateController controller(time_source); |
74 | 77 |
75 controller.SetClient(&client); | 78 controller.SetClient(&client); |
76 controller.SetActive(true); | 79 controller.SetActive(true); |
77 controller.SetMaxSwapsPending(2); | 80 controller.SetMaxSwapsPending(2); |
78 | 81 |
79 base::TimeTicks elapsed; // Muck around with time a bit | 82 base::TimeTicks elapsed; // Muck around with time a bit |
80 | 83 |
81 // Trigger one frame, make sure the BeginFrame callback is called | 84 // Trigger one frame, make sure the BeginFrame callback is called |
82 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 85 elapsed += task_runner->NextPendingTaskDelay(); |
83 time_source->SetNow(elapsed); | 86 time_source->SetNow(elapsed); |
84 thread.RunPendingTask(); | 87 task_runner->RunPendingTasks(); |
85 EXPECT_TRUE(client.BeganFrame()); | 88 EXPECT_TRUE(client.BeganFrame()); |
86 client.Reset(); | 89 client.Reset(); |
87 | 90 |
88 // Tell the controller we drew | 91 // Tell the controller we drew |
89 controller.DidSwapBuffers(); | 92 controller.DidSwapBuffers(); |
90 | 93 |
91 // Trigger another frame, make sure BeginFrame callback runs again | 94 // Trigger another frame, make sure BeginFrame callback runs again |
92 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 95 elapsed += task_runner->NextPendingTaskDelay(); |
93 // Sanity check that previous code didn't move time backward. | 96 // Sanity check that previous code didn't move time backward. |
94 EXPECT_GE(elapsed, time_source->Now()); | 97 EXPECT_GE(elapsed, time_source->Now()); |
95 time_source->SetNow(elapsed); | 98 time_source->SetNow(elapsed); |
96 thread.RunPendingTask(); | 99 task_runner->RunPendingTasks(); |
97 EXPECT_TRUE(client.BeganFrame()); | 100 EXPECT_TRUE(client.BeganFrame()); |
98 client.Reset(); | 101 client.Reset(); |
99 | 102 |
100 // Tell the controller we drew, again. | 103 // Tell the controller we drew, again. |
101 controller.DidSwapBuffers(); | 104 controller.DidSwapBuffers(); |
102 | 105 |
103 // Trigger another frame. Since two frames are pending, we should not draw. | 106 // Trigger another frame. Since two frames are pending, we should not draw. |
104 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 107 elapsed += task_runner->NextPendingTaskDelay(); |
105 // Sanity check that previous code didn't move time backward. | 108 // Sanity check that previous code didn't move time backward. |
106 EXPECT_GE(elapsed, time_source->Now()); | 109 EXPECT_GE(elapsed, time_source->Now()); |
107 time_source->SetNow(elapsed); | 110 time_source->SetNow(elapsed); |
108 thread.RunPendingTask(); | 111 task_runner->RunPendingTasks(); |
109 EXPECT_FALSE(client.BeganFrame()); | 112 EXPECT_FALSE(client.BeganFrame()); |
110 | 113 |
111 // Tell the controller the first frame ended 5ms later | 114 // Tell the controller the first frame ended 5ms later |
112 time_source->SetNow(time_source->Now() + | 115 time_source->SetNow(time_source->Now() + |
113 base::TimeDelta::FromMilliseconds(5)); | 116 base::TimeDelta::FromMilliseconds(5)); |
114 controller.DidSwapBuffersComplete(); | 117 controller.DidSwapBuffersComplete(); |
115 | 118 |
116 // Tick should not have been called | 119 // Tick should not have been called |
117 EXPECT_FALSE(client.BeganFrame()); | 120 EXPECT_FALSE(client.BeganFrame()); |
118 | 121 |
119 // Trigger yet another frame. Since one frames is pending, another | 122 // Trigger yet another frame. Since one frames is pending, another |
120 // BeginFrame callback should run. | 123 // BeginFrame callback should run. |
121 elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); | 124 elapsed += task_runner->NextPendingTaskDelay(); |
122 // Sanity check that previous code didn't move time backward. | 125 // Sanity check that previous code didn't move time backward. |
123 EXPECT_GE(elapsed, time_source->Now()); | 126 EXPECT_GE(elapsed, time_source->Now()); |
124 time_source->SetNow(elapsed); | 127 time_source->SetNow(elapsed); |
125 thread.RunPendingTask(); | 128 task_runner->RunPendingTasks(); |
126 EXPECT_TRUE(client.BeganFrame()); | 129 EXPECT_TRUE(client.BeganFrame()); |
127 } | 130 } |
128 | 131 |
129 TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) { | 132 TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) { |
130 FakeThread thread; | 133 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
| 134 new base::TestSimpleTaskRunner; |
131 FakeFrameRateControllerClient client; | 135 FakeFrameRateControllerClient client; |
132 FrameRateController controller(&thread); | 136 FrameRateController controller(task_runner.get()); |
133 | 137 |
134 controller.SetClient(&client); | 138 controller.SetClient(&client); |
135 controller.SetMaxSwapsPending(2); | 139 controller.SetMaxSwapsPending(2); |
136 | 140 |
137 // SetActive triggers 1st frame, make sure the BeginFrame callback | 141 // SetActive triggers 1st frame, make sure the BeginFrame callback |
138 // is called | 142 // is called |
139 controller.SetActive(true); | 143 controller.SetActive(true); |
140 thread.RunPendingTask(); | 144 task_runner->RunPendingTasks(); |
141 EXPECT_TRUE(client.BeganFrame()); | 145 EXPECT_TRUE(client.BeganFrame()); |
142 client.Reset(); | 146 client.Reset(); |
143 | 147 |
144 // Even if we don't call DidSwapBuffers, FrameRateController should | 148 // Even if we don't call DidSwapBuffers, FrameRateController should |
145 // still attempt to tick multiple times until it does result in | 149 // still attempt to tick multiple times until it does result in |
146 // a DidSwapBuffers. | 150 // a DidSwapBuffers. |
147 thread.RunPendingTask(); | 151 task_runner->RunPendingTasks(); |
148 EXPECT_TRUE(client.BeganFrame()); | 152 EXPECT_TRUE(client.BeganFrame()); |
149 client.Reset(); | 153 client.Reset(); |
150 | 154 |
151 thread.RunPendingTask(); | 155 task_runner->RunPendingTasks(); |
152 EXPECT_TRUE(client.BeganFrame()); | 156 EXPECT_TRUE(client.BeganFrame()); |
153 client.Reset(); | 157 client.Reset(); |
154 | 158 |
155 // DidSwapBuffers triggers 2nd frame, make sure the BeginFrame callback is | 159 // DidSwapBuffers triggers 2nd frame, make sure the BeginFrame callback is |
156 // called | 160 // called |
157 controller.DidSwapBuffers(); | 161 controller.DidSwapBuffers(); |
158 thread.RunPendingTask(); | 162 task_runner->RunPendingTasks(); |
159 EXPECT_TRUE(client.BeganFrame()); | 163 EXPECT_TRUE(client.BeganFrame()); |
160 client.Reset(); | 164 client.Reset(); |
161 | 165 |
162 // DidSwapBuffers triggers 3rd frame (> max_frames_pending), | 166 // DidSwapBuffers triggers 3rd frame (> max_frames_pending), |
163 // make sure the BeginFrame callback is NOT called | 167 // make sure the BeginFrame callback is NOT called |
164 controller.DidSwapBuffers(); | 168 controller.DidSwapBuffers(); |
165 thread.RunPendingTask(); | 169 task_runner->RunPendingTasks(); |
166 EXPECT_FALSE(client.BeganFrame()); | 170 EXPECT_FALSE(client.BeganFrame()); |
167 client.Reset(); | 171 client.Reset(); |
168 | 172 |
169 // Make sure there is no pending task since we can't do anything until we | 173 // Make sure there is no pending task since we can't do anything until we |
170 // receive a DidSwapBuffersComplete anyway. | 174 // receive a DidSwapBuffersComplete anyway. |
171 EXPECT_FALSE(thread.HasPendingTask()); | 175 EXPECT_FALSE(task_runner->HasPendingTask()); |
172 | 176 |
173 // DidSwapBuffersComplete triggers a frame, make sure the BeginFrame | 177 // DidSwapBuffersComplete triggers a frame, make sure the BeginFrame |
174 // callback is called | 178 // callback is called |
175 controller.DidSwapBuffersComplete(); | 179 controller.DidSwapBuffersComplete(); |
176 thread.RunPendingTask(); | 180 task_runner->RunPendingTasks(); |
177 EXPECT_TRUE(client.BeganFrame()); | 181 EXPECT_TRUE(client.BeganFrame()); |
178 } | 182 } |
179 | 183 |
180 } // namespace | 184 } // namespace |
181 } // namespace cc | 185 } // namespace cc |
OLD | NEW |