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

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

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

Powered by Google App Engine
This is Rietveld 408576698