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 | |
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
23 files changed, 302 insertions, 285 deletions
diff --git a/base/test/test_simple_task_runner.cc b/base/test/test_simple_task_runner.cc index 440d6a1..cc39fab 100644 --- a/base/test/test_simple_task_runner.cc +++ b/base/test/test_simple_task_runner.cc @@ -47,6 +47,16 @@ TestSimpleTaskRunner::GetPendingTasks() const { return pending_tasks_; } +bool TestSimpleTaskRunner::HasPendingTask() const { + DCHECK(thread_checker_.CalledOnValidThread()); + return !pending_tasks_.empty(); +} + +base::TimeDelta TestSimpleTaskRunner::NextPendingTaskDelay() const { + DCHECK(thread_checker_.CalledOnValidThread()); + return pending_tasks_.front().GetTimeToRun() - base::TimeTicks(); +} + void TestSimpleTaskRunner::ClearPendingTasks() { DCHECK(thread_checker_.CalledOnValidThread()); pending_tasks_.clear(); diff --git a/base/test/test_simple_task_runner.h b/base/test/test_simple_task_runner.h index 88113be..c011ea5 100644 --- a/base/test/test_simple_task_runner.h +++ b/base/test/test_simple_task_runner.h @@ -15,6 +15,8 @@ namespace base { +class TimeDelta; + // TestSimpleTaskRunner is a simple TaskRunner implementation that can // be used for testing. It implements SingleThreadTaskRunner as that // interface implements SequencedTaskRunner, which in turn implements @@ -56,6 +58,8 @@ class TestSimpleTaskRunner : public SingleThreadTaskRunner { virtual bool RunsTasksOnCurrentThread() const OVERRIDE; const std::deque<TestPendingTask>& GetPendingTasks() const; + bool HasPendingTask() const; + base::TimeDelta NextPendingTaskDelay() const; // Clears the queue of pending tasks without running them. void ClearPendingTasks(); diff --git a/cc/base/thread.h b/cc/base/thread.h index 44be3b4..296f70e 100644 --- a/cc/base/thread.h +++ b/cc/base/thread.h @@ -10,6 +10,8 @@ #include "base/time.h" #include "cc/base/cc_export.h" +namespace base { class SingleThreadTaskRunner; } + namespace cc { // Thread provides basic infrastructure for messaging with the compositor in a @@ -25,6 +27,8 @@ class CC_EXPORT Thread { virtual void PostDelayedTask(base::Closure cb, base::TimeDelta delay) = 0; virtual bool BelongsToCurrentThread() const = 0; + + virtual base::SingleThreadTaskRunner* TaskRunner() = 0; }; } // namespace cc diff --git a/cc/base/thread_impl.cc b/cc/base/thread_impl.cc index 8e779cb..c76213d 100644 --- a/cc/base/thread_impl.cc +++ b/cc/base/thread_impl.cc @@ -32,6 +32,10 @@ bool ThreadImpl::BelongsToCurrentThread() const { return thread_->BelongsToCurrentThread(); } +base::SingleThreadTaskRunner* ThreadImpl::TaskRunner() { + return thread_.get(); +} + ThreadImpl::ThreadImpl(scoped_refptr<base::MessageLoopProxy> thread) : thread_(thread) {} diff --git a/cc/base/thread_impl.h b/cc/base/thread_impl.h index 473db9c1..9bc47a8 100644 --- a/cc/base/thread_impl.h +++ b/cc/base/thread_impl.h @@ -29,6 +29,7 @@ class CC_EXPORT ThreadImpl : public Thread { virtual void PostDelayedTask(base::Closure cb, base::TimeDelta delay) OVERRIDE; virtual bool BelongsToCurrentThread() const OVERRIDE; + virtual base::SingleThreadTaskRunner* TaskRunner() OVERRIDE; private: explicit ThreadImpl(scoped_refptr<base::MessageLoopProxy> thread); diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc index 086b3af..c3d8d28 100644 --- a/cc/layers/tiled_layer_unittest.cc +++ b/cc/layers/tiled_layer_unittest.cc @@ -97,7 +97,7 @@ class TiledLayerTest : public testing::Test { DCHECK(queue_); scoped_ptr<ResourceUpdateController> update_controller = ResourceUpdateController::Create(NULL, - proxy_->ImplThread(), + NULL, queue_.Pass(), resource_provider_.get()); update_controller->Finalize(); diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc index 610aebf..160f86d 100644 --- a/cc/output/output_surface.cc +++ b/cc/output/output_surface.cc @@ -91,15 +91,15 @@ OutputSurface::OutputSurface( } void OutputSurface::InitializeBeginFrameEmulation( - Thread* thread, + base::SingleThreadTaskRunner* task_runner, bool throttle_frame_production, base::TimeDelta interval) { if (throttle_frame_production){ frame_rate_controller_.reset( new FrameRateController( - DelayBasedTimeSource::Create(interval, thread))); + DelayBasedTimeSource::Create(interval, task_runner))); } else { - frame_rate_controller_.reset(new FrameRateController(thread)); + frame_rate_controller_.reset(new FrameRateController(task_runner)); } frame_rate_controller_->SetClient(this); diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h index 8f782d7..0ef25aed 100644 --- a/cc/output/output_surface.h +++ b/cc/output/output_surface.h @@ -15,6 +15,8 @@ #include "cc/scheduler/frame_rate_controller.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" +namespace base { class SingleThreadTaskRunner; } + namespace ui { struct LatencyInfo; } namespace gfx { @@ -29,7 +31,6 @@ class CompositorFrame; class CompositorFrameAck; class OutputSurfaceClient; class OutputSurfaceCallbacks; -class Thread; // Represents the output surface for a compositor. The compositor owns // and manages its destruction. Its lifetime is: @@ -88,9 +89,9 @@ class CC_EXPORT OutputSurface : public FrameRateControllerClient { virtual bool BindToClient(OutputSurfaceClient* client); void InitializeBeginFrameEmulation( - Thread* thread, - bool throttle_frame_production, - base::TimeDelta interval); + base::SingleThreadTaskRunner* task_runner, + bool throttle_frame_production, + base::TimeDelta interval); void SetMaxFramesPending(int max_frames_pending); diff --git a/cc/output/output_surface_unittest.cc b/cc/output/output_surface_unittest.cc index 7dcb1cc..e42777a 100644 --- a/cc/output/output_surface_unittest.cc +++ b/cc/output/output_surface_unittest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/test/test_simple_task_runner.h" #include "cc/output/output_surface.h" #include "cc/output/output_surface_client.h" #include "cc/output/software_output_device.h" @@ -208,13 +209,14 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) { EXPECT_FALSE(client.deferred_initialize_called()); // Initialize BeginFrame emulation - FakeThread impl_thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; bool throttle_frame_production = true; const base::TimeDelta display_refresh_interval = base::TimeDelta::FromMicroseconds(16666); output_surface.InitializeBeginFrameEmulation( - &impl_thread, + task_runner.get(), throttle_frame_production, display_refresh_interval); @@ -225,17 +227,17 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) { EXPECT_EQ(output_surface.pending_swap_buffers(), 0); // We should not have a pending task until a BeginFrame has been requested. - EXPECT_FALSE(impl_thread.HasPendingTask()); + EXPECT_FALSE(task_runner->HasPendingTask()); output_surface.SetNeedsBeginFrame(true); - EXPECT_TRUE(impl_thread.HasPendingTask()); + EXPECT_TRUE(task_runner->HasPendingTask()); // BeginFrame should be called on the first tick. - impl_thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_EQ(client.begin_frame_count(), 1); EXPECT_EQ(output_surface.pending_swap_buffers(), 0); // BeginFrame should not be called when there is a pending BeginFrame. - impl_thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_EQ(client.begin_frame_count(), 1); EXPECT_EQ(output_surface.pending_swap_buffers(), 0); @@ -243,7 +245,7 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) { output_surface.DidSwapBuffersForTesting(); EXPECT_EQ(client.begin_frame_count(), 1); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); - impl_thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_EQ(client.begin_frame_count(), 2); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); @@ -251,7 +253,7 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) { output_surface.DidSwapBuffersForTesting(); EXPECT_EQ(client.begin_frame_count(), 2); EXPECT_EQ(output_surface.pending_swap_buffers(), 2); - impl_thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_EQ(client.begin_frame_count(), 2); EXPECT_EQ(output_surface.pending_swap_buffers(), 2); @@ -259,21 +261,21 @@ TEST(OutputSurfaceTest, BeginFrameEmulation) { output_surface.OnSwapBuffersCompleteForTesting(); EXPECT_EQ(client.begin_frame_count(), 2); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); - impl_thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_EQ(client.begin_frame_count(), 3); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); // Calling SetNeedsBeginFrame again indicates a swap did not occur but // the client still wants another BeginFrame. output_surface.SetNeedsBeginFrame(true); - impl_thread.RunPendingTask(); + task_runner->RunPendingTasks(); EXPECT_EQ(client.begin_frame_count(), 4); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); // Disabling SetNeedsBeginFrame should prevent further BeginFrames. output_surface.SetNeedsBeginFrame(false); - impl_thread.RunPendingTask(); - EXPECT_FALSE(impl_thread.HasPendingTask()); + task_runner->RunPendingTasks(); + EXPECT_FALSE(task_runner->HasPendingTask()); EXPECT_EQ(client.begin_frame_count(), 4); EXPECT_EQ(output_surface.pending_swap_buffers(), 1); diff --git a/cc/resources/resource_update_controller.cc b/cc/resources/resource_update_controller.cc index 350b4d6..e9cc2a2 100644 --- a/cc/resources/resource_update_controller.cc +++ b/cc/resources/resource_update_controller.cc @@ -5,7 +5,8 @@ #include "cc/resources/resource_update_controller.h" #include "base/bind.h" -#include "cc/base/thread.h" +#include "base/location.h" +#include "base/single_thread_task_runner.h" #include "cc/output/texture_copier.h" #include "cc/resources/prioritized_resource.h" #include "cc/resources/resource_provider.h" @@ -42,7 +43,7 @@ size_t ResourceUpdateController::MaxFullUpdatesPerTick( ResourceUpdateController::ResourceUpdateController( ResourceUpdateControllerClient* client, - Thread* thread, + base::SingleThreadTaskRunner* task_runner, scoped_ptr<ResourceUpdateQueue> queue, ResourceProvider* resource_provider) : client_(client), @@ -50,7 +51,7 @@ ResourceUpdateController::ResourceUpdateController( resource_provider_(resource_provider), texture_updates_per_tick_(MaxFullUpdatesPerTick(resource_provider)), first_update_attempt_(true), - thread_(thread), + task_runner_(task_runner), weak_factory_(this), task_posted_(false) {} @@ -74,7 +75,8 @@ void ResourceUpdateController::PerformMoreUpdates( // ReadyToFinalizeTextureUpdates() will be called. if (!UpdateMoreTexturesIfEnoughTimeRemaining()) { task_posted_ = true; - thread_->PostTask( + task_runner_->PostTask( + FROM_HERE, base::Bind(&ResourceUpdateController::OnTimerFired, weak_factory_.GetWeakPtr())); } @@ -167,7 +169,8 @@ bool ResourceUpdateController::UpdateMoreTexturesIfEnoughTimeRemaining() { } task_posted_ = true; - thread_->PostDelayedTask( + task_runner_->PostDelayedTask( + FROM_HERE, base::Bind(&ResourceUpdateController::OnTimerFired, weak_factory_.GetWeakPtr()), base::TimeDelta::FromMilliseconds(kUploaderBusyTickRate * 1000)); diff --git a/cc/resources/resource_update_controller.h b/cc/resources/resource_update_controller.h index 39ce75d9..b9fbfe1 100644 --- a/cc/resources/resource_update_controller.h +++ b/cc/resources/resource_update_controller.h @@ -12,10 +12,11 @@ #include "cc/base/cc_export.h" #include "cc/resources/resource_update_queue.h" +namespace base { class SingleThreadTaskRunner; } + namespace cc { class ResourceProvider; -class Thread; class ResourceUpdateControllerClient { public: @@ -29,11 +30,11 @@ class CC_EXPORT ResourceUpdateController { public: static scoped_ptr<ResourceUpdateController> Create( ResourceUpdateControllerClient* client, - Thread* thread, + base::SingleThreadTaskRunner* task_runner, scoped_ptr<ResourceUpdateQueue> queue, ResourceProvider* resource_provider) { return make_scoped_ptr(new ResourceUpdateController( - client, thread, queue.Pass(), resource_provider)); + client, task_runner, queue.Pass(), resource_provider)); } static size_t MaxPartialTextureUpdates(); @@ -53,7 +54,7 @@ class CC_EXPORT ResourceUpdateController { protected: ResourceUpdateController(ResourceUpdateControllerClient* client, - Thread* thread, + base::SingleThreadTaskRunner* task_runner, scoped_ptr<ResourceUpdateQueue> queue, ResourceProvider* resource_provider); @@ -77,7 +78,7 @@ class CC_EXPORT ResourceUpdateController { base::TimeTicks time_limit_; size_t texture_updates_per_tick_; bool first_update_attempt_; - Thread* thread_; + base::SingleThreadTaskRunner* task_runner_; base::WeakPtrFactory<ResourceUpdateController> weak_factory_; bool task_posted_; diff --git a/cc/resources/resource_update_controller_unittest.cc b/cc/resources/resource_update_controller_unittest.cc index 5507eb5..6196bd1 100644 --- a/cc/resources/resource_update_controller_unittest.cc +++ b/cc/resources/resource_update_controller_unittest.cc @@ -4,6 +4,7 @@ #include "cc/resources/resource_update_controller.h" +#include "base/test/test_simple_task_runner.h" #include "cc/resources/prioritized_resource_manager.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_proxy.h" @@ -180,8 +181,10 @@ class ResourceUpdateControllerTest : public Test { DebugScopedSetImplThreadAndMainThreadBlocked impl_thread_and_main_thread_blocked(&proxy_); scoped_ptr<ResourceUpdateController> update_controller = - ResourceUpdateController::Create( - NULL, proxy_.ImplThread(), queue_.Pass(), resource_provider_.get()); + ResourceUpdateController::Create(NULL, + NULL, + queue_.Pass(), + resource_provider_.get()); update_controller->Finalize(); } @@ -326,7 +329,7 @@ TEST_F(ResourceUpdateControllerTest, ManyFullManyPartialUploads) { } class FakeResourceUpdateControllerClient - : public cc::ResourceUpdateControllerClient { + : public ResourceUpdateControllerClient { public: FakeResourceUpdateControllerClient() { Reset(); } void Reset() { ready_to_finalize_called_ = false; } @@ -340,14 +343,15 @@ class FakeResourceUpdateControllerClient bool ready_to_finalize_called_; }; -class FakeResourceUpdateController : public cc::ResourceUpdateController { +class FakeResourceUpdateController : public ResourceUpdateController { public: static scoped_ptr<FakeResourceUpdateController> Create( - cc::ResourceUpdateControllerClient* client, cc::Thread* thread, + ResourceUpdateControllerClient* client, + base::TestSimpleTaskRunner* task_runner, scoped_ptr<ResourceUpdateQueue> queue, ResourceProvider* resource_provider) { return make_scoped_ptr(new FakeResourceUpdateController( - client, thread, queue.Pass(), resource_provider)); + client, task_runner, queue.Pass(), resource_provider)); } void SetNow(base::TimeTicks time) { now_ = time; } @@ -366,12 +370,12 @@ class FakeResourceUpdateController : public cc::ResourceUpdateController { } protected: - FakeResourceUpdateController(cc::ResourceUpdateControllerClient* client, - cc::Thread* thread, + FakeResourceUpdateController(ResourceUpdateControllerClient* client, + base::TestSimpleTaskRunner* task_runner, scoped_ptr<ResourceUpdateQueue> queue, ResourceProvider* resource_provider) - : cc::ResourceUpdateController( - client, thread, queue.Pass(), resource_provider), + : ResourceUpdateController( + client, task_runner, queue.Pass(), resource_provider), update_more_textures_size_(0) {} base::TimeTicks now_; @@ -379,17 +383,17 @@ class FakeResourceUpdateController : public cc::ResourceUpdateController { size_t update_more_textures_size_; }; -static void RunPendingTask(FakeThread* thread, +static void RunPendingTask(base::TestSimpleTaskRunner* task_runner, FakeResourceUpdateController* controller) { - EXPECT_TRUE(thread->HasPendingTask()); - controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds( - thread->PendingDelayMs())); - thread->RunPendingTask(); + EXPECT_TRUE(task_runner->HasPendingTask()); + controller->SetNow(controller->Now() + task_runner->NextPendingTaskDelay()); + task_runner->RunPendingTasks(); } TEST_F(ResourceUpdateControllerTest, UpdateMoreTextures) { FakeResourceUpdateControllerClient client; - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; SetMaxUploadCountPerUpdate(1); AppendFullUploadsToUpdateQueue(3); @@ -398,7 +402,9 @@ TEST_F(ResourceUpdateControllerTest, UpdateMoreTextures) { DebugScopedSetImplThreadAndMainThreadBlocked impl_thread_and_main_thread_blocked(&proxy_); scoped_ptr<FakeResourceUpdateController> controller( - FakeResourceUpdateController::Create(&client, &thread, queue_.Pass(), + FakeResourceUpdateController::Create(&client, + task_runner.get(), + queue_.Pass(), resource_provider_.get())); controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds(1)); @@ -407,14 +413,14 @@ TEST_F(ResourceUpdateControllerTest, UpdateMoreTextures) { // Not enough time for any updates. controller->PerformMoreUpdates(controller->Now() + base::TimeDelta::FromMilliseconds(90)); - EXPECT_FALSE(thread.HasPendingTask()); + EXPECT_FALSE(task_runner->HasPendingTask()); controller->SetUpdateMoreTexturesTime(base::TimeDelta::FromMilliseconds(100)); controller->SetUpdateMoreTexturesSize(1); // Only enough time for 1 update. controller->PerformMoreUpdates(controller->Now() + base::TimeDelta::FromMilliseconds(120)); - EXPECT_FALSE(thread.HasPendingTask()); + EXPECT_FALSE(task_runner->HasPendingTask()); EXPECT_EQ(1, num_total_uploads_); // Complete one upload. @@ -425,15 +431,16 @@ TEST_F(ResourceUpdateControllerTest, UpdateMoreTextures) { // Enough time for 2 updates. controller->PerformMoreUpdates(controller->Now() + base::TimeDelta::FromMilliseconds(220)); - RunPendingTask(&thread, controller.get()); - EXPECT_FALSE(thread.HasPendingTask()); + RunPendingTask(task_runner.get(), controller.get()); + EXPECT_FALSE(task_runner->HasPendingTask()); EXPECT_TRUE(client.ReadyToFinalizeCalled()); EXPECT_EQ(3, num_total_uploads_); } TEST_F(ResourceUpdateControllerTest, NoMoreUpdates) { FakeResourceUpdateControllerClient client; - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; SetMaxUploadCountPerUpdate(1); AppendFullUploadsToUpdateQueue(2); @@ -442,7 +449,9 @@ TEST_F(ResourceUpdateControllerTest, NoMoreUpdates) { DebugScopedSetImplThreadAndMainThreadBlocked impl_thread_and_main_thread_blocked(&proxy_); scoped_ptr<FakeResourceUpdateController> controller( - FakeResourceUpdateController::Create(&client, &thread, queue_.Pass(), + FakeResourceUpdateController::Create(&client, + task_runner.get(), + queue_.Pass(), resource_provider_.get())); controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds(1)); @@ -451,8 +460,8 @@ TEST_F(ResourceUpdateControllerTest, NoMoreUpdates) { // Enough time for 3 updates but only 2 necessary. controller->PerformMoreUpdates(controller->Now() + base::TimeDelta::FromMilliseconds(310)); - RunPendingTask(&thread, controller.get()); - EXPECT_FALSE(thread.HasPendingTask()); + RunPendingTask(task_runner.get(), controller.get()); + EXPECT_FALSE(task_runner->HasPendingTask()); EXPECT_TRUE(client.ReadyToFinalizeCalled()); EXPECT_EQ(2, num_total_uploads_); @@ -462,15 +471,16 @@ TEST_F(ResourceUpdateControllerTest, NoMoreUpdates) { controller->PerformMoreUpdates(controller->Now() + base::TimeDelta::FromMilliseconds(310)); // 0-delay task used to call ReadyToFinalizeTextureUpdates(). - RunPendingTask(&thread, controller.get()); - EXPECT_FALSE(thread.HasPendingTask()); + RunPendingTask(task_runner.get(), controller.get()); + EXPECT_FALSE(task_runner->HasPendingTask()); EXPECT_TRUE(client.ReadyToFinalizeCalled()); EXPECT_EQ(2, num_total_uploads_); } TEST_F(ResourceUpdateControllerTest, UpdatesCompleteInFiniteTime) { FakeResourceUpdateControllerClient client; - FakeThread thread; + scoped_refptr<base::TestSimpleTaskRunner> task_runner = + new base::TestSimpleTaskRunner; SetMaxUploadCountPerUpdate(1); AppendFullUploadsToUpdateQueue(2); @@ -479,7 +489,9 @@ TEST_F(ResourceUpdateControllerTest, UpdatesCompleteInFiniteTime) { DebugScopedSetImplThreadAndMainThreadBlocked impl_thread_and_main_thread_blocked(&proxy_); scoped_ptr<FakeResourceUpdateController> controller( - FakeResourceUpdateController::Create(&client, &thread, queue_.Pass(), + FakeResourceUpdateController::Create(&client, + task_runner.get(), + queue_.Pass(), resource_provider_.get())); controller->SetNow(controller->Now() + base::TimeDelta::FromMilliseconds(1)); @@ -494,11 +506,11 @@ TEST_F(ResourceUpdateControllerTest, UpdatesCompleteInFiniteTime) { controller->PerformMoreUpdates(controller->Now() + base::TimeDelta::FromMilliseconds(400)); - if (thread.HasPendingTask()) - RunPendingTask(&thread, controller.get()); + if (task_runner->HasPendingTask()) + RunPendingTask(task_runner.get(), controller.get()); } - EXPECT_FALSE(thread.HasPendingTask()); + EXPECT_FALSE(task_runner->HasPendingTask()); EXPECT_TRUE(client.ReadyToFinalizeCalled()); EXPECT_EQ(2, num_total_uploads_); } 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()); } diff --git a/cc/test/scheduler_test_common.cc b/cc/test/scheduler_test_common.cc index 8ccf47e..c812056 100644 --- a/cc/test/scheduler_test_common.cc +++ b/cc/test/scheduler_test_common.cc @@ -10,31 +10,6 @@ namespace cc { void FakeTimeSourceClient::OnTimerTick() { tick_called_ = true; } -FakeThread::FakeThread() { Reset(); } - -FakeThread::~FakeThread() {} - -void FakeThread::RunPendingTask() { - ASSERT_TRUE(pending_task_); - scoped_ptr<base::Closure> task = pending_task_.Pass(); - task->Run(); -} - -void FakeThread::PostTask(base::Closure cb) { - PostDelayedTask(cb, base::TimeDelta()); -} - -void FakeThread::PostDelayedTask(base::Closure cb, base::TimeDelta delay) { - if (run_pending_task_on_overwrite_ && HasPendingTask()) - RunPendingTask(); - - ASSERT_FALSE(HasPendingTask()); - pending_task_.reset(new base::Closure(cb)); - pending_task_delay_ = delay.InMilliseconds(); -} - -bool FakeThread::BelongsToCurrentThread() const { return true; } - base::TimeTicks FakeDelayBasedTimeSource::Now() const { return now_; } } // namespace cc diff --git a/cc/test/scheduler_test_common.h b/cc/test/scheduler_test_common.h index 8834e62..e268020 100644 --- a/cc/test/scheduler_test_common.h +++ b/cc/test/scheduler_test_common.h @@ -28,53 +28,21 @@ class FakeTimeSourceClient : public cc::TimeSourceClient { bool tick_called_; }; -class FakeThread : public cc::Thread { - public: - FakeThread(); - virtual ~FakeThread(); - - void Reset() { - pending_task_delay_ = 0; - pending_task_.reset(); - run_pending_task_on_overwrite_ = false; - } - - void RunPendingTaskOnOverwrite(bool enable) { - run_pending_task_on_overwrite_ = enable; - } - - bool HasPendingTask() const { return pending_task_; } - void RunPendingTask(); - - int64 PendingDelayMs() const { - EXPECT_TRUE(HasPendingTask()); - return pending_task_delay_; - } - - virtual void PostTask(base::Closure cb) OVERRIDE; - virtual void PostDelayedTask(base::Closure cb, base::TimeDelta delay) - OVERRIDE; - virtual bool BelongsToCurrentThread() const OVERRIDE; - - protected: - scoped_ptr<base::Closure> pending_task_; - int64 pending_task_delay_; - bool run_pending_task_on_overwrite_; -}; - class FakeDelayBasedTimeSource : public cc::DelayBasedTimeSource { public: static scoped_refptr<FakeDelayBasedTimeSource> Create( - base::TimeDelta interval, cc::Thread* thread) { - return make_scoped_refptr(new FakeDelayBasedTimeSource(interval, thread)); + base::TimeDelta interval, base::SingleThreadTaskRunner* task_runner) { + return make_scoped_refptr(new FakeDelayBasedTimeSource(interval, + task_runner)); } void SetNow(base::TimeTicks time) { now_ = time; } virtual base::TimeTicks Now() const OVERRIDE; protected: - FakeDelayBasedTimeSource(base::TimeDelta interval, cc::Thread* thread) - : DelayBasedTimeSource(interval, thread) {} + FakeDelayBasedTimeSource(base::TimeDelta interval, + base::SingleThreadTaskRunner* task_runner) + : DelayBasedTimeSource(interval, task_runner) {} virtual ~FakeDelayBasedTimeSource() {} base::TimeTicks now_; diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index b01aee6..e4ca7e4 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -14,6 +14,7 @@ #include "cc/animation/scrollbar_animation_controller.h" #include "cc/animation/timing_function.h" #include "cc/base/math_util.h" +#include "cc/base/thread.h" #include "cc/base/util.h" #include "cc/debug/debug_rect_history.h" #include "cc/debug/frame_rate_counter.h" @@ -775,7 +776,7 @@ void LayerTreeHostImpl::UpdateBackgroundAnimateTicking( time_source_client_adapter_ = LayerTreeHostImplTimeSourceAdapter::Create( this, DelayBasedTimeSource::Create(LowFrequencyAnimationInterval(), - proxy_->CurrentThread())); + proxy_->CurrentThread()->TaskRunner())); } time_source_client_adapter_->SetActive(enabled); @@ -1517,7 +1518,7 @@ bool LayerTreeHostImpl::DoInitializeRenderer( settings_.refresh_rate); output_surface->InitializeBeginFrameEmulation( - proxy_->ImplThread(), + proxy_->ImplThread() ? proxy_->ImplThread()->TaskRunner() : NULL, settings_.throttle_frame_production, display_refresh_interval); } diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index a03f2b9..00bd8d1 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc @@ -194,7 +194,7 @@ void SingleThreadProxy::DoCommit(scoped_ptr<ResourceUpdateQueue> queue) { scoped_ptr<ResourceUpdateController> update_controller = ResourceUpdateController::Create( NULL, - Proxy::MainThread(), + Proxy::MainThread()->TaskRunner(), queue.Pass(), layer_tree_host_impl_->resource_provider()); update_controller->Finalize(); diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index f745f3a..a7c4086 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -801,7 +801,7 @@ void ThreadProxy::StartCommitOnImplThread( current_resource_update_controller_on_impl_thread_ = ResourceUpdateController::Create( this, - Proxy::ImplThread(), + Proxy::ImplThread()->TaskRunner(), queue.Pass(), layer_tree_host_impl_->resource_provider()); current_resource_update_controller_on_impl_thread_->PerformMoreUpdates( |