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