diff options
author | skyostil <skyostil@chromium.org> | 2014-09-04 15:07:23 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-04 22:13:39 +0000 |
commit | 3976a3f8509145051ff2865ccba0fffe79fe32e6 (patch) | |
tree | ca45dac492bdae25c13c97f906eb23fec2455f3b | |
parent | d8988a18cf52f4cfc146a5a57251bfa6cd4ef8f6 (diff) | |
download | chromium_src-3976a3f8509145051ff2865ccba0fffe79fe32e6.zip chromium_src-3976a3f8509145051ff2865ccba0fffe79fe32e6.tar.gz chromium_src-3976a3f8509145051ff2865ccba0fffe79fe32e6.tar.bz2 |
cc: Use correct message loop proxy in BlockingTaskRunner
The compositor makes it possible to customize the message loop proxy
both on the main and impl threads. However BlockingTaskRunner just uses
base::MessageLoopProxy::current() directly and thus overrides this
choice. Using the correct message loop proxy is important because
clients of BlockingTaskRunner have an implicit dependency on the
ordering of tasks posted to BlockingTaskRunner vs. all other tasks
posted to the task runner for that same thread.
This patch fixes the problem by removing the thread-local
BlockingTaskRunner::current() instance in favor of an explicitly
constructed instance which is given a specific SingleThreadTaskRunner
to use. The resource provider is changed to pass a Proxy-owned
blocking task runner to the clients which need one.
BUG=391005
TEST=1. Apply https://codereview.chromium.org/363383002
2. out/Debug/chrome --disable-impl-side-painting --ignore-gpu-blacklist tools/perf/page_sets/tough_scheduling_cases/raf_canvas.html
Review URL: https://codereview.chromium.org/485043003
Cr-Commit-Position: refs/heads/master@{#293353}
62 files changed, 972 insertions, 402 deletions
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index 109b54b..43a6c6d 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn @@ -399,6 +399,8 @@ component("cc") { "resources/shared_bitmap_manager.h", "resources/single_release_callback.cc", "resources/single_release_callback.h", + "resources/single_release_callback_impl.cc", + "resources/single_release_callback_impl.h", "resources/skpicture_content_layer_updater.cc", "resources/skpicture_content_layer_updater.h", "resources/task_graph_runner.cc", @@ -724,6 +726,7 @@ test("cc_unittests") { "scheduler/scheduler_unittest.cc", "test/layer_tree_json_parser_unittest.cc", "test/test_web_graphics_context_3d_unittest.cc", + "trees/blocking_task_runner_unittest.cc", "trees/damage_tracker_unittest.cc", "trees/layer_sorter_unittest.cc", "trees/layer_tree_host_common_unittest.cc", @@ -428,6 +428,8 @@ 'resources/shared_bitmap_manager.h', 'resources/single_release_callback.cc', 'resources/single_release_callback.h', + 'resources/single_release_callback_impl.cc', + 'resources/single_release_callback_impl.h', 'resources/skpicture_content_layer_updater.cc', 'resources/skpicture_content_layer_updater.h', 'resources/task_graph_runner.cc', diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index 8ecb203..e9b99d0 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -97,6 +97,7 @@ 'test/layer_tree_json_parser_unittest.cc', 'test/ordered_simple_task_runner_unittest.cc', 'test/test_web_graphics_context_3d_unittest.cc', + 'trees/blocking_task_runner_unittest.cc', 'trees/damage_tracker_unittest.cc', 'trees/layer_sorter_unittest.cc', 'trees/layer_tree_host_common_unittest.cc', diff --git a/cc/layers/delegated_frame_resource_collection.cc b/cc/layers/delegated_frame_resource_collection.cc index 5ca4eda..b0e4cbf 100644 --- a/cc/layers/delegated_frame_resource_collection.cc +++ b/cc/layers/delegated_frame_resource_collection.cc @@ -11,7 +11,6 @@ namespace cc { DelegatedFrameResourceCollection::DelegatedFrameResourceCollection() : client_(NULL), - main_thread_runner_(BlockingTaskRunner::current()), lost_all_resources_(false), weak_ptr_factory_(this) { DCHECK(main_thread_checker_.CalledOnValidThread()); @@ -115,9 +114,9 @@ void DelegatedFrameResourceCollection::RefResources( static void UnrefResourcesOnImplThread( base::WeakPtr<DelegatedFrameResourceCollection> self, - scoped_refptr<BlockingTaskRunner> main_thread_runner, - const ReturnedResourceArray& returned) { - main_thread_runner->PostTask( + const ReturnedResourceArray& returned, + BlockingTaskRunner* main_thread_task_runner) { + main_thread_task_runner->PostTask( FROM_HERE, base::Bind( &DelegatedFrameResourceCollection::UnrefResources, self, returned)); @@ -126,8 +125,7 @@ static void UnrefResourcesOnImplThread( ReturnCallback DelegatedFrameResourceCollection::GetReturnResourcesCallbackForImplThread() { return base::Bind(&UnrefResourcesOnImplThread, - weak_ptr_factory_.GetWeakPtr(), - main_thread_runner_); + weak_ptr_factory_.GetWeakPtr()); } } // namespace cc diff --git a/cc/layers/delegated_frame_resource_collection.h b/cc/layers/delegated_frame_resource_collection.h index 9a5d336..afbc355 100644 --- a/cc/layers/delegated_frame_resource_collection.h +++ b/cc/layers/delegated_frame_resource_collection.h @@ -15,7 +15,6 @@ #include "cc/resources/transferable_resource.h" namespace cc { -class BlockingTaskRunner; class CC_EXPORT DelegatedFrameResourceCollectionClient { public: @@ -48,7 +47,6 @@ class CC_EXPORT DelegatedFrameResourceCollection ~DelegatedFrameResourceCollection(); DelegatedFrameResourceCollectionClient* client_; - scoped_refptr<BlockingTaskRunner> main_thread_runner_; ReturnedResourceArray returned_resources_for_child_compositor_; bool lost_all_resources_; diff --git a/cc/layers/delegated_frame_resource_collection_unittest.cc b/cc/layers/delegated_frame_resource_collection_unittest.cc index 9f131df..9bfd59c 100644 --- a/cc/layers/delegated_frame_resource_collection_unittest.cc +++ b/cc/layers/delegated_frame_resource_collection_unittest.cc @@ -9,6 +9,7 @@ #include "cc/layers/delegated_frame_resource_collection.h" #include "cc/resources/returned_resource.h" #include "cc/resources/transferable_resource.h" +#include "cc/trees/blocking_task_runner.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { @@ -80,8 +81,9 @@ TEST_F(DelegatedFrameResourceCollectionTest, NoRef) { void ReturnResourcesOnThread(ReturnCallback callback, const ReturnedResourceArray& resources, - base::WaitableEvent* event) { - callback.Run(resources); + base::WaitableEvent* event, + BlockingTaskRunner* main_thread_task_runner) { + callback.Run(resources, main_thread_task_runner); if (event) event->Wait(); } @@ -92,6 +94,8 @@ void ReturnResourcesOnThread(ReturnCallback callback, TEST_F(DelegatedFrameResourceCollectionTest, Thread) { base::Thread thread("test thread"); thread.Start(); + scoped_ptr<BlockingTaskRunner> main_thread_task_runner( + BlockingTaskRunner::Create(base::MessageLoopProxy::current())); TransferableResourceArray resources = CreateResourceArray(); resource_collection_->ReceivedResources(resources); @@ -112,7 +116,8 @@ TEST_F(DelegatedFrameResourceCollectionTest, Thread) { &ReturnResourcesOnThread, resource_collection_->GetReturnResourcesCallbackForImplThread(), returned_resources, - &event)); + &event, + main_thread_task_runner.get())); run_loop.Run(); } @@ -151,7 +156,8 @@ TEST_F(DelegatedFrameResourceCollectionTest, Thread) { base::Bind(&ReturnResourcesOnThread, return_callback, returned_resources, - null_event)); + null_event, + main_thread_task_runner.get())); thread.Stop(); } diff --git a/cc/layers/delegated_renderer_layer.cc b/cc/layers/delegated_renderer_layer.cc index 2dd1234..99aebdc 100644 --- a/cc/layers/delegated_renderer_layer.cc +++ b/cc/layers/delegated_renderer_layer.cc @@ -24,7 +24,6 @@ DelegatedRendererLayer::DelegatedRendererLayer( frame_provider_(frame_provider), should_collect_new_frame_(true), frame_data_(NULL), - main_thread_runner_(BlockingTaskRunner::current()), weak_ptrs_(this) { frame_provider_->AddObserver(this); } diff --git a/cc/layers/delegated_renderer_layer.h b/cc/layers/delegated_renderer_layer.h index 0e4b958..be0a04e 100644 --- a/cc/layers/delegated_renderer_layer.h +++ b/cc/layers/delegated_renderer_layer.h @@ -47,7 +47,6 @@ class CC_EXPORT DelegatedRendererLayer : public Layer { DelegatedFrameData* frame_data_; gfx::RectF frame_damage_; - scoped_refptr<BlockingTaskRunner> main_thread_runner_; base::WeakPtrFactory<DelegatedRendererLayer> weak_ptrs_; DISALLOW_COPY_AND_ASSIGN(DelegatedRendererLayer); diff --git a/cc/layers/texture_layer.cc b/cc/layers/texture_layer.cc index c498bd1..3bccc7e 100644 --- a/cc/layers/texture_layer.cc +++ b/cc/layers/texture_layer.cc @@ -12,6 +12,7 @@ #include "cc/layers/texture_layer_client.h" #include "cc/layers/texture_layer_impl.h" #include "cc/resources/single_release_callback.h" +#include "cc/resources/single_release_callback_impl.h" #include "cc/trees/blocking_task_runner.h" #include "cc/trees/layer_tree_host.h" @@ -244,13 +245,14 @@ void TextureLayer::PushPropertiesTo(LayerImpl* layer) { texture_layer->SetBlendBackgroundColor(blend_background_color_); if (needs_set_mailbox_) { TextureMailbox texture_mailbox; - scoped_ptr<SingleReleaseCallback> release_callback; + scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl; if (holder_ref_) { TextureMailboxHolder* holder = holder_ref_->holder(); texture_mailbox = holder->mailbox(); - release_callback = holder->GetCallbackForImplThread(); + release_callback_impl = holder->GetCallbackForImplThread(); } - texture_layer->SetTextureMailbox(texture_mailbox, release_callback.Pass()); + texture_layer->SetTextureMailbox(texture_mailbox, + release_callback_impl.Pass()); needs_set_mailbox_ = false; } } @@ -279,12 +281,12 @@ TextureLayer::TextureMailboxHolder::MainThreadReference:: TextureLayer::TextureMailboxHolder::TextureMailboxHolder( const TextureMailbox& mailbox, scoped_ptr<SingleReleaseCallback> release_callback) - : message_loop_(BlockingTaskRunner::current()), - internal_references_(0), + : internal_references_(0), mailbox_(mailbox), release_callback_(release_callback.Pass()), sync_point_(mailbox.sync_point()), - is_lost_(false) {} + is_lost_(false) { +} TextureLayer::TextureMailboxHolder::~TextureMailboxHolder() { DCHECK_EQ(0u, internal_references_); @@ -305,13 +307,13 @@ void TextureLayer::TextureMailboxHolder::Return(uint32 sync_point, is_lost_ = is_lost; } -scoped_ptr<SingleReleaseCallback> +scoped_ptr<SingleReleaseCallbackImpl> TextureLayer::TextureMailboxHolder::GetCallbackForImplThread() { // We can't call GetCallbackForImplThread if we released the main thread // reference. DCHECK_GT(internal_references_, 0u); InternalAddRef(); - return SingleReleaseCallback::Create( + return SingleReleaseCallbackImpl::Create( base::Bind(&TextureMailboxHolder::ReturnAndReleaseOnImplThread, this)); } @@ -320,7 +322,7 @@ void TextureLayer::TextureMailboxHolder::InternalAddRef() { } void TextureLayer::TextureMailboxHolder::InternalRelease() { - DCHECK(message_loop_->BelongsToCurrentThread()); + DCHECK(main_thread_checker_.CalledOnValidThread()); if (!--internal_references_) { release_callback_->Run(sync_point_, is_lost_); mailbox_ = TextureMailbox(); @@ -330,9 +332,10 @@ void TextureLayer::TextureMailboxHolder::InternalRelease() { void TextureLayer::TextureMailboxHolder::ReturnAndReleaseOnImplThread( uint32 sync_point, - bool is_lost) { + bool is_lost, + BlockingTaskRunner* main_thread_task_runner) { Return(sync_point, is_lost); - message_loop_->PostTask( + main_thread_task_runner->PostTask( FROM_HERE, base::Bind(&TextureMailboxHolder::InternalRelease, this)); } diff --git a/cc/layers/texture_layer.h b/cc/layers/texture_layer.h index 2fa8ad9..22dcb4d 100644 --- a/cc/layers/texture_layer.h +++ b/cc/layers/texture_layer.h @@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/synchronization/lock.h" +#include "base/threading/thread_checker.h" #include "cc/base/cc_export.h" #include "cc/layers/layer.h" #include "cc/resources/texture_mailbox.h" @@ -16,6 +17,7 @@ namespace cc { class BlockingTaskRunner; class SingleReleaseCallback; +class SingleReleaseCallbackImpl; class TextureLayerClient; // A Layer containing a the rendered output of a plugin instance. @@ -40,7 +42,7 @@ class CC_EXPORT TextureLayer : public Layer { // Gets a ReleaseCallback that can be called from another thread. Note: the // caller must ensure the callback is called. - scoped_ptr<SingleReleaseCallback> GetCallbackForImplThread(); + scoped_ptr<SingleReleaseCallbackImpl> GetCallbackForImplThread(); protected: friend class TextureLayer; @@ -60,10 +62,10 @@ class CC_EXPORT TextureLayer : public Layer { void InternalAddRef(); void InternalRelease(); - void ReturnAndReleaseOnImplThread(uint32 sync_point, bool is_lost); - - // This member is thread safe, and is accessed on main and impl threads. - const scoped_refptr<BlockingTaskRunner> message_loop_; + void ReturnAndReleaseOnImplThread( + uint32 sync_point, + bool is_lost, + BlockingTaskRunner* main_thread_task_runner); // These members are only accessed on the main thread, or on the impl thread // during commit where the main thread is blocked. @@ -78,6 +80,7 @@ class CC_EXPORT TextureLayer : public Layer { base::Lock arguments_lock_; uint32 sync_point_; bool is_lost_; + base::ThreadChecker main_thread_checker_; DISALLOW_COPY_AND_ASSIGN(TextureMailboxHolder); }; diff --git a/cc/layers/texture_layer_impl.cc b/cc/layers/texture_layer_impl.cc index 80938ba..f7f78a6f7 100644 --- a/cc/layers/texture_layer_impl.cc +++ b/cc/layers/texture_layer_impl.cc @@ -11,7 +11,7 @@ #include "cc/quads/texture_draw_quad.h" #include "cc/resources/platform_color.h" #include "cc/resources/scoped_resource.h" -#include "cc/resources/single_release_callback.h" +#include "cc/resources/single_release_callback_impl.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/occlusion_tracker.h" @@ -37,7 +37,7 @@ TextureLayerImpl::~TextureLayerImpl() { FreeTextureMailbox(); } void TextureLayerImpl::SetTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback) { + scoped_ptr<SingleReleaseCallbackImpl> release_callback) { DCHECK_EQ(mailbox.IsValid(), !!release_callback); FreeTextureMailbox(); texture_mailbox_ = mailbox; @@ -240,8 +240,11 @@ const char* TextureLayerImpl::LayerTypeAsString() const { void TextureLayerImpl::FreeTextureMailbox() { if (own_mailbox_) { DCHECK(!external_texture_resource_); - if (release_callback_) - release_callback_->Run(texture_mailbox_.sync_point(), false); + if (release_callback_) { + release_callback_->Run(texture_mailbox_.sync_point(), + false, + layer_tree_impl()->BlockingMainThreadTaskRunner()); + } texture_mailbox_ = TextureMailbox(); release_callback_.reset(); } else if (external_texture_resource_) { diff --git a/cc/layers/texture_layer_impl.h b/cc/layers/texture_layer_impl.h index 241fde8..9edf099 100644 --- a/cc/layers/texture_layer_impl.h +++ b/cc/layers/texture_layer_impl.h @@ -12,7 +12,7 @@ #include "cc/layers/layer_impl.h" namespace cc { -class SingleReleaseCallback; +class SingleReleaseCallbackImpl; class ScopedResource; class CC_EXPORT TextureLayerImpl : public LayerImpl { @@ -49,8 +49,9 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl { // 0--3 void SetVertexOpacity(const float vertex_opacity[4]); - void SetTextureMailbox(const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback); + void SetTextureMailbox( + const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallbackImpl> release_callback); private: TextureLayerImpl(LayerTreeImpl* tree_impl, int id); @@ -69,7 +70,7 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl { scoped_ptr<ScopedResource> texture_copy_; TextureMailbox texture_mailbox_; - scoped_ptr<SingleReleaseCallback> release_callback_; + scoped_ptr<SingleReleaseCallbackImpl> release_callback_; bool own_mailbox_; bool valid_texture_copy_; diff --git a/cc/layers/texture_layer_impl_unittest.cc b/cc/layers/texture_layer_impl_unittest.cc index cd7cf75..5320fcc 100644 --- a/cc/layers/texture_layer_impl_unittest.cc +++ b/cc/layers/texture_layer_impl_unittest.cc @@ -12,7 +12,10 @@ namespace cc { namespace { -void IgnoreCallback(uint32 sync_point, bool lost) {} +void IgnoreCallback(uint32 sync_point, + bool lost, + BlockingTaskRunner* main_thread_task_runner) { +} TEST(TextureLayerImplTest, Occlusion) { gfx::Size layer_size(1000, 1000); @@ -32,7 +35,7 @@ TEST(TextureLayerImplTest, Occlusion) { texture_layer_impl->SetDrawsContent(true); texture_layer_impl->SetTextureMailbox( texture_mailbox, - SingleReleaseCallback::Create(base::Bind(&IgnoreCallback))); + SingleReleaseCallbackImpl::Create(base::Bind(&IgnoreCallback))); impl.CalcDrawProps(viewport_size); diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index 08309c7..feb7126 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc @@ -102,6 +102,16 @@ class MockMailboxCallback { void(base::SharedMemory* shared_memory, uint32 sync_point, bool lost_resource)); + MOCK_METHOD4(ReleaseImpl, + void(const gpu::Mailbox& mailbox, + uint32 sync_point, + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner)); + MOCK_METHOD4(ReleaseImpl2, + void(base::SharedMemory* shared_memory, + uint32 sync_point, + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner)); }; struct CommonMailboxObjects { @@ -117,6 +127,12 @@ struct CommonMailboxObjects { release_mailbox2_ = base::Bind(&MockMailboxCallback::Release, base::Unretained(&mock_callback_), mailbox_name2_); + release_mailbox1_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl, + base::Unretained(&mock_callback_), + mailbox_name1_); + release_mailbox2_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl, + base::Unretained(&mock_callback_), + mailbox_name2_); const uint32 arbitrary_target1 = GL_TEXTURE_2D; const uint32 arbitrary_target2 = GL_TEXTURE_EXTERNAL_OES; mailbox1_ = TextureMailbox(mailbox_name1_, arbitrary_target1, sync_point1_); @@ -126,6 +142,9 @@ struct CommonMailboxObjects { release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2, base::Unretained(&mock_callback_), shared_memory_.get()); + release_mailbox3_impl_ = base::Bind(&MockMailboxCallback::ReleaseImpl2, + base::Unretained(&mock_callback_), + shared_memory_.get()); mailbox3_ = TextureMailbox(shared_memory_.get(), size); } @@ -135,6 +154,9 @@ struct CommonMailboxObjects { ReleaseCallback release_mailbox1_; ReleaseCallback release_mailbox2_; ReleaseCallback release_mailbox3_; + ReleaseCallbackImpl release_mailbox1_impl_; + ReleaseCallbackImpl release_mailbox2_impl_; + ReleaseCallbackImpl release_mailbox3_impl_; TextureMailbox mailbox1_; TextureMailbox mailbox2_; TextureMailbox mailbox3_; @@ -377,6 +399,11 @@ class TextureLayerMailboxHolderTest : public TextureLayerTest { TextureLayerMailboxHolderTest() : main_thread_("MAIN") { main_thread_.Start(); + main_thread_.message_loop()->PostTask( + FROM_HERE, + base::Bind(&TextureLayerMailboxHolderTest::InitializeOnMain, + base::Unretained(this))); + Wait(main_thread_); } void Wait(const base::Thread& thread) { @@ -399,7 +426,7 @@ class TextureLayerMailboxHolderTest : public TextureLayerTest { main_ref_.reset(); } - void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) { + void CreateImplRef(scoped_ptr<SingleReleaseCallbackImpl>* impl_ref) { *impl_ref = main_ref_->holder()->GetCallbackForImplThread(); } @@ -407,15 +434,22 @@ class TextureLayerMailboxHolderTest : public TextureLayerTest { base::WaitableEvent* wait_for_capture, base::WaitableEvent* stop_capture) { begin_capture->Wait(); - BlockingTaskRunner::CapturePostTasks capture; + BlockingTaskRunner::CapturePostTasks capture( + main_thread_task_runner_.get()); wait_for_capture->Signal(); stop_capture->Wait(); } protected: + void InitializeOnMain() { + main_thread_task_runner_ = + BlockingTaskRunner::Create(main_thread_.message_loop_proxy()); + } + scoped_ptr<TestMailboxHolder::MainThreadReference> main_ref_; base::Thread main_thread_; + scoped_ptr<BlockingTaskRunner> main_thread_task_runner_; CommonMailboxObjects test_data_; }; @@ -432,7 +466,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - scoped_ptr<SingleReleaseCallback> compositor1; + scoped_ptr<SingleReleaseCallbackImpl> compositor1; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -441,7 +475,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) { // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - scoped_ptr<SingleReleaseCallback> compositor2; + scoped_ptr<SingleReleaseCallbackImpl> compositor2; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -453,8 +487,8 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) { // The compositors both destroy their impl trees before the main thread layer // is destroyed. - compositor1->Run(100, false); - compositor2->Run(200, false); + compositor1->Run(100, false, main_thread_task_runner_.get()); + compositor2->Run(200, false, main_thread_task_runner_.get()); Wait(main_thread_); @@ -487,7 +521,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - scoped_ptr<SingleReleaseCallback> compositor1; + scoped_ptr<SingleReleaseCallbackImpl> compositor1; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -496,7 +530,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) { // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - scoped_ptr<SingleReleaseCallback> compositor2; + scoped_ptr<SingleReleaseCallbackImpl> compositor2; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -507,7 +541,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) { Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); // One compositor destroys their impl tree. - compositor1->Run(100, false); + compositor1->Run(100, false, main_thread_task_runner_.get()); // Then the main thread reference is destroyed. main_thread_.message_loop()->PostTask( @@ -525,7 +559,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) { EXPECT_CALL(test_data_.mock_callback_, Release(test_data_.mailbox_name1_, 200, true)).Times(1); - compositor2->Run(200, true); + compositor2->Run(200, true, main_thread_task_runner_.get()); Wait(main_thread_); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); } @@ -543,7 +577,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - scoped_ptr<SingleReleaseCallback> compositor1; + scoped_ptr<SingleReleaseCallbackImpl> compositor1; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -552,7 +586,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) { // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - scoped_ptr<SingleReleaseCallback> compositor2; + scoped_ptr<SingleReleaseCallbackImpl> compositor2; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -569,7 +603,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) { base::Unretained(this))); // One compositor destroys their impl tree. - compositor2->Run(200, false); + compositor2->Run(200, false, main_thread_task_runner_.get()); Wait(main_thread_); @@ -581,7 +615,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) { EXPECT_CALL(test_data_.mock_callback_, Release(test_data_.mailbox_name1_, 100, true)).Times(1); - compositor1->Run(100, true); + compositor1->Run(100, true, main_thread_task_runner_.get()); Wait(main_thread_); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); } @@ -599,7 +633,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - scoped_ptr<SingleReleaseCallback> compositor1; + scoped_ptr<SingleReleaseCallbackImpl> compositor1; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -608,7 +642,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) { // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - scoped_ptr<SingleReleaseCallback> compositor2; + scoped_ptr<SingleReleaseCallbackImpl> compositor2; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -646,7 +680,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) { // Before the main thread capturing starts, one compositor destroys their // impl reference. Since capturing did not start, this gets post-tasked to // the main thread. - compositor1->Run(100, false); + compositor1->Run(100, false, main_thread_task_runner_.get()); // Start capturing on the main thread. begin_capture.Signal(); @@ -657,7 +691,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) { // released before compositor1, whose reference will be released later when // the post-task is serviced. But since it was destroyed _on the impl thread_ // last, its sync point values should be used. - compositor2->Run(200, true); + compositor2->Run(200, true, main_thread_task_runner_.get()); stop_capture.Signal(); Wait(main_thread_); @@ -917,13 +951,12 @@ class TextureLayerImplWithMailboxTest : public TextureLayerTest { // Test conditions for results of TextureLayerImpl::WillDraw under // different configurations of different mailbox, texture_id, and draw_mode. TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { - EXPECT_CALL(test_data_.mock_callback_, - Release(test_data_.mailbox_name1_, - test_data_.sync_point1_, - false)) + EXPECT_CALL( + test_data_.mock_callback_, + ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _)) .Times(AnyNumber()); EXPECT_CALL(test_data_.mock_callback_, - Release2(test_data_.shared_memory_.get(), 0, false)) + ReleaseImpl2(test_data_.shared_memory_.get(), 0, false, _)) .Times(AnyNumber()); // Hardware mode. { @@ -931,7 +964,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox1_, - SingleReleaseCallback::Create(test_data_.release_mailbox1_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_)); EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); } @@ -939,7 +972,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox(TextureMailbox(), - scoped_ptr<SingleReleaseCallback>()); + scoped_ptr<SingleReleaseCallbackImpl>()); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); } @@ -949,7 +982,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox3_, - SingleReleaseCallback::Create(test_data_.release_mailbox3_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_)); EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); } @@ -959,7 +992,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox1_, - SingleReleaseCallback::Create(test_data_.release_mailbox1_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_)); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); } @@ -967,7 +1000,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox(TextureMailbox(), - scoped_ptr<SingleReleaseCallback>()); + scoped_ptr<SingleReleaseCallbackImpl>()); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); } @@ -977,7 +1010,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox3_, - SingleReleaseCallback::Create(test_data_.release_mailbox3_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox3_impl_)); EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); } @@ -987,7 +1020,7 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { TextureLayerImpl::Create(host_impl_.active_tree(), 1); impl_layer->SetTextureMailbox( test_data_.mailbox1_, - SingleReleaseCallback::Create(test_data_.release_mailbox1_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_)); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE)); } } @@ -1004,55 +1037,51 @@ TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) { pending_layer->SetTextureMailbox( test_data_.mailbox1_, - SingleReleaseCallback::Create(test_data_.release_mailbox1_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_)); // Test multiple commits without an activation. - EXPECT_CALL(test_data_.mock_callback_, - Release(test_data_.mailbox_name1_, - test_data_.sync_point1_, - false)) + EXPECT_CALL( + test_data_.mock_callback_, + ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _)) .Times(1); pending_layer->SetTextureMailbox( test_data_.mailbox2_, - SingleReleaseCallback::Create(test_data_.release_mailbox2_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox2_impl_)); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); // Test callback after activation. pending_layer->PushPropertiesTo(active_layer.get()); active_layer->DidBecomeActive(); - EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0); + EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0); pending_layer->SetTextureMailbox( test_data_.mailbox1_, - SingleReleaseCallback::Create(test_data_.release_mailbox1_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_)); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); EXPECT_CALL(test_data_.mock_callback_, - Release(test_data_.mailbox_name2_, _, false)) - .Times(1); + ReleaseImpl(test_data_.mailbox_name2_, _, false, _)).Times(1); pending_layer->PushPropertiesTo(active_layer.get()); active_layer->DidBecomeActive(); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); // Test resetting the mailbox. EXPECT_CALL(test_data_.mock_callback_, - Release(test_data_.mailbox_name1_, _, false)) - .Times(1); + ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1); pending_layer->SetTextureMailbox(TextureMailbox(), - scoped_ptr<SingleReleaseCallback>()); + scoped_ptr<SingleReleaseCallbackImpl>()); pending_layer->PushPropertiesTo(active_layer.get()); active_layer->DidBecomeActive(); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); // Test destructor. - EXPECT_CALL(test_data_.mock_callback_, - Release(test_data_.mailbox_name1_, - test_data_.sync_point1_, - false)) + EXPECT_CALL( + test_data_.mock_callback_, + ReleaseImpl(test_data_.mailbox_name1_, test_data_.sync_point1_, false, _)) .Times(1); pending_layer->SetTextureMailbox( test_data_.mailbox1_, - SingleReleaseCallback::Create(test_data_.release_mailbox1_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_)); } TEST_F(TextureLayerImplWithMailboxTest, @@ -1062,25 +1091,23 @@ TEST_F(TextureLayerImplWithMailboxTest, ASSERT_TRUE(impl_layer); EXPECT_CALL(test_data_.mock_callback_, - Release(test_data_.mailbox_name1_, _, false)) - .Times(1); + ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1); impl_layer->SetTextureMailbox( test_data_.mailbox1_, - SingleReleaseCallback::Create(test_data_.release_mailbox1_)); + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_)); impl_layer->DidBecomeActive(); EXPECT_TRUE(impl_layer->WillDraw( DRAW_MODE_HARDWARE, host_impl_.active_tree()->resource_provider())); impl_layer->DidDraw(host_impl_.active_tree()->resource_provider()); impl_layer->SetTextureMailbox(TextureMailbox(), - scoped_ptr<SingleReleaseCallback>()); + scoped_ptr<SingleReleaseCallbackImpl>()); } TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) { ResourceProvider* provider = host_impl_.active_tree()->resource_provider(); - ResourceProvider::ResourceId id = - provider->CreateResourceFromTextureMailbox( - test_data_.mailbox1_, - SingleReleaseCallback::Create(test_data_.release_mailbox1_)); + ResourceProvider::ResourceId id = provider->CreateResourceFromTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallbackImpl::Create(test_data_.release_mailbox1_impl_)); provider->AllocateForTesting(id); // Transfer some resources to the parent. @@ -1089,12 +1116,11 @@ TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) { TransferableResourceArray list; provider->PrepareSendToParent(resource_ids_to_transfer, &list); EXPECT_TRUE(provider->InUseByConsumer(id)); - EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0); + EXPECT_CALL(test_data_.mock_callback_, ReleaseImpl(_, _, _, _)).Times(0); provider->DeleteResource(id); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); EXPECT_CALL(test_data_.mock_callback_, - Release(test_data_.mailbox_name1_, _, false)) - .Times(1); + ReleaseImpl(test_data_.mailbox_name1_, _, false, _)).Times(1); ReturnedResourceArray returned; TransferableResource::ReturnResources(list, &returned); provider->ReceiveReturnsFromParent(returned); diff --git a/cc/layers/tiled_layer_unittest.cc b/cc/layers/tiled_layer_unittest.cc index a52a5c7..8d7f7d8 100644 --- a/cc/layers/tiled_layer_unittest.cc +++ b/cc/layers/tiled_layer_unittest.cc @@ -122,9 +122,13 @@ class TiledLayerTest : public testing::Test { DebugScopedSetImplThreadAndMainThreadBlocked impl_thread_and_main_thread_blocked(proxy_); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false); host_impl_ = make_scoped_ptr( new FakeLayerTreeHostImpl(proxy_, shared_bitmap_manager_.get())); } diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc index fc04a26..819b542 100644 --- a/cc/layers/video_layer_impl.cc +++ b/cc/layers/video_layer_impl.cc @@ -12,7 +12,7 @@ #include "cc/quads/texture_draw_quad.h" #include "cc/quads/yuv_video_draw_quad.h" #include "cc/resources/resource_provider.h" -#include "cc/resources/single_release_callback.h" +#include "cc/resources/single_release_callback_impl.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/occlusion_tracker.h" #include "cc/trees/proxy.h" @@ -122,7 +122,8 @@ bool VideoLayerImpl::WillDraw(DrawMode draw_mode, for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) { unsigned resource_id = resource_provider->CreateResourceFromTextureMailbox( external_resources.mailboxes[i], - SingleReleaseCallback::Create(external_resources.release_callbacks[i])); + SingleReleaseCallbackImpl::Create( + external_resources.release_callbacks[i])); frame_resources_.push_back(resource_id); } @@ -336,8 +337,10 @@ void VideoLayerImpl::DidDraw(ResourceProvider* resource_provider) { if (frame_resource_type_ == VideoFrameExternalResources::SOFTWARE_RESOURCE) { - for (size_t i = 0; i < software_resources_.size(); ++i) - software_release_callback_.Run(0, false); + for (size_t i = 0; i < software_resources_.size(); ++i) { + software_release_callback_.Run( + 0, false, layer_tree_impl()->BlockingMainThreadTaskRunner()); + } software_resources_.clear(); software_release_callback_.Reset(); diff --git a/cc/layers/video_layer_impl.h b/cc/layers/video_layer_impl.h index d2e0fe3..34f013a 100644 --- a/cc/layers/video_layer_impl.h +++ b/cc/layers/video_layer_impl.h @@ -9,7 +9,7 @@ #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" -#include "cc/resources/release_callback.h" +#include "cc/resources/release_callback_impl.h" #include "cc/resources/video_resource_updater.h" #include "media/base/video_rotation.h" @@ -70,7 +70,7 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl { // ExternalResource (aka TextureMailbox) classes. std::vector<unsigned> software_resources_; // Called once for each software resource. - ReleaseCallback software_release_callback_; + ReleaseCallbackImpl software_release_callback_; DISALLOW_COPY_AND_ASSIGN(VideoLayerImpl); }; diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc index 41fa60e..4befaf5 100644 --- a/cc/output/gl_renderer_unittest.cc +++ b/cc/output/gl_renderer_unittest.cc @@ -153,10 +153,13 @@ class GLRendererWithDefaultHarnessTest : public GLRendererTest { CHECK(output_surface_->BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = - ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false).Pass(); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false).Pass(); renderer_ = make_scoped_ptr(new FakeRendererGL(&renderer_client_, &settings_, output_surface_.get(), @@ -186,10 +189,13 @@ class GLRendererShaderTest : public GLRendererTest { CHECK(output_surface_->BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = - ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false).Pass(); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false).Pass(); renderer_.reset(new FakeRendererGL(&renderer_client_, &settings_, output_surface_.get(), @@ -475,8 +481,14 @@ TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -511,8 +523,14 @@ TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -544,8 +562,14 @@ TEST_F(GLRendererTest, OpaqueBackground) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -590,8 +614,14 @@ TEST_F(GLRendererTest, TransparentBackground) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -629,8 +659,14 @@ TEST_F(GLRendererTest, OffscreenOutputSurface) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -710,8 +746,14 @@ TEST_F(GLRendererTest, VisibilityChangeIsLastCall) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -775,8 +817,14 @@ TEST_F(GLRendererTest, ActiveTextureState) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -860,8 +908,14 @@ TEST_F(GLRendererTest, ShouldClearRootRenderPass) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; settings.should_clear_root_render_pass = false; @@ -952,8 +1006,14 @@ TEST_F(GLRendererTest, ScissorTestWhenClearing) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -1045,8 +1105,14 @@ TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; settings.partial_swap_enabled = true; @@ -1230,8 +1296,14 @@ TEST_F(GLRendererTest, ScissorAndViewportWithinNonreshapableSurface) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); LayerTreeSettings settings; FakeRendererClient renderer_client; @@ -1604,10 +1676,13 @@ class MockOutputSurfaceTest : public GLRendererTest { CHECK(output_surface_.BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = - ResourceProvider::Create( - &output_surface_, shared_bitmap_manager_.get(), 0, false, 1, false) - .Pass(); + resource_provider_ = ResourceProvider::Create(&output_surface_, + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false).Pass(); renderer_.reset(new FakeRendererGL(&renderer_client_, &settings_, diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc index 0e28b22..d805ae4 100644 --- a/cc/output/overlay_unittest.cc +++ b/cc/output/overlay_unittest.cc @@ -33,7 +33,10 @@ const gfx::Rect kOverlayBottomRightRect(64, 64, 64, 64); const gfx::PointF kUVTopLeft(0.1f, 0.2f); const gfx::PointF kUVBottomRight(1.0f, 1.0f); -void MailboxReleased(unsigned sync_point, bool lost_resource) {} +void MailboxReleased(unsigned sync_point, + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner) { +} class SingleOverlayValidator : public OverlayCandidateValidator { public: @@ -127,8 +130,8 @@ ResourceProvider::ResourceId CreateResource( TextureMailbox mailbox = TextureMailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point); mailbox.set_allow_overlay(true); - scoped_ptr<SingleReleaseCallback> release_callback = - SingleReleaseCallback::Create(base::Bind(&MailboxReleased)); + scoped_ptr<SingleReleaseCallbackImpl> release_callback = + SingleReleaseCallbackImpl::Create(base::Bind(&MailboxReleased)); return resource_provider->CreateResourceFromTextureMailbox( mailbox, release_callback.Pass()); @@ -233,7 +236,7 @@ TEST(OverlayTest, OverlaysProcessorHasStrategy) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - &output_surface, shared_bitmap_manager.get(), 0, false, 1, false)); + &output_surface, shared_bitmap_manager.get(), NULL, 0, false, 1, false)); scoped_ptr<DefaultOverlayProcessor> overlay_processor( new DefaultOverlayProcessor(&output_surface, resource_provider.get())); @@ -251,9 +254,13 @@ class SingleOverlayOnTopTest : public testing::Test { EXPECT_TRUE(output_surface_->overlay_candidate_validator() != NULL); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false); overlay_processor_.reset(new SingleOverlayProcessor( output_surface_.get(), resource_provider_.get())); @@ -563,9 +570,8 @@ class GLRendererWithOverlaysTest : public testing::Test { provider_ = TestContextProvider::Create(); output_surface_.reset(new OverlayOutputSurface(provider_)); CHECK(output_surface_->BindToClient(&output_surface_client_)); - resource_provider_ = - ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1, - false); + resource_provider_ = ResourceProvider::Create( + output_surface_.get(), NULL, NULL, 0, false, 1, false); provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind( &MockOverlayScheduler::Schedule, base::Unretained(&scheduler_))); diff --git a/cc/output/renderer_pixeltest.cc b/cc/output/renderer_pixeltest.cc index 70c68fe..f53d664 100644 --- a/cc/output/renderer_pixeltest.cc +++ b/cc/output/renderer_pixeltest.cc @@ -499,23 +499,23 @@ class VideoGLRendererPixelTest : public GLRendererPixelTest { ResourceProvider::ResourceId y_resource = resource_provider_->CreateResourceFromTextureMailbox( resources.mailboxes[media::VideoFrame::kYPlane], - SingleReleaseCallback::Create( + SingleReleaseCallbackImpl::Create( resources.release_callbacks[media::VideoFrame::kYPlane])); ResourceProvider::ResourceId u_resource = resource_provider_->CreateResourceFromTextureMailbox( resources.mailboxes[media::VideoFrame::kUPlane], - SingleReleaseCallback::Create( + SingleReleaseCallbackImpl::Create( resources.release_callbacks[media::VideoFrame::kUPlane])); ResourceProvider::ResourceId v_resource = resource_provider_->CreateResourceFromTextureMailbox( resources.mailboxes[media::VideoFrame::kVPlane], - SingleReleaseCallback::Create( + SingleReleaseCallbackImpl::Create( resources.release_callbacks[media::VideoFrame::kVPlane])); ResourceProvider::ResourceId a_resource = 0; if (with_alpha) { a_resource = resource_provider_->CreateResourceFromTextureMailbox( resources.mailboxes[media::VideoFrame::kAPlane], - SingleReleaseCallback::Create( + SingleReleaseCallbackImpl::Create( resources.release_callbacks[media::VideoFrame::kAPlane])); } diff --git a/cc/output/renderer_unittest.cc b/cc/output/renderer_unittest.cc index b225dd3..1d54608 100644 --- a/cc/output/renderer_unittest.cc +++ b/cc/output/renderer_unittest.cc @@ -61,9 +61,8 @@ class RendererTest : public ::testing::Test { new MockContextProvider(TestWebGraphicsContext3D::Create()); output_surface_.reset(new OutputSurface(context_provider_)); output_surface_->BindToClient(&output_surface_client_); - resource_provider_ = - ResourceProvider::Create(output_surface_.get(), NULL, 0, false, 1, - false); + resource_provider_ = ResourceProvider::Create( + output_surface_.get(), NULL, NULL, 0, false, 1, false); renderer_ = CreateRenderer<T>(&renderer_client_, &tree_settings_, output_surface_.get(), diff --git a/cc/output/software_renderer_unittest.cc b/cc/output/software_renderer_unittest.cc index bcade58..ad88709 100644 --- a/cc/output/software_renderer_unittest.cc +++ b/cc/output/software_renderer_unittest.cc @@ -36,9 +36,13 @@ class SoftwareRendererTest : public testing::Test, public RendererClient { CHECK(output_surface_->BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false); renderer_ = SoftwareRenderer::Create( this, &settings_, output_surface_.get(), resource_provider()); } diff --git a/cc/resources/picture_layer_tiling_perftest.cc b/cc/resources/picture_layer_tiling_perftest.cc index 69bb01e..00338ab 100644 --- a/cc/resources/picture_layer_tiling_perftest.cc +++ b/cc/resources/picture_layer_tiling_perftest.cc @@ -36,6 +36,7 @@ class PictureLayerTilingPerfTest : public testing::Test { shared_bitmap_manager_.reset(new TestSharedBitmapManager()); resource_provider_ = ResourceProvider::Create(output_surface_.get(), shared_bitmap_manager_.get(), + NULL, 0, false, 1, diff --git a/cc/resources/picture_layer_tiling_set_unittest.cc b/cc/resources/picture_layer_tiling_set_unittest.cc index ca75751..e566d11 100644 --- a/cc/resources/picture_layer_tiling_set_unittest.cc +++ b/cc/resources/picture_layer_tiling_set_unittest.cc @@ -202,8 +202,14 @@ class PictureLayerTilingSetTestWithResources : public testing::Test { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false); + scoped_ptr<ResourceProvider> resource_provider = + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false); FakePictureLayerTilingClient client(resource_provider.get()); client.SetTileSize(gfx::Size(256, 256)); diff --git a/cc/resources/picture_layer_tiling_unittest.cc b/cc/resources/picture_layer_tiling_unittest.cc index 29891d0..990cdd4 100644 --- a/cc/resources/picture_layer_tiling_unittest.cc +++ b/cc/resources/picture_layer_tiling_unittest.cc @@ -1256,7 +1256,7 @@ TEST(PictureLayerTilingTest, TilingEvictionTileIteratorStaticViewport) { CHECK(output_surface->BindToClient(&output_surface_client)); TestSharedBitmapManager shared_bitmap_manager; scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create( - output_surface.get(), &shared_bitmap_manager, 0, false, 1, false); + output_surface.get(), &shared_bitmap_manager, NULL, 0, false, 1, false); FakePictureLayerTilingClient client(resource_provider.get()); scoped_ptr<TestablePictureLayerTiling> tiling; diff --git a/cc/resources/prioritized_resource_unittest.cc b/cc/resources/prioritized_resource_unittest.cc index 14eb317..68d81a2 100644 --- a/cc/resources/prioritized_resource_unittest.cc +++ b/cc/resources/prioritized_resource_unittest.cc @@ -28,9 +28,13 @@ class PrioritizedResourceTest : public testing::Test { DebugScopedSetImplThread impl_thread(&proxy_); CHECK(output_surface_->BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false); } virtual ~PrioritizedResourceTest() { diff --git a/cc/resources/prioritized_tile_set_unittest.cc b/cc/resources/prioritized_tile_set_unittest.cc index f744d60..cb726b7 100644 --- a/cc/resources/prioritized_tile_set_unittest.cc +++ b/cc/resources/prioritized_tile_set_unittest.cc @@ -55,11 +55,13 @@ class PrioritizedTileSetTest : public testing::Test { CHECK(output_surface_->BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = - ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false) - .Pass(); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false).Pass(); resource_pool_ = ResourcePool::Create( resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888); tile_manager_.reset( diff --git a/cc/resources/raster_worker_pool_perftest.cc b/cc/resources/raster_worker_pool_perftest.cc index dd13843..436615c 100644 --- a/cc/resources/raster_worker_pool_perftest.cc +++ b/cc/resources/raster_worker_pool_perftest.cc @@ -158,10 +158,13 @@ class RasterWorkerPoolPerfTestBase { CHECK(output_surface_->BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = - ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false).Pass(); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false).Pass(); staging_resource_pool_ = ResourcePool::Create( resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888); } diff --git a/cc/resources/raster_worker_pool_unittest.cc b/cc/resources/raster_worker_pool_unittest.cc index e272eb7..172d087 100644 --- a/cc/resources/raster_worker_pool_unittest.cc +++ b/cc/resources/raster_worker_pool_unittest.cc @@ -117,10 +117,13 @@ class RasterWorkerPoolTest CHECK(output_surface_->BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = - ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false).Pass(); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false).Pass(); staging_resource_pool_ = ResourcePool::Create( resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888); diff --git a/cc/resources/release_callback_impl.h b/cc/resources/release_callback_impl.h new file mode 100644 index 0000000..89f22b6 --- /dev/null +++ b/cc/resources/release_callback_impl.h @@ -0,0 +1,20 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_RESOURCES_RELEASE_CALLBACK_IMPL_H_ +#define CC_RESOURCES_RELEASE_CALLBACK_IMPL_H_ + +#include "base/callback.h" + +namespace cc { +class BlockingTaskRunner; + +typedef base::Callback<void(uint32 sync_point, + bool is_lost, + BlockingTaskRunner* main_thread_task_runner)> + ReleaseCallbackImpl; + +} // namespace cc + +#endif // CC_RESOURCES_RELEASE_CALLBACK_IMPL_H_ diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 1b2cad6..a5dd320 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -601,6 +601,7 @@ ResourceProvider::Child::~Child() {} scoped_ptr<ResourceProvider> ResourceProvider::Create( OutputSurface* output_surface, SharedBitmapManager* shared_bitmap_manager, + BlockingTaskRunner* blocking_main_thread_task_runner, int highp_threshold_min, bool use_rgba_4444_texture_format, size_t id_allocation_chunk_size, @@ -608,6 +609,7 @@ scoped_ptr<ResourceProvider> ResourceProvider::Create( scoped_ptr<ResourceProvider> resource_provider( new ResourceProvider(output_surface, shared_bitmap_manager, + blocking_main_thread_task_runner, highp_threshold_min, use_rgba_4444_texture_format, id_allocation_chunk_size, @@ -777,7 +779,7 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromIOSurface( ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback) { + scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl) { DCHECK(thread_checker_.CalledOnValidThread()); // Just store the information. Mailbox will be consumed in LockForRead(). ResourceId id = next_id_++; @@ -813,9 +815,9 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox( } resource.allocated = true; resource.mailbox = mailbox; - resource.release_callback = - base::Bind(&SingleReleaseCallback::Run, - base::Owned(release_callback.release())); + resource.release_callback_impl = + base::Bind(&SingleReleaseCallbackImpl::Run, + base::Owned(release_callback_impl.release())); resource.allow_overlay = mailbox.allow_overlay(); return id; } @@ -899,7 +901,8 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, resource->shared_bitmap = NULL; } } - resource->release_callback.Run(sync_point, lost_resource); + resource->release_callback_impl.Run( + sync_point, lost_resource, blocking_main_thread_task_runner_); } if (resource->gl_id) { GLES2Interface* gl = ContextGL(); @@ -1226,14 +1229,17 @@ ResourceProvider::ScopedWriteLockSoftware::~ScopedWriteLockSoftware() { resource_provider_->UnlockForWrite(resource_id_); } -ResourceProvider::ResourceProvider(OutputSurface* output_surface, - SharedBitmapManager* shared_bitmap_manager, - int highp_threshold_min, - bool use_rgba_4444_texture_format, - size_t id_allocation_chunk_size, - bool use_distance_field_text) +ResourceProvider::ResourceProvider( + OutputSurface* output_surface, + SharedBitmapManager* shared_bitmap_manager, + BlockingTaskRunner* blocking_main_thread_task_runner, + int highp_threshold_min, + bool use_rgba_4444_texture_format, + size_t id_allocation_chunk_size, + bool use_distance_field_text) : output_surface_(output_surface), shared_bitmap_manager_(shared_bitmap_manager), + blocking_main_thread_task_runner_(blocking_main_thread_task_runner), lost_output_surface_(false), highp_threshold_min_(highp_threshold_min), next_id_(1), @@ -1421,7 +1427,8 @@ void ResourceProvider::ReceiveFromChild( TRACE_EVENT0("cc", "ResourceProvider::ReceiveFromChild dropping invalid"); ReturnedResourceArray to_return; to_return.push_back(it->ToReturnedResource()); - child_info.return_callback.Run(to_return); + child_info.return_callback.Run(to_return, + blocking_main_thread_task_runner_); continue; } @@ -1736,7 +1743,8 @@ void ResourceProvider::DeleteAndReturnUnusedResourcesToChild( } if (!to_return.empty()) - child_info->return_callback.Run(to_return); + child_info->return_callback.Run(to_return, + blocking_main_thread_task_runner_); if (child_info->marked_for_deletion && child_info->parent_to_child_map.empty()) { diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index b6c560d..3295aee 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h @@ -21,11 +21,11 @@ #include "cc/output/context_provider.h" #include "cc/output/output_surface.h" #include "cc/resources/raster_buffer.h" -#include "cc/resources/release_callback.h" +#include "cc/resources/release_callback_impl.h" #include "cc/resources/resource_format.h" #include "cc/resources/return_callback.h" #include "cc/resources/shared_bitmap.h" -#include "cc/resources/single_release_callback.h" +#include "cc/resources/single_release_callback_impl.h" #include "cc/resources/texture_mailbox.h" #include "cc/resources/transferable_resource.h" #include "third_party/khronos/GLES2/gl2.h" @@ -48,6 +48,7 @@ class Vector2d; } namespace cc { +class BlockingTaskRunner; class IdAllocator; class SharedBitmap; class SharedBitmapManager; @@ -77,6 +78,7 @@ class CC_EXPORT ResourceProvider { static scoped_ptr<ResourceProvider> Create( OutputSurface* output_surface, SharedBitmapManager* shared_bitmap_manager, + BlockingTaskRunner* blocking_main_thread_task_runner, int highp_threshold_min, bool use_rgba_4444_texture_format, size_t id_allocation_chunk_size, @@ -137,7 +139,7 @@ class CC_EXPORT ResourceProvider { // Wraps an external texture mailbox into a GL resource. ResourceId CreateResourceFromTextureMailbox( const TextureMailbox& mailbox, - scoped_ptr<SingleReleaseCallback> release_callback); + scoped_ptr<SingleReleaseCallbackImpl> release_callback_impl); void DeleteResource(ResourceId id); @@ -412,7 +414,7 @@ class CC_EXPORT ResourceProvider { // Query used to determine when read lock fence has passed. unsigned gl_read_lock_query_id; TextureMailbox mailbox; - ReleaseCallback release_callback; + ReleaseCallbackImpl release_callback_impl; uint8_t* pixels; int lock_for_read_count; int imported_count; @@ -536,6 +538,7 @@ class CC_EXPORT ResourceProvider { ResourceProvider(OutputSurface* output_surface, SharedBitmapManager* shared_bitmap_manager, + BlockingTaskRunner* blocking_main_thread_task_runner, int highp_threshold_min, bool use_rgba_4444_texture_format, size_t id_allocation_chunk_size, @@ -599,6 +602,7 @@ class CC_EXPORT ResourceProvider { OutputSurface* output_surface_; SharedBitmapManager* shared_bitmap_manager_; + BlockingTaskRunner* blocking_main_thread_task_runner_; bool lost_output_surface_; int highp_threshold_min_; ResourceId next_id_; diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index 6e0aaf3..e10e01c 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc @@ -22,6 +22,7 @@ #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_texture.h" #include "cc/test/test_web_graphics_context_3d.h" +#include "cc/trees/blocking_task_runner.h" #include "gpu/GLES2/gl2extchromium.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -39,18 +40,28 @@ using testing::_; namespace cc { namespace { -static void EmptyReleaseCallback(uint32 sync_point, bool lost_resource) {} - -static void SharedMemoryReleaseCallback(scoped_ptr<base::SharedMemory> memory, - uint32 sync_point, - bool lost_resource) {} +static void EmptyReleaseCallback(uint32 sync_point, + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner) { +} -static void ReleaseTextureMailbox(uint32* release_sync_point, - bool* release_lost_resource, - uint32 sync_point, - bool lost_resource) { +static void ReleaseCallback( + uint32* release_sync_point, + bool* release_lost_resource, + BlockingTaskRunner** release_main_thread_task_runner, + uint32 sync_point, + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner) { *release_sync_point = sync_point; *release_lost_resource = lost_resource; + *release_main_thread_task_runner = main_thread_task_runner; +} + +static void SharedMemoryReleaseCallback( + scoped_ptr<base::SharedMemory> memory, + uint32 sync_point, + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner) { } static void ReleaseSharedMemoryCallback( @@ -59,7 +70,8 @@ static void ReleaseSharedMemoryCallback( uint32* release_sync_point, bool* lost_resource_result, uint32 sync_point, - bool lost_resource) { + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner) { *release_called = true; *release_sync_point = sync_point; *lost_resource_result = lost_resource; @@ -368,7 +380,8 @@ class ResourceProviderTest ResourceProviderTest() : shared_data_(ContextSharedData::Create()), context3d_(NULL), - child_context_(NULL) { + child_context_(NULL), + main_thread_task_runner_(BlockingTaskRunner::Create(NULL)) { switch (GetParam()) { case ResourceProvider::GLTexture: { scoped_ptr<ResourceProviderContext> context3d( @@ -403,20 +416,27 @@ class ResourceProviderTest shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); - child_resource_provider_ = ResourceProvider::Create( - child_output_surface_.get(), - shared_bitmap_manager_.get(), - 0, - false, - 1, - false); + resource_provider_ = + ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + main_thread_task_runner_.get(), + 0, + false, + 1, + false); + child_resource_provider_ = + ResourceProvider::Create(child_output_surface_.get(), + shared_bitmap_manager_.get(), + main_thread_task_runner_.get(), + 0, + false, + 1, + false); } static void CollectResources(ReturnedResourceArray* array, - const ReturnedResourceArray& returned) { + const ReturnedResourceArray& returned, + BlockingTaskRunner* main_thread_task_runner) { array->insert(array->end(), returned.begin(), returned.end()); } @@ -447,12 +467,13 @@ class ResourceProviderTest EXPECT_LT(0u, *sync_point); scoped_ptr<base::SharedMemory> shared_memory; - scoped_ptr<SingleReleaseCallback> callback = - SingleReleaseCallback::Create(base::Bind(ReleaseSharedMemoryCallback, - base::Passed(&shared_memory), - release_called, - release_sync_point, - lost_resource)); + scoped_ptr<SingleReleaseCallbackImpl> callback = + SingleReleaseCallbackImpl::Create( + base::Bind(ReleaseSharedMemoryCallback, + base::Passed(&shared_memory), + release_called, + release_sync_point, + lost_resource)); return child_resource_provider_->CreateResourceFromTextureMailbox( TextureMailbox(gpu_mailbox, GL_TEXTURE_2D, *sync_point), callback.Pass()); @@ -462,12 +483,13 @@ class ResourceProviderTest CreateAndFillSharedMemory(size, 0)); base::SharedMemory* shared_memory_ptr = shared_memory.get(); - scoped_ptr<SingleReleaseCallback> callback = - SingleReleaseCallback::Create(base::Bind(ReleaseSharedMemoryCallback, - base::Passed(&shared_memory), - release_called, - release_sync_point, - lost_resource)); + scoped_ptr<SingleReleaseCallbackImpl> callback = + SingleReleaseCallbackImpl::Create( + base::Bind(ReleaseSharedMemoryCallback, + base::Passed(&shared_memory), + release_called, + release_sync_point, + lost_resource)); return child_resource_provider_->CreateResourceFromTextureMailbox( TextureMailbox(shared_memory_ptr, size), callback.Pass()); } @@ -481,6 +503,7 @@ class ResourceProviderTest FakeOutputSurfaceClient child_output_surface_client_; scoped_ptr<OutputSurface> output_surface_; scoped_ptr<OutputSurface> child_output_surface_; + scoped_ptr<BlockingTaskRunner> main_thread_task_runner_; scoped_ptr<ResourceProvider> resource_provider_; scoped_ptr<ResourceProvider> child_resource_provider_; scoped_ptr<TestSharedBitmapManager> shared_bitmap_manager_; @@ -625,7 +648,7 @@ TEST_P(ResourceProviderTest, TransferGLResources) { child_resource_provider_->CreateResourceFromTextureMailbox( TextureMailbox( external_mailbox, GL_TEXTURE_EXTERNAL_OES, external_sync_point), - SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback))); + SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback))); ReturnedResourceArray returned_to_child; int child_id = @@ -892,16 +915,16 @@ TEST_P(ResourceProviderTest, AllowOverlayTransfersToParent) { uint32 sync_point = 0; TextureMailbox mailbox(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point); mailbox.set_allow_overlay(true); - scoped_ptr<SingleReleaseCallback> release_callback = - SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback)); + scoped_ptr<SingleReleaseCallbackImpl> release_callback = + SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)); ResourceProvider::ResourceId id1 = child_resource_provider_->CreateResourceFromTextureMailbox( mailbox, release_callback.Pass()); TextureMailbox mailbox2(gpu::Mailbox::Generate(), GL_TEXTURE_2D, sync_point); mailbox2.set_allow_overlay(false); - scoped_ptr<SingleReleaseCallback> release_callback2 = - SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback)); + scoped_ptr<SingleReleaseCallbackImpl> release_callback2 = + SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)); ResourceProvider::ResourceId id2 = child_resource_provider_->CreateResourceFromTextureMailbox( mailbox2, release_callback2.Pass()); @@ -973,7 +996,7 @@ TEST_P(ResourceProviderTest, TransferSoftwareResources) { ResourceProvider::ResourceId id4 = child_resource_provider_->CreateResourceFromTextureMailbox( TextureMailbox(shared_memory_ptr, gfx::Size(1, 1)), - SingleReleaseCallback::Create(base::Bind( + SingleReleaseCallbackImpl::Create(base::Bind( &SharedMemoryReleaseCallback, base::Passed(&shared_memory)))); ReturnedResourceArray returned_to_child; @@ -1175,9 +1198,14 @@ TEST_P(ResourceProviderTest, TransferGLToSoftware) { child_context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(child_output_surface->BindToClient(&child_output_surface_client)); - scoped_ptr<ResourceProvider> child_resource_provider(ResourceProvider::Create( - child_output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, - false)); + scoped_ptr<ResourceProvider> child_resource_provider( + ResourceProvider::Create(child_output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -1655,6 +1683,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest { scoped_ptr<ResourceProvider> child_resource_provider( ResourceProvider::Create(child_output_surface.get(), shared_bitmap_manager.get(), + NULL, 0, false, 1, @@ -1672,6 +1701,7 @@ class ResourceProviderTestTextureFilters : public ResourceProviderTest { scoped_ptr<ResourceProvider> parent_resource_provider( ResourceProvider::Create(parent_output_surface.get(), shared_bitmap_manager.get(), + NULL, 0, false, 1, @@ -1842,12 +1872,15 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) { uint32 release_sync_point = 0; bool lost_resource = false; - ReleaseCallback callback = - base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource); + BlockingTaskRunner* main_thread_task_runner = NULL; + ReleaseCallbackImpl callback = base::Bind(ReleaseCallback, + &release_sync_point, + &lost_resource, + &main_thread_task_runner); ResourceProvider::ResourceId resource = resource_provider_->CreateResourceFromTextureMailbox( TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point), - SingleReleaseCallback::Create(callback)); + SingleReleaseCallbackImpl::Create(callback)); EXPECT_EQ(1u, context()->NumTextures()); EXPECT_EQ(0u, release_sync_point); { @@ -1888,6 +1921,7 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) { resource_provider_->DeleteResource(resource); EXPECT_LE(list[0].mailbox_holder.sync_point, release_sync_point); EXPECT_FALSE(lost_resource); + EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner); } // We're going to do the same thing as above, but testing the case where we @@ -1897,7 +1931,7 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) { release_sync_point = 0; resource = resource_provider_->CreateResourceFromTextureMailbox( TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point), - SingleReleaseCallback::Create(callback)); + SingleReleaseCallbackImpl::Create(callback)); EXPECT_EQ(1u, context()->NumTextures()); EXPECT_EQ(0u, release_sync_point); { @@ -1939,6 +1973,7 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) { resource_provider_->ReceiveReturnsFromParent(returned); EXPECT_LE(list[0].mailbox_holder.sync_point, release_sync_point); EXPECT_FALSE(lost_resource); + EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner); } context()->waitSyncPoint(release_sync_point); @@ -2260,19 +2295,25 @@ TEST_P(ResourceProviderTest, LostContext) { uint32 release_sync_point = 0; bool lost_resource = false; - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource)); + BlockingTaskRunner* main_thread_task_runner = NULL; + scoped_ptr<SingleReleaseCallbackImpl> callback = + SingleReleaseCallbackImpl::Create(base::Bind(ReleaseCallback, + &release_sync_point, + &lost_resource, + &main_thread_task_runner)); resource_provider_->CreateResourceFromTextureMailbox( TextureMailbox(mailbox, GL_TEXTURE_2D, sync_point), callback.Pass()); EXPECT_EQ(0u, release_sync_point); EXPECT_FALSE(lost_resource); + EXPECT_EQ(NULL, main_thread_task_runner); resource_provider_->DidLoseOutputSurface(); resource_provider_.reset(); EXPECT_LE(sync_point, release_sync_point); EXPECT_TRUE(lost_resource); + EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner); } TEST_P(ResourceProviderTest, ScopedSampler) { @@ -2289,8 +2330,14 @@ TEST_P(ResourceProviderTest, ScopedSampler) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -2370,8 +2417,14 @@ TEST_P(ResourceProviderTest, ManagedResource) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -2419,8 +2472,14 @@ TEST_P(ResourceProviderTest, TextureWrapMode) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -2472,8 +2531,14 @@ TEST_P(ResourceProviderTest, TextureHint) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); gfx::Size size(1, 1); ResourceFormat format = RGBA_8888; @@ -2539,11 +2604,23 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) { new SoftwareOutputDevice))); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + main_thread_task_runner_.get(), + 0, + false, + 1, + false)); - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind(&EmptyReleaseCallback)); + uint32 release_sync_point = 0; + bool lost_resource = false; + BlockingTaskRunner* main_thread_task_runner = NULL; + scoped_ptr<SingleReleaseCallbackImpl> callback = + SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback, + &release_sync_point, + &lost_resource, + &main_thread_task_runner)); TextureMailbox mailbox(shared_memory.get(), size); ResourceProvider::ResourceId id = @@ -2558,6 +2635,11 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) { EXPECT_EQ(sk_bitmap->height(), size.height()); EXPECT_EQ(*sk_bitmap->getAddr32(16, 16), kBadBeef); } + + resource_provider->DeleteResource(id); + EXPECT_EQ(0u, release_sync_point); + EXPECT_FALSE(lost_resource); + EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner); } TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D) { @@ -2574,8 +2656,14 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + main_thread_task_runner_.get(), + 0, + false, + 1, + false)); unsigned texture_id = 1; uint32 sync_point = 30; @@ -2589,8 +2677,14 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D) { gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind(&EmptyReleaseCallback)); + uint32 release_sync_point = 0; + bool lost_resource = false; + BlockingTaskRunner* main_thread_task_runner = NULL; + scoped_ptr<SingleReleaseCallbackImpl> callback = + SingleReleaseCallbackImpl::Create(base::Bind(&ReleaseCallback, + &release_sync_point, + &lost_resource, + &main_thread_task_runner)); TextureMailbox mailbox(gpu_mailbox, target, sync_point); @@ -2626,6 +2720,11 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D) { EXPECT_CALL(*context, waitSyncPoint(_)).Times(0); EXPECT_CALL(*context, consumeTextureCHROMIUM(_, _)).Times(0); } + + resource_provider->DeleteResource(id); + EXPECT_EQ(0u, release_sync_point); + EXPECT_FALSE(lost_resource); + EXPECT_EQ(main_thread_task_runner_.get(), main_thread_task_runner); } TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) { @@ -2642,8 +2741,14 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); unsigned texture_id = 1; uint32 sync_point = 30; @@ -2657,8 +2762,8 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) { gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( - base::Bind(&EmptyReleaseCallback)); + scoped_ptr<SingleReleaseCallbackImpl> callback = + SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)); TextureMailbox mailbox(gpu_mailbox, target, sync_point); @@ -2711,8 +2816,14 @@ TEST_P(ResourceProviderTest, context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); uint32 sync_point = 30; unsigned target = GL_TEXTURE_2D; @@ -2725,8 +2836,8 @@ TEST_P(ResourceProviderTest, gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - scoped_ptr<SingleReleaseCallback> callback = - SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback)); + scoped_ptr<SingleReleaseCallbackImpl> callback = + SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)); TextureMailbox mailbox(gpu_mailbox, target, sync_point); @@ -2764,8 +2875,14 @@ TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncPointIfNeeded_NoSyncPoint) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); uint32 sync_point = 0; unsigned target = GL_TEXTURE_2D; @@ -2778,8 +2895,8 @@ TEST_P(ResourceProviderTest, TextureMailbox_WaitSyncPointIfNeeded_NoSyncPoint) { gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - scoped_ptr<SingleReleaseCallback> callback = - SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback)); + scoped_ptr<SingleReleaseCallbackImpl> callback = + SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)); TextureMailbox mailbox(gpu_mailbox, target, sync_point); @@ -2886,8 +3003,14 @@ TEST_P(ResourceProviderTest, TextureAllocation) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); gfx::Size size(2, 2); gfx::Vector2d offset(0, 0); @@ -2963,8 +3086,14 @@ TEST_P(ResourceProviderTest, TextureAllocationHint) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); gfx::Size size(2, 2); @@ -3017,8 +3146,14 @@ TEST_P(ResourceProviderTest, TextureAllocationHint_BGRA) { context_owned.PassAs<TestWebGraphicsContext3D>())); CHECK(output_surface->BindToClient(&output_surface_client)); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); gfx::Size size(2, 2); const ResourceFormat formats[2] = {RGBA_8888, BGRA_8888}; @@ -3070,8 +3205,14 @@ TEST_P(ResourceProviderTest, PixelBuffer_GLTexture) { ResourceProvider::ResourceId id = 0; int texture_id = 123; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format); @@ -3114,8 +3255,14 @@ TEST_P(ResourceProviderTest, ForcingAsyncUploadToComplete) { ResourceProvider::ResourceId id = 0; int texture_id = 123; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format); @@ -3158,8 +3305,14 @@ TEST_P(ResourceProviderTest, PixelBufferLostContext) { ResourceProvider::ResourceId id = 0; int texture_id = 123; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); EXPECT_CALL(*context, NextTextureId()).WillRepeatedly(Return(texture_id)); @@ -3198,8 +3351,14 @@ TEST_P(ResourceProviderTest, Image_GLTexture) { const unsigned kTextureId = 123u; const unsigned kImageId = 234u; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format); @@ -3284,8 +3443,14 @@ TEST_P(ResourceProviderTest, Image_Bitmap) { ResourceProvider::ResourceId id = 0; const uint32_t kBadBeef = 0xbadbeef; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format); @@ -3335,8 +3500,14 @@ TEST_P(ResourceProviderTest, CopyResource_GLTexture) { const unsigned kDestTextureId = 321u; const unsigned kImageId = 234u; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); source_id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format); @@ -3408,8 +3579,14 @@ TEST_P(ResourceProviderTest, CopyResource_Bitmap) { ResourceProvider::ResourceId dest_id = 0; const uint32_t kBadBeef = 0xbadbeef; - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager_.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false)); source_id = resource_provider->CreateResource( size, GL_CLAMP_TO_EDGE, ResourceProvider::TextureHintImmutable, format); @@ -3471,8 +3648,14 @@ TEST(ResourceProviderTest, BasicInitializeGLSoftware) { EXPECT_TRUE(output_surface->BindToClient(&client)); scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); CheckCreateResource(ResourceProvider::Bitmap, resource_provider.get(), NULL); @@ -3507,6 +3690,7 @@ TEST_P(ResourceProviderTest, CompressedTextureETC1Allocate) { scoped_ptr<ResourceProvider> resource_provider( ResourceProvider::Create(output_surface.get(), shared_bitmap_manager_.get(), + NULL, 0, false, 1, @@ -3542,6 +3726,7 @@ TEST_P(ResourceProviderTest, CompressedTextureETC1SetPixels) { scoped_ptr<ResourceProvider> resource_provider( ResourceProvider::Create(output_surface.get(), shared_bitmap_manager_.get(), + NULL, 0, false, 1, @@ -3602,6 +3787,7 @@ TEST(ResourceProviderTest, TextureAllocationChunkSize) { scoped_ptr<ResourceProvider> resource_provider( ResourceProvider::Create(output_surface.get(), shared_bitmap_manager.get(), + NULL, 0, false, kTextureAllocationChunkSize, @@ -3621,6 +3807,7 @@ TEST(ResourceProviderTest, TextureAllocationChunkSize) { scoped_ptr<ResourceProvider> resource_provider( ResourceProvider::Create(output_surface.get(), shared_bitmap_manager.get(), + NULL, 0, false, kTextureAllocationChunkSize, diff --git a/cc/resources/resource_update_controller_unittest.cc b/cc/resources/resource_update_controller_unittest.cc index 0fb899d..58df016 100644 --- a/cc/resources/resource_update_controller_unittest.cc +++ b/cc/resources/resource_update_controller_unittest.cc @@ -125,9 +125,13 @@ class ResourceUpdateControllerTest : public Test { CHECK(output_surface_->BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false); } void AppendFullUploadsOfIndexedTextureToUpdateQueue(int count, diff --git a/cc/resources/return_callback.h b/cc/resources/return_callback.h index d12254b..abf5aec 100644 --- a/cc/resources/return_callback.h +++ b/cc/resources/return_callback.h @@ -9,8 +9,11 @@ #include "cc/resources/returned_resource.h" namespace cc { +class BlockingTaskRunner; -typedef base::Callback<void(const ReturnedResourceArray&)> ReturnCallback; +typedef base::Callback<void(const ReturnedResourceArray&, + BlockingTaskRunner* main_thread_task_runner)> + ReturnCallback; } // namespace cc diff --git a/cc/resources/scoped_resource_unittest.cc b/cc/resources/scoped_resource_unittest.cc index 5b5f143..f671479 100644 --- a/cc/resources/scoped_resource_unittest.cc +++ b/cc/resources/scoped_resource_unittest.cc @@ -21,8 +21,14 @@ TEST(ScopedResourceTest, NewScopedResource) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); scoped_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider.get()); @@ -41,8 +47,14 @@ TEST(ScopedResourceTest, CreateScopedResource) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); scoped_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider.get()); texture->Allocate( @@ -64,8 +76,14 @@ TEST(ScopedResourceTest, ScopedResourceIsDeleted) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); { scoped_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider.get()); @@ -98,8 +116,14 @@ TEST(ScopedResourceTest, LeakScopedResource) { scoped_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); - scoped_ptr<ResourceProvider> resource_provider(ResourceProvider::Create( - output_surface.get(), shared_bitmap_manager.get(), 0, false, 1, false)); + scoped_ptr<ResourceProvider> resource_provider( + ResourceProvider::Create(output_surface.get(), + shared_bitmap_manager.get(), + NULL, + 0, + false, + 1, + false)); { scoped_ptr<ScopedResource> texture = ScopedResource::Create(resource_provider.get()); diff --git a/cc/resources/single_release_callback_impl.cc b/cc/resources/single_release_callback_impl.cc new file mode 100644 index 0000000..6f3c535 --- /dev/null +++ b/cc/resources/single_release_callback_impl.cc @@ -0,0 +1,34 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/resources/single_release_callback_impl.h" + +#include "base/callback_helpers.h" +#include "base/logging.h" +#include "cc/trees/blocking_task_runner.h" + +namespace cc { + +SingleReleaseCallbackImpl::SingleReleaseCallbackImpl( + const ReleaseCallbackImpl& callback) + : has_been_run_(false), callback_(callback) { + DCHECK(!callback_.is_null()) + << "Use a NULL SingleReleaseCallbackImpl for an empty callback."; +} + +SingleReleaseCallbackImpl::~SingleReleaseCallbackImpl() { + DCHECK(callback_.is_null() || has_been_run_) + << "SingleReleaseCallbackImpl was never run."; +} + +void SingleReleaseCallbackImpl::Run( + uint32 sync_point, + bool is_lost, + BlockingTaskRunner* main_thread_task_runner) { + DCHECK(!has_been_run_) << "SingleReleaseCallbackImpl was run more than once."; + has_been_run_ = true; + callback_.Run(sync_point, is_lost, main_thread_task_runner); +} + +} // namespace cc diff --git a/cc/resources/single_release_callback_impl.h b/cc/resources/single_release_callback_impl.h new file mode 100644 index 0000000..41220dc --- /dev/null +++ b/cc/resources/single_release_callback_impl.h @@ -0,0 +1,36 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_RESOURCES_SINGLE_RELEASE_CALLBACK_IMPL_H_ +#define CC_RESOURCES_SINGLE_RELEASE_CALLBACK_IMPL_H_ + +#include "base/memory/scoped_ptr.h" +#include "cc/base/cc_export.h" +#include "cc/resources/release_callback_impl.h" + +namespace cc { + +class CC_EXPORT SingleReleaseCallbackImpl { + public: + static scoped_ptr<SingleReleaseCallbackImpl> Create( + const ReleaseCallbackImpl& cb) { + return make_scoped_ptr(new SingleReleaseCallbackImpl(cb)); + } + + ~SingleReleaseCallbackImpl(); + + void Run(uint32 sync_point, + bool is_lost, + BlockingTaskRunner* main_thread_task_runner); + + private: + explicit SingleReleaseCallbackImpl(const ReleaseCallbackImpl& callback); + + bool has_been_run_; + ReleaseCallbackImpl callback_; +}; + +} // namespace cc + +#endif // CC_RESOURCES_SINGLE_RELEASE_CALLBACK_IMPL_H_ diff --git a/cc/resources/tile_manager_unittest.cc b/cc/resources/tile_manager_unittest.cc index b85c286..f229fcd 100644 --- a/cc/resources/tile_manager_unittest.cc +++ b/cc/resources/tile_manager_unittest.cc @@ -39,9 +39,13 @@ class TileManagerTest : public testing::TestWithParam<bool>, CHECK(output_surface_->BindToClient(&output_surface_client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false); resource_pool_ = ResourcePool::Create( resource_provider_.get(), GL_TEXTURE_2D, RGBA_8888); tile_manager_ = diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc index 836f2ce..0324144 100644 --- a/cc/resources/video_resource_updater.cc +++ b/cc/resources/video_resource_updater.cc @@ -306,7 +306,8 @@ void VideoResourceUpdater::ReturnTexture( base::WeakPtr<VideoResourceUpdater> updater, const scoped_refptr<media::VideoFrame>& video_frame, uint32 sync_point, - bool lost_resource) { + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner) { // TODO(dshwang) this case should be forwarded to the decoder as lost // resource. if (lost_resource || !updater.get()) @@ -362,7 +363,8 @@ void VideoResourceUpdater::RecycleResource( base::WeakPtr<VideoResourceUpdater> updater, RecycleResourceData data, uint32 sync_point, - bool lost_resource) { + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner) { if (!updater.get()) { // Resource was already deleted. return; diff --git a/cc/resources/video_resource_updater.h b/cc/resources/video_resource_updater.h index b09a19b..e9b924b 100644 --- a/cc/resources/video_resource_updater.h +++ b/cc/resources/video_resource_updater.h @@ -12,7 +12,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "cc/base/cc_export.h" -#include "cc/resources/release_callback.h" +#include "cc/resources/release_callback_impl.h" #include "cc/resources/resource_format.h" #include "cc/resources/texture_mailbox.h" #include "ui/gfx/size.h" @@ -50,11 +50,11 @@ class CC_EXPORT VideoFrameExternalResources { ResourceType type; std::vector<TextureMailbox> mailboxes; - std::vector<ReleaseCallback> release_callbacks; + std::vector<ReleaseCallbackImpl> release_callbacks; // TODO(danakj): Remove these too. std::vector<unsigned> software_resources; - ReleaseCallback software_release_callback; + ReleaseCallbackImpl software_release_callback; VideoFrameExternalResources(); ~VideoFrameExternalResources(); @@ -105,11 +105,13 @@ class CC_EXPORT VideoResourceUpdater static void RecycleResource(base::WeakPtr<VideoResourceUpdater> updater, RecycleResourceData data, uint32 sync_point, - bool lost_resource); + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner); static void ReturnTexture(base::WeakPtr<VideoResourceUpdater> updater, const scoped_refptr<media::VideoFrame>& video_frame, uint32 sync_point, - bool lost_resource); + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner); ContextProvider* context_provider_; ResourceProvider* resource_provider_; diff --git a/cc/resources/video_resource_updater_unittest.cc b/cc/resources/video_resource_updater_unittest.cc index fff3d6b..c40d4a2 100644 --- a/cc/resources/video_resource_updater_unittest.cc +++ b/cc/resources/video_resource_updater_unittest.cc @@ -10,6 +10,7 @@ #include "cc/test/fake_output_surface_client.h" #include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" +#include "cc/trees/blocking_task_runner.h" #include "media/base/video_frame.h" #include "testing/gtest/include/gtest/gtest.h" @@ -27,9 +28,14 @@ class VideoResourceUpdaterTest : public testing::Test { FakeOutputSurface::Create3d(context3d.Pass()); CHECK(output_surface3d_->BindToClient(&client_)); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider3d_ = ResourceProvider::Create( - output_surface3d_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); + resource_provider3d_ = + ResourceProvider::Create(output_surface3d_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false); } scoped_refptr<media::VideoFrame> CreateTestYUVVideoFrame() { diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc index a46f05f..105eeb2 100644 --- a/cc/surfaces/display.cc +++ b/cc/surfaces/display.cc @@ -15,13 +15,18 @@ #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_aggregator.h" #include "cc/surfaces/surface_manager.h" +#include "cc/trees/blocking_task_runner.h" namespace cc { Display::Display(DisplayClient* client, SurfaceManager* manager, SharedBitmapManager* bitmap_manager) - : client_(client), manager_(manager), bitmap_manager_(bitmap_manager) { + : client_(client), + manager_(manager), + bitmap_manager_(bitmap_manager), + blocking_main_thread_task_runner_( + BlockingTaskRunner::Create(base::MessageLoopProxy::current())) { manager_->AddObserver(this); } @@ -49,6 +54,7 @@ void Display::InitializeOutputSurface() { scoped_ptr<ResourceProvider> resource_provider = ResourceProvider::Create(output_surface.get(), bitmap_manager_, + blocking_main_thread_task_runner_.get(), highp_threshold_min, use_rgba_4444_texture_format, id_allocation_chunk_size, @@ -89,6 +95,8 @@ bool Display::Draw() { if (!output_surface_) return false; + // TODO(skyostil): We should hold a BlockingTaskRunner::CapturePostTasks + // while Aggregate is called to immediately run release callbacks afterward. scoped_ptr<CompositorFrame> frame = aggregator_->Aggregate(current_surface_id_); if (!frame) diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h index 57d6af4..07e87ad 100644 --- a/cc/surfaces/display.h +++ b/cc/surfaces/display.h @@ -20,6 +20,7 @@ class Size; namespace cc { +class BlockingTaskRunner; class DirectRenderer; class DisplayClient; class OutputSurface; @@ -88,6 +89,7 @@ class CC_SURFACES_EXPORT Display : public OutputSurfaceClient, scoped_ptr<ResourceProvider> resource_provider_; scoped_ptr<SurfaceAggregator> aggregator_; scoped_ptr<DirectRenderer> renderer_; + scoped_ptr<BlockingTaskRunner> blocking_main_thread_task_runner_; DISALLOW_COPY_AND_ASSIGN(Display); }; diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc index d9ec296..050a2f0e 100644 --- a/cc/surfaces/surface_aggregator.cc +++ b/cc/surfaces/surface_aggregator.cc @@ -18,6 +18,7 @@ #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_factory.h" #include "cc/surfaces/surface_manager.h" +#include "cc/trees/blocking_task_runner.h" namespace cc { @@ -54,6 +55,12 @@ class SurfaceAggregator::RenderPassIdAllocator { DISALLOW_COPY_AND_ASSIGN(RenderPassIdAllocator); }; +static void UnrefHelper(base::WeakPtr<SurfaceFactory> surface_factory, + const ReturnedResourceArray& resources, + BlockingTaskRunner* main_thread_task_runner) { + surface_factory->UnrefResources(resources); +} + RenderPassId SurfaceAggregator::RemapPassId(RenderPassId surface_local_pass_id, SurfaceId surface_id) { RenderPassIdAllocator* allocator = render_pass_allocator_map_.get(surface_id); @@ -69,8 +76,8 @@ int SurfaceAggregator::ChildIdForSurface(Surface* surface) { SurfaceToResourceChildIdMap::iterator it = surface_id_to_resource_child_id_.find(surface->surface_id()); if (it == surface_id_to_resource_child_id_.end()) { - int child_id = provider_->CreateChild(base::Bind( - &SurfaceFactory::UnrefResources, surface->factory()->AsWeakPtr())); + int child_id = provider_->CreateChild( + base::Bind(&UnrefHelper, surface->factory()->AsWeakPtr())); surface_id_to_resource_child_id_[surface->surface_id()] = child_id; return child_id; } else { diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc index 50b21db..3a6d19f 100644 --- a/cc/surfaces/surface_aggregator_unittest.cc +++ b/cc/surfaces/surface_aggregator_unittest.cc @@ -971,6 +971,7 @@ class SurfaceAggregatorWithResourcesTest : public testing::Test { resource_provider_ = ResourceProvider::Create(output_surface_.get(), shared_bitmap_manager_.get(), + NULL, 0, false, 1, diff --git a/cc/test/fake_delegated_renderer_layer_impl.cc b/cc/test/fake_delegated_renderer_layer_impl.cc index b7d3254..c440d74 100644 --- a/cc/test/fake_delegated_renderer_layer_impl.cc +++ b/cc/test/fake_delegated_renderer_layer_impl.cc @@ -48,7 +48,9 @@ ResourceProvider::ResourceIdSet FakeDelegatedRendererLayerImpl::Resources() return set; } -void NoopReturnCallback(const ReturnedResourceArray& returned) {} +void NoopReturnCallback(const ReturnedResourceArray& returned, + BlockingTaskRunner* main_thread_task_runner) { +} void FakeDelegatedRendererLayerImpl::SetFrameDataForRenderPasses( float device_scale_factor, diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc index d7d3c15..de02e5b 100644 --- a/cc/test/pixel_test.cc +++ b/cc/test/pixel_test.cc @@ -25,6 +25,7 @@ #include "cc/test/pixel_test_utils.h" #include "cc/test/test_in_process_context_provider.h" #include "cc/test/test_shared_bitmap_manager.h" +#include "cc/trees/blocking_task_runner.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "testing/gtest/include/gtest/gtest.h" @@ -33,8 +34,10 @@ namespace cc { PixelTest::PixelTest() : device_viewport_size_(gfx::Size(200, 200)), disable_picture_quad_image_filtering_(false), - output_surface_client_(new FakeOutputSurfaceClient) {} - + output_surface_client_(new FakeOutputSurfaceClient), + main_thread_task_runner_( + BlockingTaskRunner::Create(base::MessageLoopProxy::current())) { +} PixelTest::~PixelTest() {} bool PixelTest::RunPixelTest(RenderPassList* pass_list, @@ -112,8 +115,13 @@ void PixelTest::SetUpGLRenderer(bool use_skia_gpu_backend) { output_surface_->BindToClient(output_surface_client_.get()); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, false); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + main_thread_task_runner_.get(), + 0, + false, + 1, + false); texture_mailbox_deleter_ = make_scoped_ptr( new TextureMailboxDeleter(base::MessageLoopProxy::current())); @@ -154,8 +162,13 @@ void PixelTest::SetUpSoftwareRenderer() { output_surface_.reset(new PixelTestOutputSurface(device.Pass())); output_surface_->BindToClient(output_surface_client_.get()); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - resource_provider_ = ResourceProvider::Create( - output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, false); + resource_provider_ = ResourceProvider::Create(output_surface_.get(), + shared_bitmap_manager_.get(), + main_thread_task_runner_.get(), + 0, + false, + 1, + false); renderer_ = SoftwareRenderer::Create( this, &settings_, output_surface_.get(), resource_provider_.get()) diff --git a/cc/test/pixel_test.h b/cc/test/pixel_test.h index bb4c13d..2ddfd04 100644 --- a/cc/test/pixel_test.h +++ b/cc/test/pixel_test.h @@ -45,6 +45,7 @@ class PixelTest : public testing::Test, RendererClient { scoped_ptr<FakeOutputSurfaceClient> output_surface_client_; scoped_ptr<OutputSurface> output_surface_; scoped_ptr<SharedBitmapManager> shared_bitmap_manager_; + scoped_ptr<BlockingTaskRunner> main_thread_task_runner_; scoped_ptr<ResourceProvider> resource_provider_; scoped_ptr<TextureMailboxDeleter> texture_mailbox_deleter_; scoped_ptr<DirectRenderer> renderer_; diff --git a/cc/test/render_pass_test_common.cc b/cc/test/render_pass_test_common.cc index 0feb025..dd5bb90 100644 --- a/cc/test/render_pass_test_common.cc +++ b/cc/test/render_pass_test_common.cc @@ -16,11 +16,14 @@ #include "cc/quads/tile_draw_quad.h" #include "cc/quads/yuv_video_draw_quad.h" #include "cc/resources/resource_provider.h" +#include "cc/trees/blocking_task_runner.h" #include "ui/gfx/transform.h" namespace cc { -static void EmptyReleaseCallback(uint32 sync_point, bool lost_resource) { +static void EmptyReleaseCallback(uint32 sync_point, + bool lost_resource, + BlockingTaskRunner* main_thread_task_runner) { } void TestRenderPass::AppendOneOfEveryQuadType( @@ -77,8 +80,8 @@ void TestRenderPass::AppendOneOfEveryQuadType( unsigned target = GL_TEXTURE_2D; gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - scoped_ptr<SingleReleaseCallback> callback = - SingleReleaseCallback::Create(base::Bind(&EmptyReleaseCallback)); + scoped_ptr<SingleReleaseCallbackImpl> callback = + SingleReleaseCallbackImpl::Create(base::Bind(&EmptyReleaseCallback)); TextureMailbox mailbox(gpu_mailbox, target, kSyncPointForMailboxTextureQuad); ResourceProvider::ResourceId resource8 = resource_provider->CreateResourceFromTextureMailbox(mailbox, diff --git a/cc/trees/blocking_task_runner.cc b/cc/trees/blocking_task_runner.cc index 2586375..1111e9b 100644 --- a/cc/trees/blocking_task_runner.cc +++ b/cc/trees/blocking_task_runner.cc @@ -6,49 +6,16 @@ #include <utility> +#include "base/callback.h" #include "base/logging.h" -#include "base/memory/singleton.h" #include "base/message_loop/message_loop_proxy.h" namespace cc { -struct TaskRunnerPairs { - static TaskRunnerPairs* GetInstance() { - return Singleton<TaskRunnerPairs>::get(); - } - - base::Lock lock; - std::vector<scoped_refptr<BlockingTaskRunner> > runners; - - private: - friend struct DefaultSingletonTraits<TaskRunnerPairs>; -}; - // static -scoped_refptr<BlockingTaskRunner> BlockingTaskRunner::current() { - TaskRunnerPairs* task_runners = TaskRunnerPairs::GetInstance(); - base::PlatformThreadId thread_id = base::PlatformThread::CurrentId(); - - base::AutoLock lock(task_runners->lock); - - scoped_refptr<BlockingTaskRunner> current_task_runner; - - for (size_t i = 0; i < task_runners->runners.size(); ++i) { - if (task_runners->runners[i]->thread_id_ == thread_id) { - current_task_runner = task_runners->runners[i]; - } else if (task_runners->runners[i]->HasOneRef()) { - task_runners->runners.erase(task_runners->runners.begin() + i); - i--; - } - } - - if (current_task_runner.get()) - return current_task_runner; - - scoped_refptr<BlockingTaskRunner> runner = - new BlockingTaskRunner(base::MessageLoopProxy::current()); - task_runners->runners.push_back(runner); - return runner; +scoped_ptr<BlockingTaskRunner> BlockingTaskRunner::Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner) { + return make_scoped_ptr(new BlockingTaskRunner(task_runner)); } BlockingTaskRunner::BlockingTaskRunner( @@ -94,8 +61,9 @@ void BlockingTaskRunner::SetCapture(bool capture) { tasks[i].Run(); } -BlockingTaskRunner::CapturePostTasks::CapturePostTasks() - : blocking_runner_(BlockingTaskRunner::current()) { +BlockingTaskRunner::CapturePostTasks::CapturePostTasks( + BlockingTaskRunner* blocking_runner) + : blocking_runner_(blocking_runner) { blocking_runner_->SetCapture(true); } diff --git a/cc/trees/blocking_task_runner.h b/cc/trees/blocking_task_runner.h index 8388a88..eb43b91 100644 --- a/cc/trees/blocking_task_runner.h +++ b/cc/trees/blocking_task_runner.h @@ -8,7 +8,7 @@ #include <vector> #include "base/location.h" -#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "base/threading/platform_thread.h" @@ -25,38 +25,43 @@ namespace cc { // to when they were posted. // // To use this class, post tasks to the task runner returned by -// BlockingTaskRunner::current() on the thread you want the tasks to run. -// Hold a reference to the BlockingTaskRunner as long as you intend to -// post tasks to it. +// BlockingTaskRunner::Create(). The thread it is created on identifies the +// thread you want the tasks to run on. The SingleThreadTaskRunner which is +// passed into Create() is used to run tasks that are posted when not in a +// capturing state. // -// Then, on the thread from which the BlockingTaskRunner was created, you -// may instantiate a BlockingTaskRunner::CapturePostTasks. While this object +// Then, on the thread that the given task runner belongs to, you may +// instantiate a BlockingTaskRunner::CapturePostTasks. While this object // exists, the task runner will collect any PostTasks called on it, posting // tasks to that thread from anywhere. This CapturePostTasks object provides // a window in time where tasks can shortcut past the MessageLoop. As soon // as the CapturePostTasks object is destroyed (goes out of scope), all -// tasks that had been posted to the thread during the window will be exectuted +// tasks that had been posted to the thread during the window will be executed // immediately. // // Beware of re-entrancy, make sure the CapturePostTasks object is destroyed at // a time when it makes sense for the embedder to call arbitrary things. -class CC_EXPORT BlockingTaskRunner - : public base::RefCountedThreadSafe<BlockingTaskRunner> { +class CC_EXPORT BlockingTaskRunner { public: - // Returns the BlockingTaskRunner for the current thread, creating one if - // necessary. - static scoped_refptr<BlockingTaskRunner> current(); + // Creates a BlockingTaskRunner for a given SingleThreadTaskRunner. + // |task_runner| will be used to run the tasks which are posted while we are + // not capturing. |task_runner| should belong to same the thread on which + // capturing is done. + static scoped_ptr<BlockingTaskRunner> Create( + scoped_refptr<base::SingleThreadTaskRunner> task_runner); + + ~BlockingTaskRunner(); // While an object of this type is held alive on a thread, any tasks // posted to the thread will be captured and run as soon as the object - // is destroyed, shortcutting past the MessageLoop. + // is destroyed, shortcutting past the task runner. class CC_EXPORT CapturePostTasks { public: - CapturePostTasks(); + explicit CapturePostTasks(BlockingTaskRunner* blocking_runner); ~CapturePostTasks(); private: - scoped_refptr<BlockingTaskRunner> blocking_runner_; + BlockingTaskRunner* blocking_runner_; DISALLOW_COPY_AND_ASSIGN(CapturePostTasks); }; @@ -73,11 +78,8 @@ class CC_EXPORT BlockingTaskRunner const base::Closure& task); private: - friend class base::RefCountedThreadSafe<BlockingTaskRunner>; - explicit BlockingTaskRunner( scoped_refptr<base::SingleThreadTaskRunner> task_runner); - virtual ~BlockingTaskRunner(); void SetCapture(bool capture); @@ -87,6 +89,8 @@ class CC_EXPORT BlockingTaskRunner base::Lock lock_; int capture_; std::vector<base::Closure> captured_tasks_; + + DISALLOW_COPY_AND_ASSIGN(BlockingTaskRunner); }; } // namespace cc diff --git a/cc/trees/blocking_task_runner_unittest.cc b/cc/trees/blocking_task_runner_unittest.cc new file mode 100644 index 0000000..ba4f96a8 --- /dev/null +++ b/cc/trees/blocking_task_runner_unittest.cc @@ -0,0 +1,42 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/trees/blocking_task_runner.h" + +#include "base/bind.h" +#include "base/run_loop.h" +#include "cc/test/ordered_simple_task_runner.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { + +void TestTask(bool* result) { + *result = true; +} + +TEST(BlockingTaskRunnerTest, NoCapture) { + bool did_run = false; + scoped_ptr<BlockingTaskRunner> runner( + BlockingTaskRunner::Create(base::MessageLoopProxy::current())); + runner->PostTask(FROM_HERE, base::Bind(&TestTask, &did_run)); + EXPECT_FALSE(did_run); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(did_run); +} + +TEST(BlockingTaskRunnerTest, Capture) { + bool did_run = false; + scoped_ptr<BlockingTaskRunner> runner( + BlockingTaskRunner::Create(base::MessageLoopProxy::current())); + { + BlockingTaskRunner::CapturePostTasks capture(runner.get()); + runner->PostTask(FROM_HERE, base::Bind(&TestTask, &did_run)); + EXPECT_FALSE(did_run); + } + EXPECT_TRUE(did_run); +} + +} // namespace +} // namespace cc diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc index f819ae8..d93593f 100644 --- a/cc/trees/layer_tree_host_impl.cc +++ b/cc/trees/layer_tree_host_impl.cc @@ -2064,6 +2064,7 @@ bool LayerTreeHostImpl::InitializeRenderer( resource_provider_ = ResourceProvider::Create(output_surface_.get(), shared_bitmap_manager_, + proxy_->blocking_main_thread_task_runner(), settings_.highp_threshold_min, settings_.use_rgba_4444_textures, settings_.texture_id_allocation_chunk_size, diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc index 999ab3f..c65725d 100644 --- a/cc/trees/layer_tree_host_perftest.cc +++ b/cc/trees/layer_tree_host_perftest.cc @@ -16,6 +16,7 @@ #include "cc/layers/nine_patch_layer.h" #include "cc/layers/solid_color_layer.h" #include "cc/layers/texture_layer.h" +#include "cc/resources/single_release_callback.h" #include "cc/resources/texture_mailbox.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/layer_tree_json_parser.h" diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc index 8fcfa28..0e15071 100644 --- a/cc/trees/layer_tree_host_unittest_context.cc +++ b/cc/trees/layer_tree_host_unittest_context.cc @@ -18,6 +18,7 @@ #include "cc/layers/video_layer.h" #include "cc/layers/video_layer_impl.h" #include "cc/output/filter_operations.h" +#include "cc/resources/single_release_callback.h" #include "cc/test/fake_content_layer.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_content_layer_impl.h" @@ -689,9 +690,14 @@ class LayerTreeHostContextTestDontUseLostResources child_output_surface_ = FakeOutputSurface::Create3d(); child_output_surface_->BindToClient(&output_surface_client_); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); - child_resource_provider_ = ResourceProvider::Create( - child_output_surface_.get(), shared_bitmap_manager_.get(), 0, false, 1, - false); + child_resource_provider_ = + ResourceProvider::Create(child_output_surface_.get(), + shared_bitmap_manager_.get(), + NULL, + 0, + false, + 1, + false); } static void EmptyReleaseCallback(unsigned sync_point, bool lost) {} diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc index 45c59a5e..61b1fcf 100644 --- a/cc/trees/layer_tree_impl.cc +++ b/cc/trees/layer_tree_impl.cc @@ -1424,4 +1424,8 @@ void LayerTreeImpl::InputScrollAnimationFinished() { layer_tree_host_impl_->ScrollEnd(); } +BlockingTaskRunner* LayerTreeImpl::BlockingMainThreadTaskRunner() const { + return proxy()->blocking_main_thread_task_runner(); +} + } // namespace cc diff --git a/cc/trees/layer_tree_impl.h b/cc/trees/layer_tree_impl.h index 9b68f1b..76d3868 100644 --- a/cc/trees/layer_tree_impl.h +++ b/cc/trees/layer_tree_impl.h @@ -102,6 +102,7 @@ class CC_EXPORT LayerTreeImpl { void InputScrollAnimationFinished(); bool use_gpu_rasterization() const; bool create_low_res_tiling() const; + BlockingTaskRunner* BlockingMainThreadTaskRunner() const; // Tree specific methods exposed to layer-impl tree. // --------------------------------------------------------------------------- diff --git a/cc/trees/proxy.cc b/cc/trees/proxy.cc index 3136c65..e981a72 100644 --- a/cc/trees/proxy.cc +++ b/cc/trees/proxy.cc @@ -6,6 +6,7 @@ #include "base/message_loop/message_loop_proxy.h" #include "base/single_thread_task_runner.h" +#include "cc/trees/blocking_task_runner.h" namespace cc { @@ -69,10 +70,15 @@ void Proxy::SetMainThreadBlocked(bool is_main_thread_blocked) { Proxy::Proxy(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) #if !DCHECK_IS_ON - : main_task_runner_(main_task_runner), impl_task_runner_(impl_task_runner) { + : main_task_runner_(main_task_runner), + impl_task_runner_(impl_task_runner), + blocking_main_thread_task_runner_( + BlockingTaskRunner::Create(main_task_runner)) { #else : main_task_runner_(main_task_runner), impl_task_runner_(impl_task_runner), + blocking_main_thread_task_runner_( + BlockingTaskRunner::Create(main_task_runner)), main_thread_id_(base::PlatformThread::CurrentId()), impl_thread_is_overridden_(false), is_main_thread_blocked_(false) { diff --git a/cc/trees/proxy.h b/cc/trees/proxy.h index 112c259..8d72728 100644 --- a/cc/trees/proxy.h +++ b/cc/trees/proxy.h @@ -29,7 +29,7 @@ class Vector2d; } namespace cc { - +class BlockingTaskRunner; class LayerTreeDebugState; class OutputSurface; struct RendererCapabilities; @@ -103,6 +103,10 @@ class CC_EXPORT Proxy { // Testing hooks virtual bool MainFrameWillHappenForTesting() = 0; + BlockingTaskRunner* blocking_main_thread_task_runner() const { + return blocking_main_thread_task_runner_.get(); + } + protected: Proxy(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); @@ -113,6 +117,8 @@ class CC_EXPORT Proxy { private: scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner_; + scoped_ptr<BlockingTaskRunner> blocking_main_thread_task_runner_; + #if DCHECK_IS_ON const base::PlatformThreadId main_thread_id_; bool impl_thread_is_overridden_; diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc index 1ccbdb9d..0e8c81c 100644 --- a/cc/trees/single_thread_proxy.cc +++ b/cc/trees/single_thread_proxy.cc @@ -192,7 +192,8 @@ void SingleThreadProxy::DoCommit(const BeginFrameArgs& begin_frame_args) { // This CapturePostTasks should be destroyed before CommitComplete() is // called since that goes out to the embedder, and we want the embedder // to receive its callbacks before that. - BlockingTaskRunner::CapturePostTasks blocked; + BlockingTaskRunner::CapturePostTasks blocked( + blocking_main_thread_task_runner()); layer_tree_host_impl_->BeginCommit(); @@ -308,7 +309,8 @@ void SingleThreadProxy::Stop() { DebugScopedSetMainThreadBlocked main_thread_blocked(this); DebugScopedSetImplThread impl(this); - BlockingTaskRunner::CapturePostTasks blocked; + BlockingTaskRunner::CapturePostTasks blocked( + blocking_main_thread_task_runner()); layer_tree_host_->DeleteContentsTexturesOnImplThread( layer_tree_host_impl_->resource_provider()); scheduler_on_impl_thread_.reset(); @@ -534,7 +536,8 @@ DrawResult SingleThreadProxy::DoComposite(base::TimeTicks frame_begin_time, // the swap buffers will execute first. DebugScopedSetMainThreadBlocked main_thread_blocked(this); - BlockingTaskRunner::CapturePostTasks blocked; + BlockingTaskRunner::CapturePostTasks blocked( + blocking_main_thread_task_runner()); layer_tree_host_impl_->SwapBuffers(*frame); } DidCommitAndDrawFrame(); diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc index 688937e..d1cb6d1 100644 --- a/cc/trees/thread_proxy.cc +++ b/cc/trees/thread_proxy.cc @@ -202,7 +202,8 @@ void ThreadProxy::DidLoseOutputSurface() { DebugScopedSetMainThreadBlocked main_thread_blocked(this); // Return lost resources to their owners immediately. - BlockingTaskRunner::CapturePostTasks blocked; + BlockingTaskRunner::CapturePostTasks blocked( + blocking_main_thread_task_runner()); CompletionEvent completion; Proxy::ImplThreadTaskRunner()->PostTask( @@ -860,7 +861,8 @@ void ThreadProxy::BeginMainFrame( // This CapturePostTasks should be destroyed before CommitComplete() is // called since that goes out to the embedder, and we want the embedder // to receive its callbacks before that. - BlockingTaskRunner::CapturePostTasks blocked; + BlockingTaskRunner::CapturePostTasks blocked( + blocking_main_thread_task_runner()); CompletionEvent completion; Proxy::ImplThreadTaskRunner()->PostTask( |