diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-18 17:39:51 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-18 17:39:51 +0000 |
commit | dfd15d1a2facf6a47473ee9da97993dbfd075b4d (patch) | |
tree | e76aa995dde441e89025d2b7c15c2065a6d2f261 /cc/scheduler | |
parent | bed29f042d424c95bad10263358bd65a36491c20 (diff) | |
download | chromium_src-dfd15d1a2facf6a47473ee9da97993dbfd075b4d.zip chromium_src-dfd15d1a2facf6a47473ee9da97993dbfd075b4d.tar.gz chromium_src-dfd15d1a2facf6a47473ee9da97993dbfd075b4d.tar.bz2 |
cc: Remove FakeThread, use SingleThreadTaskRunner in scheduling classes.
This changes from using cc::Thread to base::SingleThreadTaskRunner in
FrameRateController, DelayBasedTimeSource, and ResourceUpdateController.
Then all unit tests for these classes are switched from using
cc::FakeThread to base::TestSimpleTaskRunner.
This is a step toward deleting cc::Thread and moving to using
MessageLoopProxy directly in cc.
R=piman
BUG=251134
Review URL: https://chromiumcodereview.appspot.com/17362002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@207027 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/scheduler')
-rw-r--r-- | cc/scheduler/delay_based_time_source.cc | 25 | ||||
-rw-r--r-- | cc/scheduler/delay_based_time_source.h | 15 | ||||
-rw-r--r-- | cc/scheduler/delay_based_time_source_unittest.cc | 225 | ||||
-rw-r--r-- | cc/scheduler/frame_rate_controller.cc | 17 | ||||
-rw-r--r-- | cc/scheduler/frame_rate_controller.h | 7 | ||||
-rw-r--r-- | cc/scheduler/frame_rate_controller_unittest.cc | 54 |
6 files changed, 187 insertions, 156 deletions
diff --git a/cc/scheduler/delay_based_time_source.cc b/cc/scheduler/delay_based_time_source.cc index 7966668..5d2f20b 100644 --- a/cc/scheduler/delay_based_time_source.cc +++ b/cc/scheduler/delay_based_time_source.cc @@ -9,8 +9,7 @@ #include "base/debug/trace_event.h" #include "base/logging.h" -#include "base/message_loop.h" -#include "cc/base/thread.h" +#include "base/single_thread_task_runner.h" namespace cc { @@ -34,18 +33,18 @@ static const double kPhaseChangeThreshold = 0.25; scoped_refptr<DelayBasedTimeSource> DelayBasedTimeSource::Create( base::TimeDelta interval, - Thread* thread) { - return make_scoped_refptr(new DelayBasedTimeSource(interval, thread)); + base::SingleThreadTaskRunner* task_runner) { + return make_scoped_refptr(new DelayBasedTimeSource(interval, task_runner)); } -DelayBasedTimeSource::DelayBasedTimeSource(base::TimeDelta interval, - Thread* thread) +DelayBasedTimeSource::DelayBasedTimeSource( + base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner) : client_(NULL), has_tick_target_(false), current_parameters_(interval, base::TimeTicks()), next_parameters_(interval, base::TimeTicks()), state_(STATE_INACTIVE), - thread_(thread), + task_runner_(task_runner), weak_factory_(this) {} DelayBasedTimeSource::~DelayBasedTimeSource() {} @@ -66,8 +65,9 @@ void DelayBasedTimeSource::SetActive(bool active) { // When it runs, we use that to establish the timebase, become truly // active, and fire the first tick. state_ = STATE_STARTING; - thread_->PostTask(base::Bind(&DelayBasedTimeSource::OnTimerFired, - weak_factory_.GetWeakPtr())); + task_runner_->PostTask(FROM_HERE, + base::Bind(&DelayBasedTimeSource::OnTimerFired, + weak_factory_.GetWeakPtr())); return; } @@ -238,9 +238,10 @@ void DelayBasedTimeSource::PostNextTickTask(base::TimeTicks now) { DCHECK(delay.InMillisecondsF() <= next_parameters_.interval.InMillisecondsF() * (1.0 + kDoubleTickThreshold)); - thread_->PostDelayedTask(base::Bind(&DelayBasedTimeSource::OnTimerFired, - weak_factory_.GetWeakPtr()), - delay); + task_runner_->PostDelayedTask(FROM_HERE, + base::Bind(&DelayBasedTimeSource::OnTimerFired, + weak_factory_.GetWeakPtr()), + delay); next_parameters_.tick_target = new_tick_target; current_parameters_ = next_parameters_; diff --git a/cc/scheduler/delay_based_time_source.h b/cc/scheduler/delay_based_time_source.h index 06a4ee7..1dc4d6f 100644 --- a/cc/scheduler/delay_based_time_source.h +++ b/cc/scheduler/delay_based_time_source.h @@ -9,17 +9,17 @@ #include "cc/base/cc_export.h" #include "cc/scheduler/time_source.h" -namespace cc { +namespace base { class SingleThreadTaskRunner; } -class Thread; +namespace cc { // This timer implements a time source that achieves the specified interval // in face of millisecond-precision delayed callbacks and random queueing // delays. class CC_EXPORT DelayBasedTimeSource : public TimeSource { public: - static scoped_refptr<DelayBasedTimeSource> Create(base::TimeDelta interval, - Thread* thread); + static scoped_refptr<DelayBasedTimeSource> Create( + base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner); virtual void SetClient(TimeSourceClient* client) OVERRIDE; @@ -39,7 +39,8 @@ class CC_EXPORT DelayBasedTimeSource : public TimeSource { virtual base::TimeTicks Now() const; protected: - DelayBasedTimeSource(base::TimeDelta interval, Thread* thread); + DelayBasedTimeSource(base::TimeDelta interval, + base::SingleThreadTaskRunner* task_runner); virtual ~DelayBasedTimeSource(); base::TimeTicks NextTickTarget(base::TimeTicks now); @@ -72,8 +73,10 @@ class CC_EXPORT DelayBasedTimeSource : public TimeSource { State state_; - Thread* thread_; + base::SingleThreadTaskRunner* task_runner_; base::WeakPtrFactory<DelayBasedTimeSource> weak_factory_; + + private: DISALLOW_COPY_AND_ASSIGN(DelayBasedTimeSource); }; diff --git a/cc/scheduler/delay_based_time_source_unittest.cc b/cc/scheduler/delay_based_time_source_unittest.cc index c368195..df84c97 100644 --- a/cc/scheduler/delay_based_time_source_unittest.cc +++ b/cc/scheduler/delay_based_time_source_unittest.cc @@ -5,7 +5,7 @@ #include "cc/scheduler/delay_based_time_source.h" #include "base/basictypes.h" -#include "cc/base/thread.h" +#include "base/test/test_simple_task_runner.h" #include "cc/test/scheduler_test_common.h" #include "testing/gtest/include/gtest/gtest.h" @@ -18,300 +18,314 @@ base::TimeDelta Interval() { } TEST(DelayBasedTimeSourceTest, TaskPostedAndTickCalled) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); EXPECT_TRUE(timer->Active()); - EXPECT_TRUE(thread.HasPendingTask()); + EXPECT_TRUE(task_runner->HasPendingTask()); timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(16)); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(timer->Active()); EXPECT_TRUE(client.TickCalled()); } TEST(DelayBasedTimeSource, TickNotCalledWithTaskPosted) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - EXPECT_TRUE(thread.HasPendingTask()); + EXPECT_TRUE(task_runner->HasPendingTask()); timer->SetActive(false); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_FALSE(client.TickCalled()); } TEST(DelayBasedTimeSource, StartTwiceEnqueuesOneTask) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - EXPECT_TRUE(thread.HasPendingTask()); - thread.Reset(); + EXPECT_TRUE(task_runner->HasPendingTask()); + task_runner->ClearPendingTasks(); timer->SetActive(true); - EXPECT_FALSE(thread.HasPendingTask()); + EXPECT_FALSE(task_runner->HasPendingTask()); } TEST(DelayBasedTimeSource, StartWhenRunningDoesntTick) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); - thread.RunPendingTask(); - thread.Reset(); + EXPECT_TRUE(task_runner->HasPendingTask()); + task_runner->RunPendingTasks(); + task_runner->ClearPendingTasks(); timer->SetActive(true); - EXPECT_FALSE(thread.HasPendingTask()); + EXPECT_FALSE(task_runner->HasPendingTask()); } // At 60Hz, when the tick returns at exactly the requested next time, make sure // a 16ms next delay is posted. TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyOnRequestedTime) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Run the first task, as that activates the timer and picks up a timebase. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); timer->SetNow(timer->Now() + Interval()); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); } // At 60Hz, when the tick returns at slightly after the requested next time, // make sure a 16ms next delay is posted. TEST(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterRequestedTime) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Run the first task, as that activates the timer and picks up a timebase. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); timer->SetNow(timer->Now() + Interval() + base::TimeDelta::FromMicroseconds(1)); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); } // At 60Hz, when the tick returns at exactly 2*interval after the requested next // time, make sure a 16ms next delay is posted. TEST(DelayBasedTimeSource, NextDelaySaneWhenExactlyTwiceAfterRequestedTime) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Run the first task, as that activates the timer and picks up a timebase. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); timer->SetNow(timer->Now() + 2 * Interval()); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); } // 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(DelayBasedTimeSource, NextDelaySaneWhenSlightlyAfterTwiceRequestedTime) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Run the first task, as that activates the timer and picks up a timebase. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); timer->SetNow(timer->Now() + 2 * Interval() + base::TimeDelta::FromMicroseconds(1)); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); } // At 60Hz, when the tick returns halfway to the next frame time, make sure // a correct next delay value is posted. TEST(DelayBasedTimeSource, NextDelaySaneWhenHalfAfterRequestedTime) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Run the first task, as that activates the timer and picks up a timebase. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); timer->SetNow(timer->Now() + Interval() + base::TimeDelta::FromMilliseconds(8)); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(8, thread.PendingDelayMs()); + EXPECT_EQ(8, task_runner->NextPendingTaskDelay().InMilliseconds()); } // If the timebase and interval are updated with a jittery source, we want to // make sure we do not double tick. TEST(DelayBasedTimeSource, SaneHandlingOfJitteryTimebase) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Run the first task, as that activates the timer and picks up a timebase. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); // Jitter timebase ~1ms late timer->SetNow(timer->Now() + Interval()); timer->SetTimebaseAndInterval( timer->Now() + base::TimeDelta::FromMilliseconds(1), Interval()); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - // Without double tick prevention, PendingDelayMs would be 1. - EXPECT_EQ(17, thread.PendingDelayMs()); + // Without double tick prevention, NextPendingTaskDelay would be 1. + EXPECT_EQ(17, task_runner->NextPendingTaskDelay().InMilliseconds()); // Jitter timebase ~1ms early timer->SetNow(timer->Now() + Interval()); timer->SetTimebaseAndInterval( timer->Now() - base::TimeDelta::FromMilliseconds(1), Interval()); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(15, thread.PendingDelayMs()); + EXPECT_EQ(15, task_runner->NextPendingTaskDelay().InMilliseconds()); } TEST(DelayBasedTimeSource, HandlesSignificantTimebaseChangesImmediately) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Run the first task, as that activates the timer and picks up a timebase. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); // Tick, then shift timebase by +7ms. timer->SetNow(timer->Now() + Interval()); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); client.Reset(); - thread.RunPendingTaskOnOverwrite(true); + task_runner->ClearPendingTasks(); + task_runner->RunPendingTasks(); 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()); + EXPECT_EQ(7, task_runner->NextPendingTaskDelay().InMilliseconds()); // Tick, then shift timebase by -7ms. timer->SetNow(timer->Now() + jitter); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); client.Reset(); - thread.RunPendingTaskOnOverwrite(true); + task_runner->ClearPendingTasks(); + task_runner->RunPendingTasks(); 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()); + EXPECT_EQ(16 - 7, task_runner->NextPendingTaskDelay().InMilliseconds()); } TEST(DelayBasedTimeSource, HanldlesSignificantIntervalChangesImmediately) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Run the first task, as that activates the timer and picks up a timebase. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); // Tick, then double the interval. timer->SetNow(timer->Now() + Interval()); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(16, thread.PendingDelayMs()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); client.Reset(); - thread.RunPendingTaskOnOverwrite(true); + task_runner->ClearPendingTasks(); + task_runner->RunPendingTasks(); 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()); + EXPECT_EQ(33, task_runner->NextPendingTaskDelay().InMilliseconds()); // Tick, then halve the interval. timer->SetNow(timer->Now() + Interval() * 2); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); - EXPECT_EQ(33, thread.PendingDelayMs()); + EXPECT_EQ(33, task_runner->NextPendingTaskDelay().InMilliseconds()); client.Reset(); - thread.RunPendingTaskOnOverwrite(true); + task_runner->ClearPendingTasks(); + task_runner->RunPendingTasks(); 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()); + EXPECT_EQ(16, task_runner->NextPendingTaskDelay().InMilliseconds()); } TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) { int num_iterations = 10; - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); double total_frame_time = 0.0; for (int i = 0; i < num_iterations; ++i) { - int64 delay_ms = thread.PendingDelayMs(); + int64 delay_ms = task_runner->NextPendingTaskDelay().InMilliseconds(); // accumulate the "delay" total_frame_time += delay_ms / 1000.0; // Run the callback exactly when asked timer->SetNow(timer->Now() + base::TimeDelta::FromMilliseconds(delay_ms)); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); } double average_interval = total_frame_time / static_cast<double>(num_iterations); @@ -319,63 +333,68 @@ TEST(DelayBasedTimeSourceTest, AchievesTargetRateWithNoNoise) { } TEST(DelayBasedTimeSource, TestDeactivateWhilePending) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); timer->SetActive(true); // Should post a task. timer->SetActive(false); timer = NULL; - thread.RunPendingTask(); // Should run the posted task without crashing. + // Should run the posted task without crashing. + EXPECT_TRUE(task_runner->HasPendingTask()); + task_runner->RunPendingTasks(); } TEST(DelayBasedTimeSource, TestDeactivateAndReactivateBeforeNextTickTime) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); // Should run the activate task, and pick up a new timebase. timer->SetActive(true); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); // Stop the timer timer->SetActive(false); // Task will be pending anyway, run it - thread.RunPendingTask(); + task_runner->RunPendingTasks(); // 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()); + EXPECT_EQ(12, task_runner->NextPendingTaskDelay().InMilliseconds()); } TEST(DelayBasedTimeSource, TestDeactivateAndReactivateAfterNextTickTime) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeTimeSourceClient client; scoped_refptr<FakeDelayBasedTimeSource> timer = - FakeDelayBasedTimeSource::Create(Interval(), &thread); + FakeDelayBasedTimeSource::Create(Interval(), task_runner.get()); timer->SetClient(&client); // Should run the activate task, and pick up a new timebase. timer->SetActive(true); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); // Stop the timer. timer->SetActive(false); // Task will be pending anyway, run it. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); // 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()); + EXPECT_EQ(13, task_runner->NextPendingTaskDelay().InMilliseconds()); } } // namespace diff --git a/cc/scheduler/frame_rate_controller.cc b/cc/scheduler/frame_rate_controller.cc index 90cf0d7..1977294 100644 --- a/cc/scheduler/frame_rate_controller.cc +++ b/cc/scheduler/frame_rate_controller.cc @@ -5,8 +5,9 @@ #include "cc/scheduler/frame_rate_controller.h" #include "base/debug/trace_event.h" +#include "base/location.h" #include "base/logging.h" -#include "cc/base/thread.h" +#include "base/single_thread_task_runner.h" #include "cc/scheduler/delay_based_time_source.h" #include "cc/scheduler/time_source.h" @@ -41,20 +42,21 @@ FrameRateController::FrameRateController(scoped_refptr<TimeSource> timer) active_(false), is_time_source_throttling_(true), weak_factory_(this), - thread_(NULL) { + task_runner_(NULL) { time_source_client_adapter_ = FrameRateControllerTimeSourceAdapter::Create(this); time_source_->SetClient(time_source_client_adapter_.get()); } -FrameRateController::FrameRateController(Thread* thread) +FrameRateController::FrameRateController( + base::SingleThreadTaskRunner* task_runner) : client_(NULL), num_frames_pending_(0), max_swaps_pending_(0), active_(false), is_time_source_throttling_(false), weak_factory_(this), - thread_(thread) {} + task_runner_(task_runner) {} FrameRateController::~FrameRateController() { if (is_time_source_throttling_) @@ -95,7 +97,7 @@ void FrameRateController::OnTimerTick() { // Check if we have too many frames in flight. bool throttled = max_swaps_pending_ && num_frames_pending_ >= max_swaps_pending_; - TRACE_COUNTER_ID1("cc", "ThrottledCompositor", thread_, throttled); + TRACE_COUNTER_ID1("cc", "ThrottledCompositor", task_runner_, throttled); if (client_) { client_->FrameRateControllerTick(throttled); @@ -107,8 +109,9 @@ void FrameRateController::OnTimerTick() { void FrameRateController::PostManualTick() { if (active_) { - thread_->PostTask(base::Bind(&FrameRateController::ManualTick, - weak_factory_.GetWeakPtr())); + task_runner_->PostTask(FROM_HERE, + base::Bind(&FrameRateController::ManualTick, + weak_factory_.GetWeakPtr())); } } diff --git a/cc/scheduler/frame_rate_controller.h b/cc/scheduler/frame_rate_controller.h index 70964e2..bf667446 100644 --- a/cc/scheduler/frame_rate_controller.h +++ b/cc/scheduler/frame_rate_controller.h @@ -11,9 +11,10 @@ #include "base/time.h" #include "cc/base/cc_export.h" +namespace base { class SingleThreadTaskRunner; } + namespace cc { -class Thread; class TimeSource; class FrameRateController; @@ -38,7 +39,7 @@ class CC_EXPORT FrameRateController { explicit FrameRateController(scoped_refptr<TimeSource> timer); // Alternate form of FrameRateController with unthrottled frame-rate. - explicit FrameRateController(Thread* thread); + explicit FrameRateController(base::SingleThreadTaskRunner* task_runner); virtual ~FrameRateController(); void SetClient(FrameRateControllerClient* client) { client_ = client; } @@ -85,7 +86,7 @@ class CC_EXPORT FrameRateController { // Members for unthrottled frame-rate. bool is_time_source_throttling_; base::WeakPtrFactory<FrameRateController> weak_factory_; - Thread* thread_; + base::SingleThreadTaskRunner* task_runner_; private: DISALLOW_COPY_AND_ASSIGN(FrameRateController); diff --git a/cc/scheduler/frame_rate_controller_unittest.cc b/cc/scheduler/frame_rate_controller_unittest.cc index 3fcf4a7..7c0a0cc 100644 --- a/cc/scheduler/frame_rate_controller_unittest.cc +++ b/cc/scheduler/frame_rate_controller_unittest.cc @@ -4,6 +4,7 @@ #include "cc/scheduler/frame_rate_controller.h" +#include "base/test/test_simple_task_runner.h" #include "cc/test/scheduler_test_common.h" #include "testing/gtest/include/gtest/gtest.h" @@ -26,12 +27,13 @@ class FakeFrameRateControllerClient : public cc::FrameRateControllerClient { }; TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeFrameRateControllerClient client; base::TimeDelta interval = base::TimeDelta::FromMicroseconds( base::Time::kMicrosecondsPerSecond / 60); scoped_refptr<FakeDelayBasedTimeSource> time_source = - FakeDelayBasedTimeSource::Create(interval, &thread); + FakeDelayBasedTimeSource::Create(interval, task_runner.get()); FrameRateController controller(time_source); controller.SetClient(&client); @@ -40,9 +42,9 @@ TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) { base::TimeTicks elapsed; // Muck around with time a bit // Trigger one frame, make sure the BeginFrame callback is called - elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); + elapsed += task_runner->NextPendingTaskDelay(); time_source->SetNow(elapsed); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); client.Reset(); @@ -55,21 +57,22 @@ TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) { controller.DidSwapBuffersComplete(); // Trigger another frame, make sure BeginFrame runs again - elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); + elapsed += task_runner->NextPendingTaskDelay(); // Sanity check that previous code didn't move time backward. EXPECT_GE(elapsed, time_source->Now()); time_source->SetNow(elapsed); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); } TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeFrameRateControllerClient client; base::TimeDelta interval = base::TimeDelta::FromMicroseconds( base::Time::kMicrosecondsPerSecond / 60); scoped_refptr<FakeDelayBasedTimeSource> time_source = - FakeDelayBasedTimeSource::Create(interval, &thread); + FakeDelayBasedTimeSource::Create(interval, task_runner.get()); FrameRateController controller(time_source); controller.SetClient(&client); @@ -79,9 +82,9 @@ TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { base::TimeTicks elapsed; // Muck around with time a bit // Trigger one frame, make sure the BeginFrame callback is called - elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); + elapsed += task_runner->NextPendingTaskDelay(); time_source->SetNow(elapsed); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); client.Reset(); @@ -89,11 +92,11 @@ TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { controller.DidSwapBuffers(); // Trigger another frame, make sure BeginFrame callback runs again - elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); + elapsed += task_runner->NextPendingTaskDelay(); // Sanity check that previous code didn't move time backward. EXPECT_GE(elapsed, time_source->Now()); time_source->SetNow(elapsed); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); client.Reset(); @@ -101,11 +104,11 @@ TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { controller.DidSwapBuffers(); // Trigger another frame. Since two frames are pending, we should not draw. - elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); + elapsed += task_runner->NextPendingTaskDelay(); // Sanity check that previous code didn't move time backward. EXPECT_GE(elapsed, time_source->Now()); time_source->SetNow(elapsed); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_FALSE(client.BeganFrame()); // Tell the controller the first frame ended 5ms later @@ -118,18 +121,19 @@ TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { // Trigger yet another frame. Since one frames is pending, another // BeginFrame callback should run. - elapsed += base::TimeDelta::FromMilliseconds(thread.PendingDelayMs()); + elapsed += task_runner->NextPendingTaskDelay(); // Sanity check that previous code didn't move time backward. EXPECT_GE(elapsed, time_source->Now()); time_source->SetNow(elapsed); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); } TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) { - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; FakeFrameRateControllerClient client; - FrameRateController controller(&thread); + FrameRateController controller(task_runner.get()); controller.SetClient(&client); controller.SetMaxSwapsPending(2); @@ -137,43 +141,43 @@ TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) { // SetActive triggers 1st frame, make sure the BeginFrame callback // is called controller.SetActive(true); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); client.Reset(); // Even if we don't call DidSwapBuffers, FrameRateController should // still attempt to tick multiple times until it does result in // a DidSwapBuffers. - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); client.Reset(); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); client.Reset(); // DidSwapBuffers triggers 2nd frame, make sure the BeginFrame callback is // called controller.DidSwapBuffers(); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); client.Reset(); // DidSwapBuffers triggers 3rd frame (> max_frames_pending), // make sure the BeginFrame callback is NOT called controller.DidSwapBuffers(); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_FALSE(client.BeganFrame()); client.Reset(); // Make sure there is no pending task since we can't do anything until we // receive a DidSwapBuffersComplete anyway. - EXPECT_FALSE(thread.HasPendingTask()); + EXPECT_FALSE(task_runner->HasPendingTask()); // DidSwapBuffersComplete triggers a frame, make sure the BeginFrame // callback is called controller.DidSwapBuffersComplete(); - thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_TRUE(client.BeganFrame()); } |