summaryrefslogtreecommitdiffstats
path: root/cc/delay_based_time_source_unittest.cc
diff options
context:
space:
mode:
authorenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-12 19:40:56 +0000
committerenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-10-12 19:40:56 +0000
commitc79f147c0474a311a83829a44b55aaffa42c6237 (patch)
tree8bb41fcb74068042828da31c279b0d53dd0844fa /cc/delay_based_time_source_unittest.cc
parente62f2909e0aabf37131a65c7e50e85c1f07473f8 (diff)
downloadchromium_src-c79f147c0474a311a83829a44b55aaffa42c6237.zip
chromium_src-c79f147c0474a311a83829a44b55aaffa42c6237.tar.gz
chromium_src-c79f147c0474a311a83829a44b55aaffa42c6237.tar.bz2
[cc] Change cc_tests.gyp filenames to Chromium style
BUG=155413 Review URL: https://codereview.chromium.org/11108020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161642 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/delay_based_time_source_unittest.cc')
-rw-r--r--cc/delay_based_time_source_unittest.cc379
1 files changed, 379 insertions, 0 deletions
diff --git a/cc/delay_based_time_source_unittest.cc b/cc/delay_based_time_source_unittest.cc
new file mode 100644
index 0000000..1819123
--- /dev/null
+++ b/cc/delay_based_time_source_unittest.cc
@@ -0,0 +1,379 @@
+// Copyright 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#include "CCDelayBasedTimeSource.h"
+
+#include "CCSchedulerTestCommon.h"
+#include "CCThread.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include <wtf/RefPtr.h>
+
+using namespace cc;
+using namespace WTF;
+using namespace WebKitTests;
+
+namespace {
+
+base::TimeDelta interval()
+{
+ return base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond / 60);
+}
+
+TEST(CCDelayBasedTimeSourceTest, TaskPostedAndTickCalled)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+
+ timer->setActive(true);
+ EXPECT_TRUE(timer->active());
+ EXPECT_TRUE(thread.hasPendingTask());
+
+ timer->setNow(timer->now() + base::TimeDelta::FromMilliseconds(16));
+ thread.runPendingTask();
+ EXPECT_TRUE(timer->active());
+ EXPECT_TRUE(client.tickCalled());
+}
+
+TEST(CCDelayBasedTimeSource, TickNotCalledWithTaskPosted)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ EXPECT_TRUE(thread.hasPendingTask());
+ timer->setActive(false);
+ thread.runPendingTask();
+ EXPECT_FALSE(client.tickCalled());
+}
+
+TEST(CCDelayBasedTimeSource, StartTwiceEnqueuesOneTask)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ EXPECT_TRUE(thread.hasPendingTask());
+ thread.reset();
+ timer->setActive(true);
+ EXPECT_FALSE(thread.hasPendingTask());
+}
+
+TEST(CCDelayBasedTimeSource, StartWhenRunningDoesntTick)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ thread.runPendingTask();
+ thread.reset();
+ timer->setActive(true);
+ EXPECT_FALSE(thread.hasPendingTask());
+}
+
+// At 60Hz, when the tick returns at exactly the requested next time, make sure
+// a 16ms next delay is posted.
+TEST(CCDelayBasedTimeSource, NextDelaySaneWhenExactlyOnRequestedTime)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ // Run the first task, as that activates the timer and picks up a timebase.
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ timer->setNow(timer->now() + interval());
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+}
+
+// At 60Hz, when the tick returns at slightly after the requested next time, make sure
+// a 16ms next delay is posted.
+TEST(CCDelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterRequestedTime)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ // Run the first task, as that activates the timer and picks up a timebase.
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ timer->setNow(timer->now() + interval() + base::TimeDelta::FromMicroseconds(1));
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+}
+
+// At 60Hz, when the tick returns at exactly 2*interval after the requested next time, make sure
+// a 16ms next delay is posted.
+TEST(CCDelayBasedTimeSource, NextDelaySaneWhenExactlyTwiceAfterRequestedTime)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ // Run the first task, as that activates the timer and picks up a timebase.
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ timer->setNow(timer->now() + 2 * interval());
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+}
+
+// At 60Hz, when the tick returns at 2*interval and a bit after the requested next time, make sure
+// a 16ms next delay is posted.
+TEST(CCDelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterTwiceRequestedTime)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ // Run the first task, as that activates the timer and picks up a timebase.
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ timer->setNow(timer->now() + 2 * interval() + base::TimeDelta::FromMicroseconds(1));
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+}
+
+// At 60Hz, when the tick returns halfway to the next frame time, make sure
+// a correct next delay value is posted.
+TEST(CCDelayBasedTimeSource, NextDelaySaneWhenHalfAfterRequestedTime)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ // Run the first task, as that activates the timer and picks up a timebase.
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ timer->setNow(timer->now() + interval() + base::TimeDelta::FromMilliseconds(8));
+ thread.runPendingTask();
+
+ EXPECT_EQ(8, thread.pendingDelayMs());
+}
+
+// If the timebase and interval are updated with a jittery source, we want to
+// make sure we do not double tick.
+TEST(CCDelayBasedTimeSource, SaneHandlingOfJitteryTimebase)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ // Run the first task, as that activates the timer and picks up a timebase.
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ // Jitter timebase ~1ms late
+ timer->setNow(timer->now() + interval());
+ timer->setTimebaseAndInterval(timer->now() + base::TimeDelta::FromMilliseconds(1), interval());
+ thread.runPendingTask();
+
+ // Without double tick prevention, pendingDelayMs would be 1.
+ EXPECT_EQ(17, thread.pendingDelayMs());
+
+ // Jitter timebase ~1ms early
+ timer->setNow(timer->now() + interval());
+ timer->setTimebaseAndInterval(timer->now() - base::TimeDelta::FromMilliseconds(1), interval());
+ thread.runPendingTask();
+
+ EXPECT_EQ(15, thread.pendingDelayMs());
+}
+
+TEST(CCDelayBasedTimeSource, HandlesSignificantTimebaseChangesImmediately)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ // Run the first task, as that activates the timer and picks up a timebase.
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ // Tick, then shift timebase by +7ms.
+ timer->setNow(timer->now() + interval());
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ client.reset();
+ thread.runPendingTaskOnOverwrite(true);
+ base::TimeDelta jitter = base::TimeDelta::FromMilliseconds(7) + base::TimeDelta::FromMicroseconds(1);
+ timer->setTimebaseAndInterval(timer->now() + jitter, interval());
+ thread.runPendingTaskOnOverwrite(false);
+
+ EXPECT_FALSE(client.tickCalled()); // Make sure pending tasks were canceled.
+ EXPECT_EQ(7, thread.pendingDelayMs());
+
+ // Tick, then shift timebase by -7ms.
+ timer->setNow(timer->now() + jitter);
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ client.reset();
+ thread.runPendingTaskOnOverwrite(true);
+ timer->setTimebaseAndInterval(base::TimeTicks() + interval(), interval());
+ thread.runPendingTaskOnOverwrite(false);
+
+ EXPECT_FALSE(client.tickCalled()); // Make sure pending tasks were canceled.
+ EXPECT_EQ(16-7, thread.pendingDelayMs());
+}
+
+TEST(CCDelayBasedTimeSource, HanldlesSignificantIntervalChangesImmediately)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+ // Run the first task, as that activates the timer and picks up a timebase.
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ // Tick, then double the interval.
+ timer->setNow(timer->now() + interval());
+ thread.runPendingTask();
+
+ EXPECT_EQ(16, thread.pendingDelayMs());
+
+ client.reset();
+ thread.runPendingTaskOnOverwrite(true);
+ timer->setTimebaseAndInterval(base::TimeTicks() + interval(), interval() * 2);
+ thread.runPendingTaskOnOverwrite(false);
+
+ EXPECT_FALSE(client.tickCalled()); // Make sure pending tasks were canceled.
+ EXPECT_EQ(33, thread.pendingDelayMs());
+
+ // Tick, then halve the interval.
+ timer->setNow(timer->now() + interval() * 2);
+ thread.runPendingTask();
+
+ EXPECT_EQ(33, thread.pendingDelayMs());
+
+ client.reset();
+ thread.runPendingTaskOnOverwrite(true);
+ timer->setTimebaseAndInterval(base::TimeTicks() + interval() * 3, interval());
+ thread.runPendingTaskOnOverwrite(false);
+
+ EXPECT_FALSE(client.tickCalled()); // Make sure pending tasks were canceled.
+ EXPECT_EQ(16, thread.pendingDelayMs());
+}
+
+TEST(CCDelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise)
+{
+ int numIterations = 10;
+
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true);
+
+ double totalFrameTime = 0;
+ for (int i = 0; i < numIterations; ++i) {
+ long long delayMs = thread.pendingDelayMs();
+
+ // accumulate the "delay"
+ totalFrameTime += delayMs / 1000.0;
+
+ // Run the callback exactly when asked
+ timer->setNow(timer->now() + base::TimeDelta::FromMilliseconds(delayMs));
+ thread.runPendingTask();
+ }
+ double averageInterval = totalFrameTime / static_cast<double>(numIterations);
+ EXPECT_NEAR(1.0 / 60.0, averageInterval, 0.1);
+}
+
+TEST(CCDelayBasedTimeSource, TestDeactivateWhilePending)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+ timer->setActive(true); // Should post a task.
+ timer->setActive(false);
+ timer.clear();
+ thread.runPendingTask(); // Should run the posted task without crashing.
+}
+
+TEST(CCDelayBasedTimeSource, TestDeactivateAndReactivateBeforeNextTickTime)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+
+ // Should run the activate task, and pick up a new timebase.
+ timer->setActive(true);
+ thread.runPendingTask();
+
+ // Stop the timer
+ timer->setActive(false);
+
+ // Task will be pending anyway, run it
+ thread.runPendingTask();
+
+ // Start the timer again, but before the next tick time the timer previously
+ // planned on using. That same tick time should still be targeted.
+ timer->setNow(timer->now() + base::TimeDelta::FromMilliseconds(4));
+ timer->setActive(true);
+ EXPECT_EQ(12, thread.pendingDelayMs());
+}
+
+TEST(CCDelayBasedTimeSource, TestDeactivateAndReactivateAfterNextTickTime)
+{
+ FakeCCThread thread;
+ FakeCCTimeSourceClient client;
+ RefPtr<FakeCCDelayBasedTimeSource> timer = FakeCCDelayBasedTimeSource::create(interval(), &thread);
+ timer->setClient(&client);
+
+ // Should run the activate task, and pick up a new timebase.
+ timer->setActive(true);
+ thread.runPendingTask();
+
+ // Stop the timer
+ timer->setActive(false);
+
+ // Task will be pending anyway, run it
+ thread.runPendingTask();
+
+ // Start the timer again, but before the next tick time the timer previously
+ // planned on using. That same tick time should still be targeted.
+ timer->setNow(timer->now() + base::TimeDelta::FromMilliseconds(20));
+ timer->setActive(true);
+ EXPECT_EQ(13, thread.pendingDelayMs());
+}
+
+}