diff options
author | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-12 19:40:56 +0000 |
---|---|---|
committer | enne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-10-12 19:40:56 +0000 |
commit | c79f147c0474a311a83829a44b55aaffa42c6237 (patch) | |
tree | 8bb41fcb74068042828da31c279b0d53dd0844fa /cc/delay_based_time_source_unittest.cc | |
parent | e62f2909e0aabf37131a65c7e50e85c1f07473f8 (diff) | |
download | chromium_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.cc | 379 |
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()); +} + +} |