summaryrefslogtreecommitdiffstats
path: root/cc/scheduler
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-18 17:39:51 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-18 17:39:51 +0000
commitdfd15d1a2facf6a47473ee9da97993dbfd075b4d (patch)
treee76aa995dde441e89025d2b7c15c2065a6d2f261 /cc/scheduler
parentbed29f042d424c95bad10263358bd65a36491c20 (diff)
downloadchromium_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.cc25
-rw-r--r--cc/scheduler/delay_based_time_source.h15
-rw-r--r--cc/scheduler/delay_based_time_source_unittest.cc225
-rw-r--r--cc/scheduler/frame_rate_controller.cc17
-rw-r--r--cc/scheduler/frame_rate_controller.h7
-rw-r--r--cc/scheduler/frame_rate_controller_unittest.cc54
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());
}