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/delay_based_time_source.h" | 5 #include "cc/scheduler/delay_based_time_source.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "cc/base/thread.h" | 8 #include "base/test/test_simple_task_runner.h" |
9 #include "cc/test/scheduler_test_common.h" | 9 #include "cc/test/scheduler_test_common.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
11 | 11 |
12 namespace cc { | 12 namespace cc { |
13 namespace { | 13 namespace { |
14 | 14 |
15 base::TimeDelta Interval() { | 15 base::TimeDelta Interval() { |
16 return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond / | 16 return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond / |
17 60); | 17 60); |
18 } | 18 } |
19 | 19 |
20 TEST(DelayBasedTimeSourceTest, TaskPostedAndTickCalled) { | 20 TEST(DelayBasedTimeSourceTest, TaskPostedAndTickCalled) { |
21 FakeThread thread; | 21 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
22 FakeTimeSourceClient client; | 22 new base::TestSimpleTaskRunner; |
23 scoped_refptr<FakeDelayBasedTimeSource> timer = | 23 FakeTimeSourceClient client; |
24 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 24 scoped_refptr<FakeDelayBasedTimeSource> timer = |
| 25 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
25 timer->SetClient(&client); | 26 timer->SetClient(&client); |
26 | 27 |
27 timer->SetActive(true); | 28 timer->SetActive(true); |
28 EXPECT_TRUE(timer->Active()); | 29 EXPECT_TRUE(timer->Active()); |
29 EXPECT_TRUE(thread.HasPendingTask()); | 30 EXPECT_TRUE(task_runner->HasPendingTask()); |
30 | 31 |
31 timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(16)); | 32 timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(16)); |
32 thread.RunPendingTask(); | 33 task_runner->RunPendingTasks(); |
33 EXPECT_TRUE(timer->Active()); | 34 EXPECT_TRUE(timer->Active()); |
34 EXPECT_TRUE(client.TickCalled()); | 35 EXPECT_TRUE(client.TickCalled()); |
35 } | 36 } |
36 | 37 |
37 TEST(DelayBasedTimeSource, TickNotCalledWithTaskPosted) { | 38 TEST(DelayBasedTimeSource, TickNotCalledWithTaskPosted) { |
38 FakeThread thread; | 39 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
39 FakeTimeSourceClient client; | 40 new base::TestSimpleTaskRunner; |
40 scoped_refptr<FakeDelayBasedTimeSource> timer = | 41 FakeTimeSourceClient client; |
41 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 42 scoped_refptr<FakeDelayBasedTimeSource> timer = |
42 timer->SetClient(&client); | 43 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
43 timer->SetActive(true); | 44 timer->SetClient(&client); |
44 EXPECT_TRUE(thread.HasPendingTask()); | 45 timer->SetActive(true); |
| 46 EXPECT_TRUE(task_runner->HasPendingTask()); |
45 timer->SetActive(false); | 47 timer->SetActive(false); |
46 thread.RunPendingTask(); | 48 task_runner->RunPendingTasks(); |
47 EXPECT_FALSE(client.TickCalled()); | 49 EXPECT_FALSE(client.TickCalled()); |
48 } | 50 } |
49 | 51 |
50 TEST(DelayBasedTimeSource, StartTwiceEnqueuesOneTask) { | 52 TEST(DelayBasedTimeSource, StartTwiceEnqueuesOneTask) { |
51 FakeThread thread; | 53 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
52 FakeTimeSourceClient client; | 54 new base::TestSimpleTaskRunner; |
53 scoped_refptr<FakeDelayBasedTimeSource> timer = | 55 FakeTimeSourceClient client; |
54 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 56 scoped_refptr<FakeDelayBasedTimeSource> timer = |
55 timer->SetClient(&client); | 57 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
56 timer->SetActive(true); | 58 timer->SetClient(&client); |
57 EXPECT_TRUE(thread.HasPendingTask()); | 59 timer->SetActive(true); |
58 thread.Reset(); | 60 EXPECT_TRUE(task_runner->HasPendingTask()); |
59 timer->SetActive(true); | 61 task_runner->ClearPendingTasks(); |
60 EXPECT_FALSE(thread.HasPendingTask()); | 62 timer->SetActive(true); |
| 63 EXPECT_FALSE(task_runner->HasPendingTask()); |
61 } | 64 } |
62 | 65 |
63 TEST(DelayBasedTimeSource, StartWhenRunningDoesntTick) { | 66 TEST(DelayBasedTimeSource, StartWhenRunningDoesntTick) { |
64 FakeThread thread; | 67 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
65 FakeTimeSourceClient client; | 68 new base::TestSimpleTaskRunner; |
66 scoped_refptr<FakeDelayBasedTimeSource> timer = | 69 FakeTimeSourceClient client; |
67 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 70 scoped_refptr<FakeDelayBasedTimeSource> timer = |
68 timer->SetClient(&client); | 71 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
69 timer->SetActive(true); | 72 timer->SetClient(&client); |
70 thread.RunPendingTask(); | 73 timer->SetActive(true); |
71 thread.Reset(); | 74 EXPECT_TRUE(task_runner->HasPendingTask()); |
72 timer->SetActive(true); | 75 task_runner->RunPendingTasks(); |
73 EXPECT_FALSE(thread.HasPendingTask()); | 76 task_runner->ClearPendingTasks(); |
| 77 timer->SetActive(true); |
| 78 EXPECT_FALSE(task_runner->HasPendingTask()); |
74 } | 79 } |
75 | 80 |
76 // At 60Hz, when the tick returns at exactly the requested next time, make sure | 81 // At 60Hz, when the tick returns at exactly the requested next time, make sure |
77 // a 16ms next delay is posted. | 82 // a 16ms next delay is posted. |
78 TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyOnRequestedTime) { | 83 TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyOnRequestedTime) { |
79 FakeThread thread; | 84 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
80 FakeTimeSourceClient client; | 85 new base::TestSimpleTaskRunner; |
81 scoped_refptr<FakeDelayBasedTimeSource> timer = | 86 FakeTimeSourceClient client; |
82 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 87 scoped_refptr<FakeDelayBasedTimeSource> timer = |
83 timer->SetClient(&client); | 88 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
84 timer->SetActive(true); | 89 timer->SetClient(&client); |
85 // Run the first task, as that activates the timer and picks up a timebase. | 90 timer->SetActive(true); |
86 thread.RunPendingTask(); | 91 // Run the first task, as that activates the timer and picks up a timebase. |
87 | 92 task_runner->RunPendingTasks(); |
88 EXPECT_EQ(16, thread.PendingDelayMs()); | 93 |
89 | 94 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
90 timer->SetNow(timer->Now() + Interval()); | 95 |
91 thread.RunPendingTask(); | 96 timer->SetNow(timer->Now() + Interval()); |
92 | 97 task_runner->RunPendingTasks(); |
93 EXPECT_EQ(16, thread.PendingDelayMs()); | 98 |
| 99 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
94 } | 100 } |
95 | 101 |
96 // At 60Hz, when the tick returns at slightly after the requested next time, | 102 // At 60Hz, when the tick returns at slightly after the requested next time, |
97 // make sure a 16ms next delay is posted. | 103 // make sure a 16ms next delay is posted. |
98 TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterRequestedTime) { | 104 TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterRequestedTime) { |
99 FakeThread thread; | 105 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
100 FakeTimeSourceClient client; | 106 new base::TestSimpleTaskRunner; |
101 scoped_refptr<FakeDelayBasedTimeSource> timer = | 107 FakeTimeSourceClient client; |
102 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 108 scoped_refptr<FakeDelayBasedTimeSource> timer = |
103 timer->SetClient(&client); | 109 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
104 timer->SetActive(true); | 110 timer->SetClient(&client); |
105 // Run the first task, as that activates the timer and picks up a timebase. | 111 timer->SetActive(true); |
106 thread.RunPendingTask(); | 112 // Run the first task, as that activates the timer and picks up a timebase. |
107 | 113 task_runner->RunPendingTasks(); |
108 EXPECT_EQ(16, thread.PendingDelayMs()); | 114 |
| 115 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
109 | 116 |
110 timer->SetNow(timer->Now() + Interval() + | 117 timer->SetNow(timer->Now() + Interval() + |
111 base::TimeDelta::FromMicroseconds(1)); | 118 base::TimeDelta::FromMicroseconds(1)); |
112 thread.RunPendingTask(); | 119 task_runner->RunPendingTasks(); |
113 | 120 |
114 EXPECT_EQ(16, thread.PendingDelayMs()); | 121 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
115 } | 122 } |
116 | 123 |
117 // At 60Hz, when the tick returns at exactly 2*interval after the requested next | 124 // At 60Hz, when the tick returns at exactly 2*interval after the requested next |
118 // time, make sure a 16ms next delay is posted. | 125 // time, make sure a 16ms next delay is posted. |
119 TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyTwiceAfterRequestedTime) { | 126 TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyTwiceAfterRequestedTime) { |
120 FakeThread thread; | 127 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
121 FakeTimeSourceClient client; | 128 new base::TestSimpleTaskRunner; |
122 scoped_refptr<FakeDelayBasedTimeSource> timer = | 129 FakeTimeSourceClient client; |
123 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 130 scoped_refptr<FakeDelayBasedTimeSource> timer = |
124 timer->SetClient(&client); | 131 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
125 timer->SetActive(true); | 132 timer->SetClient(&client); |
126 // Run the first task, as that activates the timer and picks up a timebase. | 133 timer->SetActive(true); |
127 thread.RunPendingTask(); | 134 // Run the first task, as that activates the timer and picks up a timebase. |
128 | 135 task_runner->RunPendingTasks(); |
129 EXPECT_EQ(16, thread.PendingDelayMs()); | 136 |
| 137 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
130 | 138 |
131 timer->SetNow(timer->Now() + 2 * Interval()); | 139 timer->SetNow(timer->Now() + 2 * Interval()); |
132 thread.RunPendingTask(); | 140 task_runner->RunPendingTasks(); |
133 | 141 |
134 EXPECT_EQ(16, thread.PendingDelayMs()); | 142 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
135 } | 143 } |
136 | 144 |
137 // At 60Hz, when the tick returns at 2*interval and a bit after the requested | 145 // At 60Hz, when the tick returns at 2*interval and a bit after the requested |
138 // next time, make sure a 16ms next delay is posted. | 146 // next time, make sure a 16ms next delay is posted. |
139 TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterTwiceRequestedTime) { | 147 TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterTwiceRequestedTime) { |
140 FakeThread thread; | 148 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
141 FakeTimeSourceClient client; | 149 new base::TestSimpleTaskRunner; |
142 scoped_refptr<FakeDelayBasedTimeSource> timer = | 150 FakeTimeSourceClient client; |
143 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 151 scoped_refptr<FakeDelayBasedTimeSource> timer = |
144 timer->SetClient(&client); | 152 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
145 timer->SetActive(true); | 153 timer->SetClient(&client); |
146 // Run the first task, as that activates the timer and picks up a timebase. | 154 timer->SetActive(true); |
147 thread.RunPendingTask(); | 155 // Run the first task, as that activates the timer and picks up a timebase. |
148 | 156 task_runner->RunPendingTasks(); |
149 EXPECT_EQ(16, thread.PendingDelayMs()); | 157 |
| 158 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
150 | 159 |
151 timer->SetNow(timer->Now() + 2 * Interval() + | 160 timer->SetNow(timer->Now() + 2 * Interval() + |
152 base::TimeDelta::FromMicroseconds(1)); | 161 base::TimeDelta::FromMicroseconds(1)); |
153 thread.RunPendingTask(); | 162 task_runner->RunPendingTasks(); |
154 | 163 |
155 EXPECT_EQ(16, thread.PendingDelayMs()); | 164 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
156 } | 165 } |
157 | 166 |
158 // At 60Hz, when the tick returns halfway to the next frame time, make sure | 167 // At 60Hz, when the tick returns halfway to the next frame time, make sure |
159 // a correct next delay value is posted. | 168 // a correct next delay value is posted. |
160 TEST(DelayBasedTimeSource, NextDelaySaneWhenHalfAfterRequestedTime) { | 169 TEST(DelayBasedTimeSource, NextDelaySaneWhenHalfAfterRequestedTime) { |
161 FakeThread thread; | 170 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
162 FakeTimeSourceClient client; | 171 new base::TestSimpleTaskRunner; |
163 scoped_refptr<FakeDelayBasedTimeSource> timer = | 172 FakeTimeSourceClient client; |
164 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 173 scoped_refptr<FakeDelayBasedTimeSource> timer = |
165 timer->SetClient(&client); | 174 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
166 timer->SetActive(true); | 175 timer->SetClient(&client); |
167 // Run the first task, as that activates the timer and picks up a timebase. | 176 timer->SetActive(true); |
168 thread.RunPendingTask(); | 177 // Run the first task, as that activates the timer and picks up a timebase. |
169 | 178 task_runner->RunPendingTasks(); |
170 EXPECT_EQ(16, thread.PendingDelayMs()); | 179 |
| 180 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
171 | 181 |
172 timer->SetNow(timer->Now() + Interval() + | 182 timer->SetNow(timer->Now() + Interval() + |
173 base::TimeDelta::FromMilliseconds(8)); | 183 base::TimeDelta::FromMilliseconds(8)); |
174 thread.RunPendingTask(); | 184 task_runner->RunPendingTasks(); |
175 | 185 |
176 EXPECT_EQ(8, thread.PendingDelayMs()); | 186 EXPECT_EQ(8, task_runner->NextPendingTaskDelay().InMilliseconds()); |
177 } | 187 } |
178 | 188 |
179 // If the timebase and interval are updated with a jittery source, we want to | 189 // If the timebase and interval are updated with a jittery source, we want to |
180 // make sure we do not double tick. | 190 // make sure we do not double tick. |
181 TEST(DelayBasedTimeSource, SaneHandlingOfJitteryTimebase) { | 191 TEST(DelayBasedTimeSource, SaneHandlingOfJitteryTimebase) { |
182 FakeThread thread; | 192 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
183 FakeTimeSourceClient client; | 193 new base::TestSimpleTaskRunner; |
184 scoped_refptr<FakeDelayBasedTimeSource> timer = | 194 FakeTimeSourceClient client; |
185 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 195 scoped_refptr<FakeDelayBasedTimeSource> timer = |
186 timer->SetClient(&client); | 196 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
187 timer->SetActive(true); | 197 timer->SetClient(&client); |
188 // Run the first task, as that activates the timer and picks up a timebase. | 198 timer->SetActive(true); |
189 thread.RunPendingTask(); | 199 // Run the first task, as that activates the timer and picks up a timebase. |
190 | 200 task_runner->RunPendingTasks(); |
191 EXPECT_EQ(16, thread.PendingDelayMs()); | 201 |
| 202 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
192 | 203 |
193 // Jitter timebase ~1ms late | 204 // Jitter timebase ~1ms late |
194 timer->SetNow(timer->Now() + Interval()); | 205 timer->SetNow(timer->Now() + Interval()); |
195 timer->SetTimebaseAndInterval( | 206 timer->SetTimebaseAndInterval( |
196 timer->Now() + base::TimeDelta::FromMilliseconds(1), Interval()); | 207 timer->Now() + base::TimeDelta::FromMilliseconds(1), Interval()); |
197 thread.RunPendingTask(); | 208 task_runner->RunPendingTasks(); |
198 | 209 |
199 // Without double tick prevention, PendingDelayMs would be 1. | 210 // Without double tick prevention, NextPendingTaskDelay would be 1. |
200 EXPECT_EQ(17, thread.PendingDelayMs()); | 211 EXPECT_EQ(17, task_runner->NextPendingTaskDelay().InMilliseconds()); |
201 | 212 |
202 // Jitter timebase ~1ms early | 213 // Jitter timebase ~1ms early |
203 timer->SetNow(timer->Now() + Interval()); | 214 timer->SetNow(timer->Now() + Interval()); |
204 timer->SetTimebaseAndInterval( | 215 timer->SetTimebaseAndInterval( |
205 timer->Now() - base::TimeDelta::FromMilliseconds(1), Interval()); | 216 timer->Now() - base::TimeDelta::FromMilliseconds(1), Interval()); |
206 thread.RunPendingTask(); | 217 task_runner->RunPendingTasks(); |
207 | 218 |
208 EXPECT_EQ(15, thread.PendingDelayMs()); | 219 EXPECT_EQ(15, task_runner->NextPendingTaskDelay().InMilliseconds()); |
209 } | 220 } |
210 | 221 |
211 TEST(DelayBasedTimeSource, HandlesSignificantTimebaseChangesImmediately) { | 222 TEST(DelayBasedTimeSource, HandlesSignificantTimebaseChangesImmediately) { |
212 FakeThread thread; | 223 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
213 FakeTimeSourceClient client; | 224 new base::TestSimpleTaskRunner; |
214 scoped_refptr<FakeDelayBasedTimeSource> timer = | 225 FakeTimeSourceClient client; |
215 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 226 scoped_refptr<FakeDelayBasedTimeSource> timer = |
216 timer->SetClient(&client); | 227 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
217 timer->SetActive(true); | 228 timer->SetClient(&client); |
218 // Run the first task, as that activates the timer and picks up a timebase. | 229 timer->SetActive(true); |
219 thread.RunPendingTask(); | 230 // Run the first task, as that activates the timer and picks up a timebase. |
220 | 231 task_runner->RunPendingTasks(); |
221 EXPECT_EQ(16, thread.PendingDelayMs()); | 232 |
| 233 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
222 | 234 |
223 // Tick, then shift timebase by +7ms. | 235 // Tick, then shift timebase by +7ms. |
224 timer->SetNow(timer->Now() + Interval()); | 236 timer->SetNow(timer->Now() + Interval()); |
225 thread.RunPendingTask(); | 237 task_runner->RunPendingTasks(); |
226 | 238 |
227 EXPECT_EQ(16, thread.PendingDelayMs()); | 239 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
228 | 240 |
229 client.Reset(); | 241 client.Reset(); |
230 thread.RunPendingTaskOnOverwrite(true); | 242 task_runner->ClearPendingTasks(); |
| 243 task_runner->RunPendingTasks(); |
231 base::TimeDelta jitter = base::TimeDelta::FromMilliseconds(7) + | 244 base::TimeDelta jitter = base::TimeDelta::FromMilliseconds(7) + |
232 base::TimeDelta::FromMicroseconds(1); | 245 base::TimeDelta::FromMicroseconds(1); |
233 timer->SetTimebaseAndInterval(timer->Now() + jitter, Interval()); | 246 timer->SetTimebaseAndInterval(timer->Now() + jitter, Interval()); |
234 thread.RunPendingTaskOnOverwrite(false); | |
235 | 247 |
236 EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled. | 248 EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled. |
237 EXPECT_EQ(7, thread.PendingDelayMs()); | 249 EXPECT_EQ(7, task_runner->NextPendingTaskDelay().InMilliseconds()); |
238 | 250 |
239 // Tick, then shift timebase by -7ms. | 251 // Tick, then shift timebase by -7ms. |
240 timer->SetNow(timer->Now() + jitter); | 252 timer->SetNow(timer->Now() + jitter); |
241 thread.RunPendingTask(); | 253 task_runner->RunPendingTasks(); |
242 | 254 |
243 EXPECT_EQ(16, thread.PendingDelayMs()); | 255 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
244 | 256 |
245 client.Reset(); | 257 client.Reset(); |
246 thread.RunPendingTaskOnOverwrite(true); | 258 task_runner->ClearPendingTasks(); |
| 259 task_runner->RunPendingTasks(); |
247 timer->SetTimebaseAndInterval(base::TimeTicks() + Interval(), Interval()); | 260 timer->SetTimebaseAndInterval(base::TimeTicks() + Interval(), Interval()); |
248 thread.RunPendingTaskOnOverwrite(false); | |
249 | 261 |
250 EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled. | 262 EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled. |
251 EXPECT_EQ(16 - 7, thread.PendingDelayMs()); | 263 EXPECT_EQ(16 - 7, task_runner->NextPendingTaskDelay().InMilliseconds()); |
252 } | 264 } |
253 | 265 |
254 TEST(DelayBasedTimeSource, HanldlesSignificantIntervalChangesImmediately) { | 266 TEST(DelayBasedTimeSource, HanldlesSignificantIntervalChangesImmediately) { |
255 FakeThread thread; | 267 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
256 FakeTimeSourceClient client; | 268 new base::TestSimpleTaskRunner; |
257 scoped_refptr<FakeDelayBasedTimeSource> timer = | 269 FakeTimeSourceClient client; |
258 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 270 scoped_refptr<FakeDelayBasedTimeSource> timer = |
259 timer->SetClient(&client); | 271 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
260 timer->SetActive(true); | 272 timer->SetClient(&client); |
261 // Run the first task, as that activates the timer and picks up a timebase. | 273 timer->SetActive(true); |
262 thread.RunPendingTask(); | 274 // Run the first task, as that activates the timer and picks up a timebase. |
263 | 275 task_runner->RunPendingTasks(); |
264 EXPECT_EQ(16, thread.PendingDelayMs()); | 276 |
| 277 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
265 | 278 |
266 // Tick, then double the interval. | 279 // Tick, then double the interval. |
267 timer->SetNow(timer->Now() + Interval()); | 280 timer->SetNow(timer->Now() + Interval()); |
268 thread.RunPendingTask(); | 281 task_runner->RunPendingTasks(); |
269 | 282 |
270 EXPECT_EQ(16, thread.PendingDelayMs()); | 283 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
271 | 284 |
272 client.Reset(); | 285 client.Reset(); |
273 thread.RunPendingTaskOnOverwrite(true); | 286 task_runner->ClearPendingTasks(); |
| 287 task_runner->RunPendingTasks(); |
274 timer->SetTimebaseAndInterval(base::TimeTicks() + Interval(), Interval() * 2); | 288 timer->SetTimebaseAndInterval(base::TimeTicks() + Interval(), Interval() * 2); |
275 thread.RunPendingTaskOnOverwrite(false); | |
276 | 289 |
277 EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled. | 290 EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled. |
278 EXPECT_EQ(33, thread.PendingDelayMs()); | 291 EXPECT_EQ(33, task_runner->NextPendingTaskDelay().InMilliseconds()); |
279 | 292 |
280 // Tick, then halve the interval. | 293 // Tick, then halve the interval. |
281 timer->SetNow(timer->Now() + Interval() * 2); | 294 timer->SetNow(timer->Now() + Interval() * 2); |
282 thread.RunPendingTask(); | 295 task_runner->RunPendingTasks(); |
283 | 296 |
284 EXPECT_EQ(33, thread.PendingDelayMs()); | 297 EXPECT_EQ(33, task_runner->NextPendingTaskDelay().InMilliseconds()); |
285 | 298 |
286 client.Reset(); | 299 client.Reset(); |
287 thread.RunPendingTaskOnOverwrite(true); | 300 task_runner->ClearPendingTasks(); |
| 301 task_runner->RunPendingTasks(); |
288 timer->SetTimebaseAndInterval(base::TimeTicks() + Interval() * 3, Interval()); | 302 timer->SetTimebaseAndInterval(base::TimeTicks() + Interval() * 3, Interval()); |
289 thread.RunPendingTaskOnOverwrite(false); | |
290 | 303 |
291 EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled. | 304 EXPECT_FALSE(client.TickCalled()); // Make sure pending tasks were canceled. |
292 EXPECT_EQ(16, thread.PendingDelayMs()); | 305 EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); |
293 } | 306 } |
294 | 307 |
295 TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) { | 308 TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) { |
296 int num_iterations = 10; | 309 int num_iterations = 10; |
297 | 310 |
298 FakeThread thread; | 311 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
299 FakeTimeSourceClient client; | 312 new base::TestSimpleTaskRunner; |
300 scoped_refptr<FakeDelayBasedTimeSource> timer = | 313 FakeTimeSourceClient client; |
301 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 314 scoped_refptr<FakeDelayBasedTimeSource> timer = |
| 315 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
302 timer->SetClient(&client); | 316 timer->SetClient(&client); |
303 timer->SetActive(true); | 317 timer->SetActive(true); |
304 | 318 |
305 double total_frame_time = 0.0; | 319 double total_frame_time = 0.0; |
306 for (int i = 0; i < num_iterations; ++i) { | 320 for (int i = 0; i < num_iterations; ++i) { |
307 int64 delay_ms = thread.PendingDelayMs(); | 321 int64 delay_ms = task_runner->NextPendingTaskDelay().InMilliseconds(); |
308 | 322 |
309 // accumulate the "delay" | 323 // accumulate the "delay" |
310 total_frame_time += delay_ms / 1000.0; | 324 total_frame_time += delay_ms / 1000.0; |
311 | 325 |
312 // Run the callback exactly when asked | 326 // Run the callback exactly when asked |
313 timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(delay_ms)); | 327 timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(delay_ms)); |
314 thread.RunPendingTask(); | 328 task_runner->RunPendingTasks(); |
315 } | 329 } |
316 double average_interval = | 330 double average_interval = |
317 total_frame_time / static_cast<double>(num_iterations); | 331 total_frame_time / static_cast<double>(num_iterations); |
318 EXPECT_NEAR(1.0 / 60.0, average_interval, 0.1); | 332 EXPECT_NEAR(1.0 / 60.0, average_interval, 0.1); |
319 } | 333 } |
320 | 334 |
321 TEST(DelayBasedTimeSource, TestDeactivateWhilePending) { | 335 TEST(DelayBasedTimeSource, TestDeactivateWhilePending) { |
322 FakeThread thread; | 336 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
| 337 new base::TestSimpleTaskRunner; |
323 FakeTimeSourceClient client; | 338 FakeTimeSourceClient client; |
324 scoped_refptr<FakeDelayBasedTimeSource> timer = | 339 scoped_refptr<FakeDelayBasedTimeSource> timer = |
325 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 340 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
326 timer->SetClient(&client); | 341 timer->SetClient(&client); |
327 timer->SetActive(true); // Should post a task. | 342 timer->SetActive(true); // Should post a task. |
328 timer->SetActive(false); | 343 timer->SetActive(false); |
329 timer = NULL; | 344 timer = NULL; |
330 thread.RunPendingTask(); // Should run the posted task without crashing. | 345 // Should run the posted task without crashing. |
| 346 EXPECT_TRUE(task_runner->HasPendingTask()); |
| 347 task_runner->RunPendingTasks(); |
331 } | 348 } |
332 | 349 |
333 TEST(DelayBasedTimeSource, TestDeactivateAndReactivateBeforeNextTickTime) { | 350 TEST(DelayBasedTimeSource, TestDeactivateAndReactivateBeforeNextTickTime) { |
334 FakeThread thread; | 351 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
| 352 new base::TestSimpleTaskRunner; |
335 FakeTimeSourceClient client; | 353 FakeTimeSourceClient client; |
336 scoped_refptr<FakeDelayBasedTimeSource> timer = | 354 scoped_refptr<FakeDelayBasedTimeSource> timer = |
337 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 355 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
338 timer->SetClient(&client); | 356 timer->SetClient(&client); |
339 | 357 |
340 // Should run the activate task, and pick up a new timebase. | 358 // Should run the activate task, and pick up a new timebase. |
341 timer->SetActive(true); | 359 timer->SetActive(true); |
342 thread.RunPendingTask(); | 360 task_runner->RunPendingTasks(); |
343 | 361 |
344 // Stop the timer | 362 // Stop the timer |
345 timer->SetActive(false); | 363 timer->SetActive(false); |
346 | 364 |
347 // Task will be pending anyway, run it | 365 // Task will be pending anyway, run it |
348 thread.RunPendingTask(); | 366 task_runner->RunPendingTasks(); |
349 | 367 |
350 // Start the timer again, but before the next tick time the timer previously | 368 // Start the timer again, but before the next tick time the timer previously |
351 // planned on using. That same tick time should still be targeted. | 369 // planned on using. That same tick time should still be targeted. |
352 timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(4)); | 370 timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(4)); |
353 timer->SetActive(true); | 371 timer->SetActive(true); |
354 EXPECT_EQ(12, thread.PendingDelayMs()); | 372 EXPECT_EQ(12, task_runner->NextPendingTaskDelay().InMilliseconds()); |
355 } | 373 } |
356 | 374 |
357 TEST(DelayBasedTimeSource, TestDeactivateAndReactivateAfterNextTickTime) { | 375 TEST(DelayBasedTimeSource, TestDeactivateAndReactivateAfterNextTickTime) { |
358 FakeThread thread; | 376 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
| 377 new base::TestSimpleTaskRunner; |
359 FakeTimeSourceClient client; | 378 FakeTimeSourceClient client; |
360 scoped_refptr<FakeDelayBasedTimeSource> timer = | 379 scoped_refptr<FakeDelayBasedTimeSource> timer = |
361 FakeDelayBasedTimeSource::Create(Interval(), &thread); | 380 FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); |
362 timer->SetClient(&client); | 381 timer->SetClient(&client); |
363 | 382 |
364 // Should run the activate task, and pick up a new timebase. | 383 // Should run the activate task, and pick up a new timebase. |
365 timer->SetActive(true); | 384 timer->SetActive(true); |
366 thread.RunPendingTask(); | 385 task_runner->RunPendingTasks(); |
367 | 386 |
368 // Stop the timer. | 387 // Stop the timer. |
369 timer->SetActive(false); | 388 timer->SetActive(false); |
370 | 389 |
371 // Task will be pending anyway, run it. | 390 // Task will be pending anyway, run it. |
372 thread.RunPendingTask(); | 391 task_runner->RunPendingTasks(); |
373 | 392 |
374 // Start the timer again, but before the next tick time the timer previously | 393 // Start the timer again, but before the next tick time the timer previously |
375 // planned on using. That same tick time should still be targeted. | 394 // planned on using. That same tick time should still be targeted. |
376 timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(20)); | 395 timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(20)); |
377 timer->SetActive(true); | 396 timer->SetActive(true); |
378 EXPECT_EQ(13, thread.PendingDelayMs()); | 397 EXPECT_EQ(13, task_runner->NextPendingTaskDelay().InMilliseconds()); |
379 } | 398 } |
380 | 399 |
381 } // namespace | 400 } // namespace |
382 } // namespace cc | 401 } // namespace cc |
OLD | NEW |