| 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 |