diff options
Diffstat (limited to 'cc')
30 files changed, 471 insertions, 286 deletions
@@ -314,6 +314,7 @@ 'resources/raster_mode.h', 'resources/raster_worker_pool.cc', 'resources/raster_worker_pool.h', + 'resources/release_callback.h', 'resources/resource.cc', 'resources/resource.h', 'resources/resource_pool.cc', @@ -331,6 +332,8 @@ 'resources/scoped_resource.h', 'resources/scoped_ui_resource.cc', 'resources/scoped_ui_resource.h', + 'resources/single_release_callback.cc', + 'resources/single_release_callback.h', 'resources/skpicture_content_layer_updater.cc', 'resources/skpicture_content_layer_updater.h', 'resources/sync_point_helper.cc', diff --git a/cc/layers/texture_layer.cc b/cc/layers/texture_layer.cc index d4a1314..340526e 100644 --- a/cc/layers/texture_layer.cc +++ b/cc/layers/texture_layer.cc @@ -5,10 +5,12 @@ #include "cc/layers/texture_layer.h" #include "base/bind.h" +#include "base/callback_helpers.h" #include "base/location.h" #include "base/synchronization/lock.h" #include "cc/layers/texture_layer_client.h" #include "cc/layers/texture_layer_impl.h" +#include "cc/resources/single_release_callback.h" #include "cc/trees/blocking_task_runner.h" #include "cc/trees/layer_tree_host.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" @@ -51,7 +53,7 @@ void TextureLayer::ClearClient() { layer_tree_host()->StopRateLimiter(client_->Context3d()); client_ = NULL; if (uses_mailbox_) - SetTextureMailbox(TextureMailbox()); + SetTextureMailbox(TextureMailbox(), scoped_ptr<SingleReleaseCallback>()); else SetTextureId(0); } @@ -130,13 +132,17 @@ void TextureLayer::SetTextureId(unsigned id) { SetNextCommitWaitsForActivation(); } -void TextureLayer::SetTextureMailbox(const TextureMailbox& mailbox) { +void TextureLayer::SetTextureMailbox( + const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback) { DCHECK(uses_mailbox_); DCHECK(!mailbox.IsValid() || !holder_ref_ || !mailbox.Equals(holder_ref_->holder()->mailbox())); + DCHECK_EQ(mailbox.IsValid(), !!release_callback); + // If we never commited the mailbox, we need to release it here. if (mailbox.IsValid()) - holder_ref_ = MailboxHolder::Create(mailbox); + holder_ref_ = MailboxHolder::Create(mailbox, release_callback.Pass()); else holder_ref_.reset(); needs_set_mailbox_ = true; @@ -198,9 +204,12 @@ bool TextureLayer::Update(ResourceUpdateQueue* queue, if (client_) { if (uses_mailbox_) { TextureMailbox mailbox; + scoped_ptr<SingleReleaseCallback> release_callback; if (client_->PrepareTextureMailbox( - &mailbox, layer_tree_host()->UsingSharedMemoryResources())) { - SetTextureMailbox(mailbox); + &mailbox, + &release_callback, + layer_tree_host()->UsingSharedMemoryResources())) { + SetTextureMailbox(mailbox, release_callback.Pass()); updated = true; } } else { @@ -235,13 +244,13 @@ void TextureLayer::PushPropertiesTo(LayerImpl* layer) { texture_layer->set_blend_background_color(blend_background_color_); if (uses_mailbox_ && needs_set_mailbox_) { TextureMailbox texture_mailbox; + scoped_ptr<SingleReleaseCallback> release_callback; if (holder_ref_) { MailboxHolder* holder = holder_ref_->holder(); - TextureMailbox::ReleaseCallback callback = - holder->GetCallbackForImplThread(); - texture_mailbox = holder->mailbox().CopyWithNewCallback(callback); + texture_mailbox = holder->mailbox(); + release_callback = holder->GetCallbackForImplThread(); } - texture_layer->SetTextureMailbox(texture_mailbox); + texture_layer->SetTextureMailbox(texture_mailbox, release_callback.Pass()); needs_set_mailbox_ = false; } else { texture_layer->set_texture_id(texture_id_); @@ -273,10 +282,13 @@ TextureLayer::MailboxHolder::MainThreadReference::~MainThreadReference() { holder_->InternalRelease(); } -TextureLayer::MailboxHolder::MailboxHolder(const TextureMailbox& mailbox) +TextureLayer::MailboxHolder::MailboxHolder( + const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback) : message_loop_(BlockingTaskRunner::current()), internal_references_(0), mailbox_(mailbox), + release_callback_(release_callback.Pass()), sync_point_(mailbox.sync_point()), is_lost_(false) { } @@ -286,9 +298,11 @@ TextureLayer::MailboxHolder::~MailboxHolder() { } scoped_ptr<TextureLayer::MailboxHolder::MainThreadReference> -TextureLayer::MailboxHolder::Create(const TextureMailbox& mailbox) { +TextureLayer::MailboxHolder::Create( + const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback) { return scoped_ptr<MainThreadReference>(new MainThreadReference( - new MailboxHolder(mailbox))); + new MailboxHolder(mailbox, release_callback.Pass()))); } void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) { @@ -297,13 +311,14 @@ void TextureLayer::MailboxHolder::Return(unsigned sync_point, bool is_lost) { is_lost_ = is_lost; } -TextureMailbox::ReleaseCallback +scoped_ptr<SingleReleaseCallback> TextureLayer::MailboxHolder::GetCallbackForImplThread() { // We can't call GetCallbackForImplThread if we released the main thread // reference. DCHECK_GT(internal_references_, 0u); InternalAddRef(); - return base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this); + return SingleReleaseCallback::Create( + base::Bind(&MailboxHolder::ReturnAndReleaseOnImplThread, this)); } void TextureLayer::MailboxHolder::InternalAddRef() { @@ -313,8 +328,9 @@ void TextureLayer::MailboxHolder::InternalAddRef() { void TextureLayer::MailboxHolder::InternalRelease() { DCHECK(message_loop_->BelongsToCurrentThread()); if (!--internal_references_) { - mailbox_.RunReleaseCallback(sync_point_, is_lost_); - DCHECK(mailbox_.callback().is_null()); + release_callback_->Run(sync_point_, is_lost_); + mailbox_ = TextureMailbox(); + release_callback_.reset(); } } diff --git a/cc/layers/texture_layer.h b/cc/layers/texture_layer.h index cb34cf5..5fb214c 100644 --- a/cc/layers/texture_layer.h +++ b/cc/layers/texture_layer.h @@ -17,6 +17,7 @@ namespace WebKit { class WebGraphicsContext3D; } namespace cc { class BlockingTaskRunner; +class SingleReleaseCallback; class TextureLayerClient; // A Layer containing a the rendered output of a plugin instance. @@ -41,20 +42,22 @@ 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. - TextureMailbox::ReleaseCallback GetCallbackForImplThread(); + scoped_ptr<SingleReleaseCallback> GetCallbackForImplThread(); protected: friend class TextureLayer; // Protected visiblity so only TextureLayer and unit tests can create these. static scoped_ptr<MainThreadReference> Create( - const TextureMailbox& mailbox); + const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback); virtual ~MailboxHolder(); private: friend class base::RefCountedThreadSafe<MailboxHolder>; friend class MainThreadReference; - explicit MailboxHolder(const TextureMailbox& mailbox); + explicit MailboxHolder(const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback); void InternalAddRef(); void InternalRelease(); @@ -67,6 +70,7 @@ class CC_EXPORT TextureLayer : public Layer { // during commit where the main thread is blocked. unsigned internal_references_; TextureMailbox mailbox_; + scoped_ptr<SingleReleaseCallback> release_callback_; // This lock guards the sync_point_ and is_lost_ fields because they can be // accessed on both the impl and main thread. We do this to ensure that the @@ -125,7 +129,8 @@ class CC_EXPORT TextureLayer : public Layer { // Code path for plugins which supply their own mailbox. bool uses_mailbox() const { return uses_mailbox_; } - void SetTextureMailbox(const TextureMailbox& mailbox); + void SetTextureMailbox(const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback); void WillModifyTexture(); diff --git a/cc/layers/texture_layer_client.h b/cc/layers/texture_layer_client.h index 73d34b3..187b12f 100644 --- a/cc/layers/texture_layer_client.h +++ b/cc/layers/texture_layer_client.h @@ -5,6 +5,8 @@ #ifndef CC_LAYERS_TEXTURE_LAYER_CLIENT_H_ #define CC_LAYERS_TEXTURE_LAYER_CLIENT_H_ +#include "cc/resources/single_release_callback.h" + namespace WebKit { class WebGraphicsContext3D; } namespace cc { @@ -24,8 +26,10 @@ class TextureLayerClient { // Returns true and provides a mailbox if a new frame is available. // Returns false if no new data is available // and the old mailbox is to be reused. - virtual bool PrepareTextureMailbox(TextureMailbox* mailbox, - bool use_shared_memory) = 0; + virtual bool PrepareTextureMailbox( + TextureMailbox* mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback, + bool use_shared_memory) = 0; protected: virtual ~TextureLayerClient() {} diff --git a/cc/layers/texture_layer_impl.cc b/cc/layers/texture_layer_impl.cc index 851bf9a..413708d 100644 --- a/cc/layers/texture_layer_impl.cc +++ b/cc/layers/texture_layer_impl.cc @@ -4,12 +4,15 @@ #include "cc/layers/texture_layer_impl.h" +#include <vector> + #include "base/strings/stringprintf.h" #include "cc/layers/quad_sink.h" #include "cc/output/renderer.h" #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/trees/layer_tree_impl.h" namespace cc { @@ -36,10 +39,14 @@ TextureLayerImpl::TextureLayerImpl(LayerTreeImpl* tree_impl, TextureLayerImpl::~TextureLayerImpl() { FreeTextureMailbox(); } -void TextureLayerImpl::SetTextureMailbox(const TextureMailbox& mailbox) { +void TextureLayerImpl::SetTextureMailbox( + const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback) { DCHECK(uses_mailbox_); + DCHECK_EQ(mailbox.IsValid(), !!release_callback); FreeTextureMailbox(); texture_mailbox_ = mailbox; + release_callback_ = release_callback.Pass(); own_mailbox_ = true; valid_texture_copy_ = false; } @@ -60,7 +67,8 @@ void TextureLayerImpl::PushPropertiesTo(LayerImpl* layer) { texture_layer->set_vertex_opacity(vertex_opacity_); texture_layer->set_premultiplied_alpha(premultiplied_alpha_); if (uses_mailbox_ && own_mailbox_) { - texture_layer->SetTextureMailbox(texture_mailbox_); + texture_layer->SetTextureMailbox(texture_mailbox_, + release_callback_.Pass()); own_mailbox_ = false; } else { texture_layer->set_texture_id(texture_id_); @@ -80,7 +88,8 @@ bool TextureLayerImpl::WillDraw(DrawMode draw_mode, texture_mailbox_.IsSharedMemory())) { external_texture_resource_ = resource_provider->CreateResourceFromTextureMailbox( - texture_mailbox_); + texture_mailbox_, + release_callback_.Pass()); DCHECK(external_texture_resource_); texture_copy_.reset(); valid_texture_copy_ = false; @@ -229,7 +238,10 @@ void TextureLayerImpl::FreeTextureMailbox() { return; if (own_mailbox_) { DCHECK(!external_texture_resource_); - texture_mailbox_.RunReleaseCallback(texture_mailbox_.sync_point(), false); + if (release_callback_) + release_callback_->Run(texture_mailbox_.sync_point(), false); + texture_mailbox_ = TextureMailbox(); + release_callback_.reset(); } else if (external_texture_resource_) { DCHECK(!own_mailbox_); ResourceProvider* resource_provider = diff --git a/cc/layers/texture_layer_impl.h b/cc/layers/texture_layer_impl.h index f857206..90c2692 100644 --- a/cc/layers/texture_layer_impl.h +++ b/cc/layers/texture_layer_impl.h @@ -12,6 +12,7 @@ #include "cc/layers/layer_impl.h" namespace cc { +class SingleReleaseCallback; class ScopedResource; class CC_EXPORT TextureLayerImpl : public LayerImpl { @@ -61,7 +62,8 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl { virtual bool CanClipSelf() const OVERRIDE; - void SetTextureMailbox(const TextureMailbox& mailbox); + void SetTextureMailbox(const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback); private: TextureLayerImpl(LayerTreeImpl* tree_impl, int id, bool uses_mailbox); @@ -81,6 +83,7 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl { scoped_ptr<ScopedResource> texture_copy_; TextureMailbox texture_mailbox_; + scoped_ptr<SingleReleaseCallback> release_callback_; bool uses_mailbox_; bool own_mailbox_; bool valid_texture_copy_; diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index cf13ebe..3126ddb 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc @@ -255,9 +255,12 @@ class FakeTextureLayerClient : public TextureLayerClient { return context_.get(); } - virtual bool PrepareTextureMailbox(TextureMailbox* mailbox, - bool use_shared_memory) OVERRIDE { + virtual bool PrepareTextureMailbox( + TextureMailbox* mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE { *mailbox = TextureMailbox(); + *release_callback = scoped_ptr<SingleReleaseCallback>(); return true; } @@ -340,25 +343,25 @@ struct CommonMailboxObjects { mailbox_name2_); gpu::Mailbox m1; m1.SetName(reinterpret_cast<const int8*>(mailbox_name1_.data())); - mailbox1_ = TextureMailbox(m1, release_mailbox1_, sync_point1_); + mailbox1_ = TextureMailbox(m1, sync_point1_); gpu::Mailbox m2; m2.SetName(reinterpret_cast<const int8*>(mailbox_name2_.data())); - mailbox2_ = TextureMailbox(m2, release_mailbox2_, sync_point2_); + mailbox2_ = TextureMailbox(m2, sync_point2_); gfx::Size size(128, 128); EXPECT_TRUE(shared_memory_->CreateAndMapAnonymous(4 * size.GetArea())); release_mailbox3_ = base::Bind(&MockMailboxCallback::Release2, base::Unretained(&mock_callback_), shared_memory_.get()); - mailbox3_ = TextureMailbox(shared_memory_.get(), size, release_mailbox3_); + mailbox3_ = TextureMailbox(shared_memory_.get(), size); } std::string mailbox_name1_; std::string mailbox_name2_; MockMailboxCallback mock_callback_; - TextureMailbox::ReleaseCallback release_mailbox1_; - TextureMailbox::ReleaseCallback release_mailbox2_; - TextureMailbox::ReleaseCallback release_mailbox3_; + ReleaseCallback release_mailbox1_; + ReleaseCallback release_mailbox2_; + ReleaseCallback release_mailbox3_; TextureMailbox mailbox1_; TextureMailbox mailbox2_; TextureMailbox mailbox3_; @@ -400,7 +403,9 @@ TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) { EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); - test_layer->SetTextureMailbox(test_data_.mailbox1_); + test_layer->SetTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); Mock::VerifyAndClearExpectations(layer_tree_host_.get()); EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); @@ -410,7 +415,9 @@ TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) { test_data_.sync_point1_, false)) .Times(1); - test_layer->SetTextureMailbox(test_data_.mailbox2_); + test_layer->SetTextureMailbox( + test_data_.mailbox2_, + SingleReleaseCallback::Create(test_data_.release_mailbox2_)); Mock::VerifyAndClearExpectations(layer_tree_host_.get()); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); @@ -421,13 +428,16 @@ TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) { test_data_.sync_point2_, false)) .Times(1); - test_layer->SetTextureMailbox(TextureMailbox()); + test_layer->SetTextureMailbox(TextureMailbox(), + scoped_ptr<SingleReleaseCallback>()); Mock::VerifyAndClearExpectations(layer_tree_host_.get()); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); EXPECT_CALL(*layer_tree_host_, AcquireLayerTextures()).Times(0); EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); - test_layer->SetTextureMailbox(test_data_.mailbox3_); + test_layer->SetTextureMailbox( + test_data_.mailbox3_, + SingleReleaseCallback::Create(test_data_.release_mailbox3_)); Mock::VerifyAndClearExpectations(layer_tree_host_.get()); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); @@ -437,13 +447,16 @@ TEST_F(TextureLayerWithMailboxTest, ReplaceMailboxOnMainThreadBeforeCommit) { Release2(test_data_.shared_memory_.get(), 0, false)) .Times(1); - test_layer->SetTextureMailbox(TextureMailbox()); + test_layer->SetTextureMailbox(TextureMailbox(), + scoped_ptr<SingleReleaseCallback>()); Mock::VerifyAndClearExpectations(layer_tree_host_.get()); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); // Test destructor. EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); - test_layer->SetTextureMailbox(test_data_.mailbox1_); + test_layer->SetTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); } class TextureLayerMailboxHolderTest : public TextureLayerTest { @@ -465,14 +478,15 @@ class TextureLayerMailboxHolderTest : public TextureLayerTest { void CreateMainRef() { main_ref_ = TestMailboxHolder::Create( - test_data_.mailbox1_).Pass(); + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)).Pass(); } void ReleaseMainRef() { main_ref_.reset(); } - void CreateImplRef(TextureMailbox::ReleaseCallback* impl_ref) { + void CreateImplRef(scoped_ptr<SingleReleaseCallback>* impl_ref) { *impl_ref = main_ref_->holder()->GetCallbackForImplThread(); } @@ -505,7 +519,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - TextureMailbox::ReleaseCallback compositor1; + scoped_ptr<SingleReleaseCallback> compositor1; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -514,7 +528,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_BothReleaseThenMain) { // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - TextureMailbox::ReleaseCallback compositor2; + scoped_ptr<SingleReleaseCallback> compositor2; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -526,8 +540,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); + compositor2->Run(200, false); Wait(main_thread_); @@ -560,7 +574,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - TextureMailbox::ReleaseCallback compositor1; + scoped_ptr<SingleReleaseCallback> compositor1; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -569,7 +583,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleaseBetween) { // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - TextureMailbox::ReleaseCallback compositor2; + scoped_ptr<SingleReleaseCallback> compositor2; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -580,7 +594,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); // Then the main thread reference is destroyed. main_thread_.message_loop()->PostTask( @@ -598,7 +612,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); Wait(main_thread_); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); } @@ -616,7 +630,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - TextureMailbox::ReleaseCallback compositor1; + scoped_ptr<SingleReleaseCallback> compositor1; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -625,7 +639,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) { // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - TextureMailbox::ReleaseCallback compositor2; + scoped_ptr<SingleReleaseCallback> compositor2; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -642,7 +656,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_MainReleasedFirst) { base::Unretained(this))); // One compositor destroys their impl tree. - compositor2.Run(200, false); + compositor2->Run(200, false); Wait(main_thread_); @@ -654,7 +668,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); Wait(main_thread_); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); } @@ -672,7 +686,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) { // The texture layer is attached to compositor1, and passes a reference to its // impl tree. - TextureMailbox::ReleaseCallback compositor1; + scoped_ptr<SingleReleaseCallback> compositor1; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -681,7 +695,7 @@ TEST_F(TextureLayerMailboxHolderTest, TwoCompositors_SecondImplRefShortcut) { // Then the texture layer is removed and attached to compositor2, and passes a // reference to its impl tree. - TextureMailbox::ReleaseCallback compositor2; + scoped_ptr<SingleReleaseCallback> compositor2; main_thread_.message_loop()->PostTask( FROM_HERE, base::Bind(&TextureLayerMailboxHolderTest::CreateImplRef, @@ -719,7 +733,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); // Start capturing on the main thread. begin_capture.Signal(); @@ -730,7 +744,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); stop_capture.Signal(); Wait(main_thread_); @@ -753,12 +767,12 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest { void SetMailbox(char mailbox_char) { EXPECT_EQ(true, main_thread_.CalledOnValidThread()); - TextureMailbox mailbox( - std::string(64, mailbox_char), + TextureMailbox mailbox(std::string(64, mailbox_char)); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( base::Bind( &TextureLayerImplWithMailboxThreadedCallback::ReleaseCallback, base::Unretained(this))); - layer_->SetTextureMailbox(mailbox); + layer_->SetTextureMailbox(mailbox, callback.Pass()); } virtual void BeginTest() OVERRIDE { @@ -808,7 +822,8 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest { EXPECT_EQ(3, callback_count_); // Case #4: release mailbox that was committed but never drawn. The // old mailbox should be released during the next commit. - layer_->SetTextureMailbox(TextureMailbox()); + layer_->SetTextureMailbox(TextureMailbox(), + scoped_ptr<SingleReleaseCallback>()); break; case 4: if (layer_tree_host()->settings().impl_side_painting) { @@ -847,7 +862,8 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest { case 8: EXPECT_EQ(4, callback_count_); // Resetting the mailbox will call the callback now. - layer_->SetTextureMailbox(TextureMailbox()); + layer_->SetTextureMailbox(TextureMailbox(), + scoped_ptr<SingleReleaseCallback>()); EXPECT_EQ(5, callback_count_); EndTest(); break; @@ -908,8 +924,10 @@ class TextureLayerNoMailboxIsActivatedDuringCommit : public LayerTreeTest, virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE { return OffscreenContextProviderForMainThread()->Context3d(); } - virtual bool PrepareTextureMailbox(TextureMailbox* mailbox, - bool use_shared_memory) OVERRIDE { + virtual bool PrepareTextureMailbox( + TextureMailbox* mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE { return false; } @@ -1003,11 +1021,11 @@ class TextureLayerMailboxIsActivatedDuringCommit : public LayerTreeTest { static void ReleaseCallback(unsigned sync_point, bool lost_resource) {} void SetMailbox(char mailbox_char) { - TextureMailbox mailbox( - std::string(64, mailbox_char), + TextureMailbox mailbox(std::string(64, mailbox_char)); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( base::Bind( &TextureLayerMailboxIsActivatedDuringCommit::ReleaseCallback)); - layer_->SetTextureMailbox(mailbox); + layer_->SetTextureMailbox(mailbox, callback.Pass()); } virtual void BeginTest() OVERRIDE { @@ -1148,14 +1166,17 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { { scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); - impl_layer->SetTextureMailbox(test_data_.mailbox1_); + impl_layer->SetTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); } { scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); - impl_layer->SetTextureMailbox(TextureMailbox()); + impl_layer->SetTextureMailbox(TextureMailbox(), + scoped_ptr<SingleReleaseCallback>()); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); } @@ -1163,7 +1184,9 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { // Software resource. scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); - impl_layer->SetTextureMailbox(test_data_.mailbox3_); + impl_layer->SetTextureMailbox( + test_data_.mailbox3_, + SingleReleaseCallback::Create(test_data_.release_mailbox3_)); EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_HARDWARE)); } @@ -1189,14 +1212,17 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { { scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); - impl_layer->SetTextureMailbox(test_data_.mailbox1_); + impl_layer->SetTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); } { scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); - impl_layer->SetTextureMailbox(TextureMailbox()); + impl_layer->SetTextureMailbox(TextureMailbox(), + scoped_ptr<SingleReleaseCallback>()); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); } @@ -1204,7 +1230,9 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { // Software resource. scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); - impl_layer->SetTextureMailbox(test_data_.mailbox3_); + impl_layer->SetTextureMailbox( + test_data_.mailbox3_, + SingleReleaseCallback::Create(test_data_.release_mailbox3_)); EXPECT_TRUE(WillDraw(impl_layer.get(), DRAW_MODE_SOFTWARE)); } @@ -1230,7 +1258,9 @@ TEST_F(TextureLayerImplWithMailboxTest, TestWillDraw) { { scoped_ptr<TextureLayerImpl> impl_layer = TextureLayerImpl::Create(host_impl_.active_tree(), 1, true); - impl_layer->SetTextureMailbox(test_data_.mailbox1_); + impl_layer->SetTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); EXPECT_FALSE(WillDraw(impl_layer.get(), DRAW_MODE_RESOURCELESS_SOFTWARE)); } @@ -1256,7 +1286,9 @@ TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) { pending_layer->CreateLayerImpl(host_impl_.active_tree())); ASSERT_TRUE(active_layer); - pending_layer->SetTextureMailbox(test_data_.mailbox1_); + pending_layer->SetTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); // Test multiple commits without an activation. EXPECT_CALL(test_data_.mock_callback_, @@ -1264,7 +1296,9 @@ TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) { test_data_.sync_point1_, false)) .Times(1); - pending_layer->SetTextureMailbox(test_data_.mailbox2_); + pending_layer->SetTextureMailbox( + test_data_.mailbox2_, + SingleReleaseCallback::Create(test_data_.release_mailbox2_)); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); // Test callback after activation. @@ -1272,7 +1306,9 @@ TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) { active_layer->DidBecomeActive(); EXPECT_CALL(test_data_.mock_callback_, Release(_, _, _)).Times(0); - pending_layer->SetTextureMailbox(test_data_.mailbox1_); + pending_layer->SetTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); EXPECT_CALL(test_data_.mock_callback_, @@ -1286,7 +1322,8 @@ TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) { EXPECT_CALL(test_data_.mock_callback_, Release(test_data_.mailbox_name1_, _, false)) .Times(1); - pending_layer->SetTextureMailbox(TextureMailbox()); + pending_layer->SetTextureMailbox(TextureMailbox(), + scoped_ptr<SingleReleaseCallback>()); pending_layer->PushPropertiesTo(active_layer.get()); active_layer->DidBecomeActive(); Mock::VerifyAndClearExpectations(&test_data_.mock_callback_); @@ -1297,7 +1334,9 @@ TEST_F(TextureLayerImplWithMailboxTest, TestImplLayerCallbacks) { test_data_.sync_point1_, false)) .Times(1); - pending_layer->SetTextureMailbox(test_data_.mailbox1_); + pending_layer->SetTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); } TEST_F(TextureLayerImplWithMailboxTest, @@ -1309,18 +1348,23 @@ TEST_F(TextureLayerImplWithMailboxTest, EXPECT_CALL(test_data_.mock_callback_, Release(test_data_.mailbox_name1_, _, false)) .Times(1); - impl_layer->SetTextureMailbox(test_data_.mailbox1_); + impl_layer->SetTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); 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()); + impl_layer->SetTextureMailbox(TextureMailbox(), + scoped_ptr<SingleReleaseCallback>()); } TEST_F(TextureLayerImplWithMailboxTest, TestCallbackOnInUseResource) { ResourceProvider* provider = host_impl_.active_tree()->resource_provider(); ResourceProvider::ResourceId id = - provider->CreateResourceFromTextureMailbox(test_data_.mailbox1_); + provider->CreateResourceFromTextureMailbox( + test_data_.mailbox1_, + SingleReleaseCallback::Create(test_data_.release_mailbox1_)); provider->AllocateForTesting(id); // Transfer some resources to the parent. @@ -1371,7 +1415,9 @@ class TextureLayerClientTest } virtual bool PrepareTextureMailbox( - cc::TextureMailbox* mailbox, bool use_shared_memory) OVERRIDE { + TextureMailbox* mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE { return false; } @@ -1487,7 +1533,9 @@ class TextureLayerChangeInvisibleTest // TextureLayerClient implementation. virtual bool PrepareTextureMailbox( - cc::TextureMailbox* mailbox, bool use_shared_memory) OVERRIDE { + cc::TextureMailbox* mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE { return false; } @@ -1661,19 +1709,21 @@ class TextureLayerChangeInvisibleMailboxTest // TextureLayerClient implementation. virtual bool PrepareTextureMailbox( - cc::TextureMailbox* mailbox, bool use_shared_memory) OVERRIDE { + cc::TextureMailbox* mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE { ++prepare_called_; if (!mailbox_changed_) return false; *mailbox = mailbox_; + *release_callback = SingleReleaseCallback::Create( + base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased, + base::Unretained(this))); return true; } TextureMailbox MakeMailbox(char name) { - return TextureMailbox( - std::string(64, name), - base::Bind(&TextureLayerChangeInvisibleMailboxTest::MailboxReleased, - base::Unretained(this))); + return TextureMailbox(std::string(64, name)); } void MailboxReleased(unsigned sync_point, bool lost_resource) { @@ -1819,7 +1869,9 @@ class TextureLayerLostContextTest } virtual bool PrepareTextureMailbox( - cc::TextureMailbox* mailbox, bool use_shared_memory) OVERRIDE { + TextureMailbox* mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE { return false; } @@ -1880,12 +1932,12 @@ class TextureLayerWithMailboxMainThreadDeleted : public LayerTreeTest { void SetMailbox(char mailbox_char) { EXPECT_EQ(true, main_thread_.CalledOnValidThread()); - TextureMailbox mailbox( - std::string(64, mailbox_char), + TextureMailbox mailbox(std::string(64, mailbox_char)); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( base::Bind( &TextureLayerWithMailboxMainThreadDeleted::ReleaseCallback, base::Unretained(this))); - layer_->SetTextureMailbox(mailbox); + layer_->SetTextureMailbox(mailbox, callback.Pass()); } virtual void SetupTree() OVERRIDE { @@ -1952,12 +2004,12 @@ class TextureLayerWithMailboxImplThreadDeleted : public LayerTreeTest { void SetMailbox(char mailbox_char) { EXPECT_EQ(true, main_thread_.CalledOnValidThread()); - TextureMailbox mailbox( - std::string(64, mailbox_char), + TextureMailbox mailbox(std::string(64, mailbox_char)); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( base::Bind( &TextureLayerWithMailboxImplThreadDeleted::ReleaseCallback, base::Unretained(this))); - layer_->SetTextureMailbox(mailbox); + layer_->SetTextureMailbox(mailbox, callback.Pass()); } virtual void SetupTree() OVERRIDE { diff --git a/cc/layers/video_layer_impl.cc b/cc/layers/video_layer_impl.cc index 4328067..28e470e 100644 --- a/cc/layers/video_layer_impl.cc +++ b/cc/layers/video_layer_impl.cc @@ -13,6 +13,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/trees/layer_tree_impl.h" #include "cc/trees/proxy.h" #include "media/base/video_frame.h" @@ -111,10 +112,13 @@ bool VideoLayerImpl::WillDraw(DrawMode draw_mode, return true; } + DCHECK_EQ(external_resources.mailboxes.size(), + external_resources.release_callbacks.size()); for (size_t i = 0; i < external_resources.mailboxes.size(); ++i) { - frame_resources_.push_back( - resource_provider->CreateResourceFromTextureMailbox( - external_resources.mailboxes[i])); + unsigned resource_id = resource_provider->CreateResourceFromTextureMailbox( + external_resources.mailboxes[i], + SingleReleaseCallback::Create(external_resources.release_callbacks[i])); + frame_resources_.push_back(resource_id); } return true; diff --git a/cc/layers/video_layer_impl.h b/cc/layers/video_layer_impl.h index b071871..b4df141 100644 --- a/cc/layers/video_layer_impl.h +++ b/cc/layers/video_layer_impl.h @@ -9,6 +9,7 @@ #include "cc/base/cc_export.h" #include "cc/layers/layer_impl.h" +#include "cc/resources/release_callback.h" #include "cc/resources/video_resource_updater.h" namespace media { @@ -59,7 +60,8 @@ class CC_EXPORT VideoLayerImpl : public LayerImpl { // TODO(danakj): Remove these, hide software path inside ResourceProvider and // ExternalResource (aka TextureMailbox) classes. std::vector<unsigned> software_resources_; - TextureMailbox::ReleaseCallback software_release_callback_; + // Called once for each software resource. + ReleaseCallback software_release_callback_; DISALLOW_COPY_AND_ASSIGN(VideoLayerImpl); }; diff --git a/cc/output/copy_output_request.cc b/cc/output/copy_output_request.cc index 995c3f4..6163d5d 100644 --- a/cc/output/copy_output_request.cc +++ b/cc/output/copy_output_request.cc @@ -8,6 +8,7 @@ #include "base/callback_helpers.h" #include "base/logging.h" #include "cc/output/copy_output_result.h" +#include "cc/resources/single_release_callback.h" #include "cc/resources/texture_mailbox.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -40,11 +41,13 @@ void CopyOutputRequest::SendBitmapResult(scoped_ptr<SkBitmap> bitmap) { SendResult(CopyOutputResult::CreateBitmapResult(bitmap.Pass()).Pass()); } -void CopyOutputRequest::SendTextureResult(gfx::Size size, - scoped_ptr<TextureMailbox> texture) { - DCHECK(texture->IsTexture()); - SendResult(CopyOutputResult::CreateTextureResult(size, - texture.Pass()).Pass()); +void CopyOutputRequest::SendTextureResult( + gfx::Size size, + const TextureMailbox& texture_mailbox, + scoped_ptr<SingleReleaseCallback> release_callback) { + DCHECK(texture_mailbox.IsTexture()); + SendResult(CopyOutputResult::CreateTextureResult( + size, texture_mailbox, release_callback.Pass())); } } // namespace cc diff --git a/cc/output/copy_output_request.h b/cc/output/copy_output_request.h index 3f4d925..c4a9248 100644 --- a/cc/output/copy_output_request.h +++ b/cc/output/copy_output_request.h @@ -14,6 +14,7 @@ class SkBitmap; namespace cc { class CopyOutputResult; +class SingleReleaseCallback; class TextureMailbox; class CC_EXPORT CopyOutputRequest { @@ -61,7 +62,8 @@ class CC_EXPORT CopyOutputRequest { void SendEmptyResult(); void SendBitmapResult(scoped_ptr<SkBitmap> bitmap); void SendTextureResult(gfx::Size size, - scoped_ptr<TextureMailbox> texture_mailbox); + const TextureMailbox& texture_mailbox, + scoped_ptr<SingleReleaseCallback> release_callback); void SendResult(scoped_ptr<CopyOutputResult> result); diff --git a/cc/output/copy_output_result.cc b/cc/output/copy_output_result.cc index 55213cd..1831fba 100644 --- a/cc/output/copy_output_result.cc +++ b/cc/output/copy_output_result.cc @@ -5,6 +5,7 @@ #include "cc/output/copy_output_result.h" #include "base/logging.h" +#include "cc/resources/single_release_callback.h" #include "cc/resources/texture_mailbox.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -18,25 +19,32 @@ CopyOutputResult::CopyOutputResult(scoped_ptr<SkBitmap> bitmap) DCHECK(bitmap_); } -CopyOutputResult::CopyOutputResult(gfx::Size size, - scoped_ptr<TextureMailbox> texture_mailbox) +CopyOutputResult::CopyOutputResult( + gfx::Size size, + const TextureMailbox& texture_mailbox, + scoped_ptr<SingleReleaseCallback> release_callback) : size_(size), - texture_mailbox_(texture_mailbox.Pass()) { - DCHECK(texture_mailbox_); - DCHECK(texture_mailbox_->IsTexture()); + texture_mailbox_(texture_mailbox), + release_callback_(release_callback.Pass()) { + DCHECK(texture_mailbox_.IsTexture()); } CopyOutputResult::~CopyOutputResult() { - if (texture_mailbox_) - texture_mailbox_->RunReleaseCallback(0, false); + if (release_callback_) + release_callback_->Run(0, false); } scoped_ptr<SkBitmap> CopyOutputResult::TakeBitmap() { return bitmap_.Pass(); } -scoped_ptr<TextureMailbox> CopyOutputResult::TakeTexture() { - return texture_mailbox_.Pass(); +void CopyOutputResult::TakeTexture( + TextureMailbox* texture_mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback) { + *texture_mailbox = texture_mailbox_; + *release_callback = release_callback_.Pass(); + + texture_mailbox_ = TextureMailbox(); } } // namespace cc diff --git a/cc/output/copy_output_result.h b/cc/output/copy_output_result.h index 04cf2c6..c2f011d 100644 --- a/cc/output/copy_output_result.h +++ b/cc/output/copy_output_result.h @@ -7,11 +7,13 @@ #include "base/memory/scoped_ptr.h" #include "cc/base/cc_export.h" +#include "cc/resources/texture_mailbox.h" #include "ui/gfx/size.h" class SkBitmap; namespace cc { +class SingleReleaseCallback; class TextureMailbox; class CC_EXPORT CopyOutputResult { @@ -25,29 +27,34 @@ class CC_EXPORT CopyOutputResult { } static scoped_ptr<CopyOutputResult> CreateTextureResult( gfx::Size size, - scoped_ptr<TextureMailbox> texture_mailbox) { - return make_scoped_ptr(new CopyOutputResult(size, texture_mailbox.Pass())); + const TextureMailbox& texture_mailbox, + scoped_ptr<SingleReleaseCallback> release_callback) { + return make_scoped_ptr( + new CopyOutputResult(size, texture_mailbox, release_callback.Pass())); } ~CopyOutputResult(); bool IsEmpty() const { return !HasBitmap() && !HasTexture(); } bool HasBitmap() const { return !!bitmap_; } - bool HasTexture() const { return !!texture_mailbox_; } + bool HasTexture() const { return texture_mailbox_.IsValid(); } gfx::Size size() const { return size_; } scoped_ptr<SkBitmap> TakeBitmap(); - scoped_ptr<TextureMailbox> TakeTexture(); + void TakeTexture(TextureMailbox* texture_mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback); private: CopyOutputResult(); explicit CopyOutputResult(scoped_ptr<SkBitmap> bitmap); explicit CopyOutputResult(gfx::Size size, - scoped_ptr<TextureMailbox> texture_mailbox); + const TextureMailbox& texture_mailbox, + scoped_ptr<SingleReleaseCallback> release_callback); gfx::Size size_; scoped_ptr<SkBitmap> bitmap_; - scoped_ptr<TextureMailbox> texture_mailbox_; + TextureMailbox texture_mailbox_; + scoped_ptr<SingleReleaseCallback> release_callback_; }; } // namespace cc diff --git a/cc/output/gl_renderer.cc b/cc/output/gl_renderer.cc index 0b56c9d..074d603 100644 --- a/cc/output/gl_renderer.cc +++ b/cc/output/gl_renderer.cc @@ -2221,13 +2221,13 @@ void GLRenderer::GetFramebufferPixelsAsync( GL_TEXTURE_2D, mailbox.name)); GLC(context_, context_->bindTexture(GL_TEXTURE_2D, 0)); sync_point = context_->insertSyncPoint(); - scoped_ptr<TextureMailbox> texture_mailbox = make_scoped_ptr( - new TextureMailbox(mailbox, - texture_mailbox_deleter_->GetReleaseCallback( - output_surface_->context_provider(), texture_id), - GL_TEXTURE_2D, - sync_point)); - request->SendTextureResult(window_rect.size(), texture_mailbox.Pass()); + TextureMailbox texture_mailbox(mailbox, GL_TEXTURE_2D, sync_point); + scoped_ptr<SingleReleaseCallback> release_callback = + texture_mailbox_deleter_->GetReleaseCallback( + output_surface_->context_provider(), texture_id); + request->SendTextureResult(window_rect.size(), + texture_mailbox, + release_callback.Pass()); return; } diff --git a/cc/resources/release_callback.h b/cc/resources/release_callback.h new file mode 100644 index 0000000..9433f7f --- /dev/null +++ b/cc/resources/release_callback.h @@ -0,0 +1,17 @@ +// Copyright 2013 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_H_ +#define CC_RESOURCES_RELEASE_CALLBACK_H_ + +#include "base/callback.h" + +namespace cc { + +typedef base::Callback<void(unsigned sync_point, bool is_lost)> + ReleaseCallback; + +} // namespace cc + +#endif // CC_RESOURCES_RELEASE_CALLBACK_H_ diff --git a/cc/resources/resource_provider.cc b/cc/resources/resource_provider.cc index 5c8d39c..017c2e9 100644 --- a/cc/resources/resource_provider.cc +++ b/cc/resources/resource_provider.cc @@ -312,7 +312,8 @@ ResourceProvider::CreateResourceFromExternalTexture( } ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox( - const TextureMailbox& mailbox) { + const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback) { DCHECK(thread_checker_.CalledOnValidThread()); // Just store the information. Mailbox will be consumed in LockForRead(). ResourceId id = next_id_++; @@ -332,6 +333,9 @@ ResourceProvider::ResourceId ResourceProvider::CreateResourceFromTextureMailbox( resource.external = true; resource.allocated = true; resource.mailbox = mailbox; + resource.release_callback = + base::Bind(&SingleReleaseCallback::Run, + base::Owned(release_callback.release())); return id; } @@ -400,7 +404,7 @@ void ResourceProvider::DeleteResourceInternal(ResourceMap::iterator it, resource->pixels = NULL; } } - resource->mailbox.RunReleaseCallback(sync_point, lost_resource); + resource->release_callback.Run(sync_point, lost_resource); } if (resource->pixels) delete[] resource->pixels; @@ -963,9 +967,8 @@ void ResourceProvider::ReceiveReturnsFromParent( if (it->sync_point) GLC(context3d, context3d->waitSyncPoint(it->sync_point)); } else { - resource->mailbox = TextureMailbox(resource->mailbox.name(), - resource->mailbox.callback(), - it->sync_point); + resource->mailbox = + TextureMailbox(resource->mailbox.name(), it->sync_point); } if (resource->marked_for_deletion) DeleteResourceInternal(map_iterator, Normal); diff --git a/cc/resources/resource_provider.h b/cc/resources/resource_provider.h index 8b4b01b..88ff274 100644 --- a/cc/resources/resource_provider.h +++ b/cc/resources/resource_provider.h @@ -18,6 +18,8 @@ #include "cc/base/cc_export.h" #include "cc/output/context_provider.h" #include "cc/output/output_surface.h" +#include "cc/resources/release_callback.h" +#include "cc/resources/single_release_callback.h" #include "cc/resources/texture_mailbox.h" #include "cc/resources/transferable_resource.h" #include "third_party/khronos/GLES2/gl2.h" @@ -103,7 +105,9 @@ class CC_EXPORT ResourceProvider { unsigned texture_id); // Wraps an external texture mailbox into a GL resource. - ResourceId CreateResourceFromTextureMailbox(const TextureMailbox& mailbox); + ResourceId CreateResourceFromTextureMailbox( + const TextureMailbox& mailbox, + scoped_ptr<SingleReleaseCallback> release_callback); void DeleteResource(ResourceId id); @@ -354,6 +358,7 @@ class CC_EXPORT ResourceProvider { // Query used to determine when asynchronous set pixels complete. unsigned gl_upload_query_id; TextureMailbox mailbox; + ReleaseCallback release_callback; uint8_t* pixels; uint8_t* pixel_buffer; int lock_for_read_count; diff --git a/cc/resources/resource_provider_unittest.cc b/cc/resources/resource_provider_unittest.cc index afb2330..abdd78e 100644 --- a/cc/resources/resource_provider_unittest.cc +++ b/cc/resources/resource_provider_unittest.cc @@ -14,6 +14,7 @@ #include "cc/debug/test_web_graphics_context_3d.h" #include "cc/output/output_surface.h" #include "cc/resources/returned_resource.h" +#include "cc/resources/single_release_callback.h" #include "cc/test/fake_output_surface.h" #include "cc/test/fake_output_surface_client.h" #include "gpu/GLES2/gl2extchromium.h" @@ -918,11 +919,12 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) { unsigned release_sync_point = 0; bool lost_resource = false; - TextureMailbox::ReleaseCallback callback = + ReleaseCallback callback = base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource); ResourceProvider::ResourceId resource = resource_provider_->CreateResourceFromTextureMailbox( - TextureMailbox(mailbox, callback, sync_point)); + TextureMailbox(mailbox, sync_point), + SingleReleaseCallback::Create(callback)); EXPECT_EQ(1, context()->texture_count()); EXPECT_EQ(0u, release_sync_point); { @@ -968,7 +970,8 @@ TEST_P(ResourceProviderTest, TransferMailboxResources) { EXPECT_LT(0u, sync_point); release_sync_point = 0; resource = resource_provider_->CreateResourceFromTextureMailbox( - TextureMailbox(mailbox, callback, sync_point)); + TextureMailbox(mailbox, sync_point), + SingleReleaseCallback::Create(callback)); EXPECT_EQ(1, context()->texture_count()); EXPECT_EQ(0u, release_sync_point); { @@ -1030,10 +1033,11 @@ TEST_P(ResourceProviderTest, Shutdown) { unsigned release_sync_point = 0; bool lost_resource = false; - TextureMailbox::ReleaseCallback callback = - base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( + base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource)); resource_provider_->CreateResourceFromTextureMailbox( - TextureMailbox(mailbox, callback, sync_point)); + TextureMailbox(mailbox, sync_point), + callback.Pass()); EXPECT_EQ(0u, release_sync_point); EXPECT_FALSE(lost_resource); @@ -1069,10 +1073,11 @@ TEST_P(ResourceProviderTest, ShutdownSharedMemory) { CreateAndFillSharedMemory(size, 0)); bool release_called = false; - TextureMailbox::ReleaseCallback callback = - base::Bind(ReleaseSharedMemoryCallback, &release_called); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( + base::Bind(ReleaseSharedMemoryCallback, &release_called)); resource_provider_->CreateResourceFromTextureMailbox( - TextureMailbox(shared_memory.get(), size, callback)); + TextureMailbox(shared_memory.get(), size), + callback.Pass()); resource_provider_.reset(); @@ -1094,11 +1099,12 @@ TEST_P(ResourceProviderTest, ShutdownWithExportedResource) { unsigned release_sync_point = 0; bool lost_resource = false; - TextureMailbox::ReleaseCallback callback = - base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( + base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource)); ResourceProvider::ResourceId resource = resource_provider_->CreateResourceFromTextureMailbox( - TextureMailbox(mailbox, callback, sync_point)); + TextureMailbox(mailbox, sync_point), + callback.Pass()); // Transfer the resource, so we can't release it properly on shutdown. ResourceProvider::ResourceIdArray resource_ids_to_transfer; @@ -1131,10 +1137,11 @@ TEST_P(ResourceProviderTest, LostContext) { unsigned release_sync_point = 0; bool lost_resource = false; - TextureMailbox::ReleaseCallback callback = - base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( + base::Bind(ReleaseTextureMailbox, &release_sync_point, &lost_resource)); resource_provider_->CreateResourceFromTextureMailbox( - TextureMailbox(mailbox, callback, sync_point)); + TextureMailbox(mailbox, sync_point), + callback.Pass()); EXPECT_EQ(0u, release_sync_point); EXPECT_FALSE(lost_resource); @@ -1341,11 +1348,13 @@ TEST_P(ResourceProviderTest, TextureMailbox_SharedMemory) { scoped_ptr<ResourceProvider> resource_provider( ResourceProvider::Create(output_surface.get(), 0)); - TextureMailbox::ReleaseCallback callback = base::Bind(&EmptyReleaseCallback); - TextureMailbox mailbox(shared_memory.get(), size, callback); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( + base::Bind(&EmptyReleaseCallback)); + TextureMailbox mailbox(shared_memory.get(), size); ResourceProvider::ResourceId id = - resource_provider->CreateResourceFromTextureMailbox(mailbox); + resource_provider->CreateResourceFromTextureMailbox( + mailbox, callback.Pass()); EXPECT_NE(0u, id); { @@ -1386,14 +1395,14 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTexture2D) { gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - TextureMailbox::ReleaseCallback callback = base::Bind(&EmptyReleaseCallback); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( + base::Bind(&EmptyReleaseCallback)); - TextureMailbox mailbox(gpu_mailbox, - callback, - sync_point); + TextureMailbox mailbox(gpu_mailbox, sync_point); ResourceProvider::ResourceId id = - resource_provider->CreateResourceFromTextureMailbox(mailbox); + resource_provider->CreateResourceFromTextureMailbox( + mailbox, callback.Pass()); EXPECT_NE(0u, id); Mock::VerifyAndClearExpectations(context); @@ -1450,15 +1459,14 @@ TEST_P(ResourceProviderTest, TextureMailbox_GLTextureExternalOES) { gpu::Mailbox gpu_mailbox; memcpy(gpu_mailbox.name, "Hello world", strlen("Hello world") + 1); - TextureMailbox::ReleaseCallback callback = base::Bind(&EmptyReleaseCallback); + scoped_ptr<SingleReleaseCallback> callback = SingleReleaseCallback::Create( + base::Bind(&EmptyReleaseCallback)); - TextureMailbox mailbox(gpu_mailbox, - callback, - target, - sync_point); + TextureMailbox mailbox(gpu_mailbox, target, sync_point); ResourceProvider::ResourceId id = - resource_provider->CreateResourceFromTextureMailbox(mailbox); + resource_provider->CreateResourceFromTextureMailbox( + mailbox, callback.Pass()); EXPECT_NE(0u, id); Mock::VerifyAndClearExpectations(context); diff --git a/cc/resources/single_release_callback.cc b/cc/resources/single_release_callback.cc new file mode 100644 index 0000000..9c6b9de --- /dev/null +++ b/cc/resources/single_release_callback.cc @@ -0,0 +1,29 @@ +// Copyright 2013 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.h" + +#include "base/callback_helpers.h" +#include "base/logging.h" + +namespace cc { + +SingleReleaseCallback::SingleReleaseCallback(const ReleaseCallback& callback) + : has_been_run_(false), callback_(callback) { + DCHECK(!callback_.is_null()) + << "Use a NULL SingleReleaseCallback for an empty callback."; +} + +SingleReleaseCallback::~SingleReleaseCallback() { + DCHECK(callback_.is_null() || has_been_run_) + << "SingleReleaseCallback was never run."; +} + +void SingleReleaseCallback::Run(unsigned sync_point, bool is_lost) { + DCHECK(!has_been_run_) << "SingleReleaseCallback was run more than once."; + has_been_run_ = true; + callback_.Run(sync_point, is_lost); +} + +} // namespace cc diff --git a/cc/resources/single_release_callback.h b/cc/resources/single_release_callback.h new file mode 100644 index 0000000..fe1a3ba --- /dev/null +++ b/cc/resources/single_release_callback.h @@ -0,0 +1,33 @@ +// Copyright 2013 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_H_ +#define CC_RESOURCES_SINGLE_RELEASE_CALLBACK_H_ + +#include "base/memory/scoped_ptr.h" +#include "cc/base/cc_export.h" +#include "cc/resources/release_callback.h" + +namespace cc { + +class CC_EXPORT SingleReleaseCallback { + public: + static scoped_ptr<SingleReleaseCallback> Create(const ReleaseCallback& cb) { + return make_scoped_ptr(new SingleReleaseCallback(cb)); + } + + ~SingleReleaseCallback(); + + void Run(unsigned sync_point, bool is_lost); + + private: + explicit SingleReleaseCallback(const ReleaseCallback& callback); + + bool has_been_run_; + ReleaseCallback callback_; +}; + +} // namespace cc + +#endif // CC_RESOURCES_SINGLE_RELEASE_CALLBACK_H_ diff --git a/cc/resources/texture_mailbox.cc b/cc/resources/texture_mailbox.cc index 2a8f570..149d56c 100644 --- a/cc/resources/texture_mailbox.cc +++ b/cc/resources/texture_mailbox.cc @@ -4,7 +4,6 @@ #include "cc/resources/texture_mailbox.h" -#include "base/callback_helpers.h" #include "base/logging.h" #include "third_party/khronos/GLES2/gl2.h" @@ -16,69 +15,48 @@ TextureMailbox::TextureMailbox() shared_memory_(NULL) { } -TextureMailbox::TextureMailbox( - const std::string& mailbox_name, - const ReleaseCallback& callback) - : callback_(callback), - target_(GL_TEXTURE_2D), +TextureMailbox::TextureMailbox(const std::string& mailbox_name) + : target_(GL_TEXTURE_2D), sync_point_(0), shared_memory_(NULL) { - DCHECK(mailbox_name.empty() == callback.is_null()); if (!mailbox_name.empty()) { CHECK(mailbox_name.size() == sizeof(name_.name)); name_.SetName(reinterpret_cast<const int8*>(mailbox_name.data())); } } -TextureMailbox::TextureMailbox( - const gpu::Mailbox& mailbox_name, - const ReleaseCallback& callback) - : callback_(callback), - target_(GL_TEXTURE_2D), +TextureMailbox::TextureMailbox(const gpu::Mailbox& mailbox_name) + : target_(GL_TEXTURE_2D), sync_point_(0), shared_memory_(NULL) { - DCHECK(mailbox_name.IsZero() == callback.is_null()); name_.SetName(mailbox_name.name); } -TextureMailbox::TextureMailbox( - const gpu::Mailbox& mailbox_name, - const ReleaseCallback& callback, - unsigned sync_point) - : callback_(callback), - target_(GL_TEXTURE_2D), +TextureMailbox::TextureMailbox(const gpu::Mailbox& mailbox_name, + unsigned sync_point) + : target_(GL_TEXTURE_2D), sync_point_(sync_point), shared_memory_(NULL) { - DCHECK(mailbox_name.IsZero() == callback.is_null()); name_.SetName(mailbox_name.name); } -TextureMailbox::TextureMailbox( - const gpu::Mailbox& mailbox_name, - const ReleaseCallback& callback, - unsigned texture_target, - unsigned sync_point) - : callback_(callback), - target_(texture_target), +TextureMailbox::TextureMailbox(const gpu::Mailbox& mailbox_name, + unsigned texture_target, + unsigned sync_point) + : target_(texture_target), sync_point_(sync_point), shared_memory_(NULL) { - DCHECK(mailbox_name.IsZero() == callback.is_null()); name_.SetName(mailbox_name.name); } -TextureMailbox::TextureMailbox( - base::SharedMemory* shared_memory, - gfx::Size size, - const ReleaseCallback& callback) - : callback_(callback), - target_(GL_TEXTURE_2D), +TextureMailbox::TextureMailbox(base::SharedMemory* shared_memory, + gfx::Size size) + : target_(GL_TEXTURE_2D), sync_point_(0), shared_memory_(shared_memory), - shared_memory_size_(size) { -} + shared_memory_size_(size) {} -TextureMailbox::~TextureMailbox() { -} +TextureMailbox::~TextureMailbox() {} bool TextureMailbox::Equals(const TextureMailbox& other) const { if (other.IsTexture()) @@ -103,19 +81,6 @@ void TextureMailbox::SetName(const gpu::Mailbox& name) { name_ = name; } -void TextureMailbox::RunReleaseCallback(unsigned sync_point, - bool lost_resource) { - if (!callback_.is_null()) - base::ResetAndReturn(&callback_).Run(sync_point, lost_resource); -} - -TextureMailbox TextureMailbox::CopyWithNewCallback( - const ReleaseCallback& callback) const { - TextureMailbox result(*this); - result.callback_ = callback; - return result; -} - size_t TextureMailbox::shared_memory_size_in_bytes() const { return 4 * shared_memory_size_.GetArea(); } diff --git a/cc/resources/texture_mailbox.h b/cc/resources/texture_mailbox.h index 9490939..a9b021b 100644 --- a/cc/resources/texture_mailbox.h +++ b/cc/resources/texture_mailbox.h @@ -19,23 +19,16 @@ namespace cc { // can hold a shared memory resource as well as a texture mailbox. class CC_EXPORT TextureMailbox { public: - typedef base::Callback<void(unsigned sync_point, - bool lost_resource)> ReleaseCallback; TextureMailbox(); - TextureMailbox(const std::string& mailbox_name, - const ReleaseCallback& callback); + explicit TextureMailbox(const std::string& mailbox_name); + explicit TextureMailbox(const gpu::Mailbox& mailbox_name); TextureMailbox(const gpu::Mailbox& mailbox_name, - const ReleaseCallback& callback); - TextureMailbox(const gpu::Mailbox& mailbox_name, - const ReleaseCallback& callback, unsigned sync_point); TextureMailbox(const gpu::Mailbox& mailbox_name, - const ReleaseCallback& callback, unsigned texture_target, unsigned sync_point); TextureMailbox(base::SharedMemory* shared_memory, - gfx::Size size, - const ReleaseCallback& callback); + gfx::Size size); ~TextureMailbox(); @@ -61,16 +54,8 @@ class CC_EXPORT TextureMailbox { // storing a TextureMailbox in ResourceProvider. Then we can remove this. void SetName(const gpu::Mailbox& name); - // TODO(danakj): ReleaseCallback should be a separate scoped_ptr outside this - // class to avoid silently adding references to the callback's internals. - void RunReleaseCallback(unsigned sync_point, bool lost_resource); - - TextureMailbox CopyWithNewCallback(const ReleaseCallback& callback) const; - const ReleaseCallback& callback() const { return callback_; } - private: gpu::Mailbox name_; - ReleaseCallback callback_; unsigned target_; unsigned sync_point_; base::SharedMemory* shared_memory_; diff --git a/cc/resources/texture_mailbox_deleter.cc b/cc/resources/texture_mailbox_deleter.cc index ed611e4..ae6df17 100644 --- a/cc/resources/texture_mailbox_deleter.cc +++ b/cc/resources/texture_mailbox_deleter.cc @@ -9,6 +9,7 @@ #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop_proxy.h" #include "cc/output/context_provider.h" +#include "cc/resources/single_release_callback.h" #include "third_party/WebKit/public/platform/WebGraphicsContext3D.h" namespace cc { @@ -25,7 +26,7 @@ static void DeleteTextureOnImplThread( static void PostTaskFromMainToImplThread( scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, - TextureMailbox::ReleaseCallback run_impl_callback, + ReleaseCallback run_impl_callback, unsigned sync_point, bool is_lost) { // This posts the task to RunDeleteTextureOnImplThread(). @@ -40,43 +41,45 @@ TextureMailboxDeleter::~TextureMailboxDeleter() { impl_callbacks_.at(i)->Run(0, true); } -TextureMailbox::ReleaseCallback TextureMailboxDeleter::GetReleaseCallback( +scoped_ptr<SingleReleaseCallback> TextureMailboxDeleter::GetReleaseCallback( const scoped_refptr<ContextProvider>& context_provider, unsigned texture_id) { // This callback owns a reference on the |context_provider|. It must be // destroyed on the impl thread. Upon destruction of this class, the // callback must immediately be destroyed. - scoped_ptr<TextureMailbox::ReleaseCallback> impl_callback( - new TextureMailbox::ReleaseCallback(base::Bind( - &DeleteTextureOnImplThread, context_provider, texture_id))); + scoped_ptr<SingleReleaseCallback> impl_callback = + SingleReleaseCallback::Create(base::Bind(&DeleteTextureOnImplThread, + context_provider, + texture_id)); impl_callbacks_.push_back(impl_callback.Pass()); // The raw pointer to the impl-side callback is valid as long as this // class is alive. So we guard it with a WeakPtr. - TextureMailbox::ReleaseCallback run_impl_callback = + ReleaseCallback run_impl_callback( base::Bind(&TextureMailboxDeleter::RunDeleteTextureOnImplThread, weak_ptr_factory_.GetWeakPtr(), - impl_callbacks_.back()); + impl_callbacks_.back())); // Provide a callback for the main thread that posts back to the impl // thread. - TextureMailbox::ReleaseCallback main_callback = - base::Bind(&PostTaskFromMainToImplThread, - base::MessageLoopProxy::current(), - run_impl_callback); + scoped_ptr<SingleReleaseCallback> main_callback = + SingleReleaseCallback::Create(base::Bind( + &PostTaskFromMainToImplThread, + base::MessageLoopProxy::current(), + run_impl_callback)); - return main_callback; + return main_callback.Pass(); } void TextureMailboxDeleter::RunDeleteTextureOnImplThread( - TextureMailbox::ReleaseCallback* impl_callback, + SingleReleaseCallback* impl_callback, unsigned sync_point, bool is_lost) { for (size_t i = 0; i < impl_callbacks_.size(); ++i) { - if (impl_callbacks_.at(i)->Equals(*impl_callback)) { + if (impl_callbacks_.at(i) == impl_callback) { // Run the callback, then destroy it here on the impl thread. - impl_callback->Run(sync_point, is_lost); + impl_callbacks_.at(i)->Run(sync_point, is_lost); impl_callbacks_.erase(impl_callbacks_.begin() + i); return; } diff --git a/cc/resources/texture_mailbox_deleter.h b/cc/resources/texture_mailbox_deleter.h index 608dd7a..072dcab 100644 --- a/cc/resources/texture_mailbox_deleter.h +++ b/cc/resources/texture_mailbox_deleter.h @@ -8,10 +8,10 @@ #include "base/memory/weak_ptr.h" #include "cc/base/cc_export.h" #include "cc/base/scoped_ptr_vector.h" -#include "cc/resources/texture_mailbox.h" namespace cc { class ContextProvider; +class SingleReleaseCallback; class CC_EXPORT TextureMailboxDeleter { public: @@ -25,7 +25,7 @@ class CC_EXPORT TextureMailboxDeleter { // due to the compositor shutting down, then the ReleaseCallback will // become a no-op and the texture will be deleted immediately on the // impl thread, along with dropping the reference to the ContextProvider. - TextureMailbox::ReleaseCallback GetReleaseCallback( + scoped_ptr<SingleReleaseCallback> GetReleaseCallback( const scoped_refptr<ContextProvider>& context_provider, unsigned texture_id); @@ -33,12 +33,12 @@ class CC_EXPORT TextureMailboxDeleter { // Runs the |impl_callback| to delete the texture and removes the callback // from the |impl_callbacks_| list. void RunDeleteTextureOnImplThread( - TextureMailbox::ReleaseCallback* impl_callback, + SingleReleaseCallback* impl_callback, unsigned sync_point, bool is_lost); base::WeakPtrFactory<TextureMailboxDeleter> weak_ptr_factory_; - ScopedPtrVector<TextureMailbox::ReleaseCallback> impl_callbacks_; + ScopedPtrVector<SingleReleaseCallback> impl_callbacks_; }; } // namespace cc diff --git a/cc/resources/texture_mailbox_deleter_unittest.cc b/cc/resources/texture_mailbox_deleter_unittest.cc index e08984e..a6ec48e 100644 --- a/cc/resources/texture_mailbox_deleter_unittest.cc +++ b/cc/resources/texture_mailbox_deleter_unittest.cc @@ -6,6 +6,7 @@ #include "cc/debug/test_context_provider.h" #include "cc/debug/test_web_graphics_context_3d.h" +#include "cc/resources/single_release_callback.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { @@ -23,8 +24,8 @@ TEST(TextureMailboxDeleterTest, Destroy) { EXPECT_TRUE(context_provider->HasOneRef()); EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); - TextureMailbox::ReleaseCallback cb = - deleter->GetReleaseCallback(context_provider, texture_id); + scoped_ptr<SingleReleaseCallback> cb = + deleter->GetReleaseCallback(context_provider, texture_id).Pass(); EXPECT_FALSE(context_provider->HasOneRef()); EXPECT_EQ(1u, context_provider->TestContext3d()->NumTextures()); @@ -33,6 +34,10 @@ TEST(TextureMailboxDeleterTest, Destroy) { deleter.reset(); EXPECT_TRUE(context_provider->HasOneRef()); EXPECT_EQ(0u, context_provider->TestContext3d()->NumTextures()); + + // Run the scoped release callback before destroying it, but it won't do + // anything. + cb->Run(0, false); } } // namespace diff --git a/cc/resources/video_resource_updater.cc b/cc/resources/video_resource_updater.cc index f278c59..d07ff35 100644 --- a/cc/resources/video_resource_updater.cc +++ b/cc/resources/video_resource_updater.cc @@ -271,13 +271,12 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( plane_resources[0].resource_format, gpu::Mailbox() }; - TextureMailbox::ReleaseCallback callback_to_free_resource = - base::Bind(&RecycleResource, - AsWeakPtr(), - recycle_data); + external_resources.software_resources.push_back( plane_resources[0].resource_id); - external_resources.software_release_callback = callback_to_free_resource; + external_resources.software_release_callback = + base::Bind(&RecycleResource, AsWeakPtr(), recycle_data); + external_resources.type = VideoFrameExternalResources::SOFTWARE_RESOURCE; return external_resources; @@ -307,13 +306,11 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( plane_resources[i].resource_format, plane_resources[i].mailbox }; - TextureMailbox::ReleaseCallback callback_to_free_resource = - base::Bind(&RecycleResource, - AsWeakPtr(), - recycle_data); + external_resources.mailboxes.push_back( - TextureMailbox(plane_resources[i].mailbox, - callback_to_free_resource)); + TextureMailbox(plane_resources[i].mailbox)); + external_resources.release_callbacks.push_back( + base::Bind(&RecycleResource, AsWeakPtr(), recycle_data)); } external_resources.type = VideoFrameExternalResources::YUV_RESOURCE; @@ -358,14 +355,12 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForHardwarePlanes( scoped_refptr<media::VideoFrame::MailboxHolder> mailbox_holder = video_frame->texture_mailbox(); - TextureMailbox::ReleaseCallback callback_to_return_resource = - base::Bind(&ReturnTexture, mailbox_holder); - external_resources.mailboxes.push_back( TextureMailbox(mailbox_holder->mailbox(), - callback_to_return_resource, video_frame->texture_target(), mailbox_holder->sync_point())); + external_resources.release_callbacks.push_back( + base::Bind(&ReturnTexture, mailbox_holder)); return external_resources; } diff --git a/cc/resources/video_resource_updater.h b/cc/resources/video_resource_updater.h index cf71cfa..d0e9f9c 100644 --- a/cc/resources/video_resource_updater.h +++ b/cc/resources/video_resource_updater.h @@ -12,6 +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/texture_mailbox.h" #include "ui/gfx/size.h" @@ -48,10 +49,11 @@ class CC_EXPORT VideoFrameExternalResources { ResourceType type; std::vector<TextureMailbox> mailboxes; + std::vector<ReleaseCallback> release_callbacks; // TODO(danakj): Remove these too. std::vector<unsigned> software_resources; - TextureMailbox::ReleaseCallback software_release_callback; + ReleaseCallback software_release_callback; VideoFrameExternalResources(); ~VideoFrameExternalResources(); diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index 16d7187..1d38e64 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc @@ -125,8 +125,10 @@ scoped_refptr<SolidColorLayer> LayerTreePixelTest::CreateSolidColorLayer( void LayerTreePixelTest::EndTest() { // Drop TextureMailboxes on the main thread so that they can be cleaned up and // the pending callbacks will fire. - for (size_t i = 0; i < texture_layers_.size(); ++i) - texture_layers_[i]->SetTextureMailbox(TextureMailbox()); + for (size_t i = 0; i < texture_layers_.size(); ++i) { + texture_layers_[i]->SetTextureMailbox(TextureMailbox(), + scoped_ptr<SingleReleaseCallback>()); + } TryEndTest(); } @@ -174,7 +176,12 @@ scoped_refptr<TextureLayer> LayerTreePixelTest::CreateTextureLayer( layer->SetAnchorPoint(gfx::PointF()); layer->SetBounds(rect.size()); layer->SetPosition(rect.origin()); - layer->SetTextureMailbox(CopyBitmapToTextureMailboxAsTexture(bitmap)); + + TextureMailbox texture_mailbox; + scoped_ptr<SingleReleaseCallback> release_callback; + CopyBitmapToTextureMailboxAsTexture( + bitmap, &texture_mailbox, &release_callback); + layer->SetTextureMailbox(texture_mailbox, release_callback.Pass()); texture_layers_.push_back(layer); pending_texture_mailbox_callbacks_++; @@ -301,8 +308,10 @@ void LayerTreePixelTest::ReleaseTextureMailbox( TryEndTest(); } -TextureMailbox LayerTreePixelTest::CopyBitmapToTextureMailboxAsTexture( - const SkBitmap& bitmap) { +void LayerTreePixelTest::CopyBitmapToTextureMailboxAsTexture( + const SkBitmap& bitmap, + TextureMailbox* texture_mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback) { DCHECK_GT(bitmap.width(), 0); DCHECK_GT(bitmap.height(), 0); @@ -364,13 +373,12 @@ TextureMailbox LayerTreePixelTest::CopyBitmapToTextureMailboxAsTexture( context3d->bindTexture(GL_TEXTURE_2D, 0); uint32 sync_point = context3d->insertSyncPoint(); - return TextureMailbox( - mailbox, + *texture_mailbox = TextureMailbox(mailbox, sync_point); + *release_callback = SingleReleaseCallback::Create( base::Bind(&LayerTreePixelTest::ReleaseTextureMailbox, base::Unretained(this), base::Passed(&context3d), - texture_id), - sync_point); + texture_id)); } } // namespace cc diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h index 82fffb4..2fdf2a6 100644 --- a/cc/test/layer_tree_pixel_test.h +++ b/cc/test/layer_tree_pixel_test.h @@ -7,6 +7,7 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "cc/resources/single_release_callback.h" #include "cc/test/layer_tree_test.h" #ifndef CC_TEST_LAYER_TREE_PIXEL_TEST_H_ @@ -75,7 +76,10 @@ class LayerTreePixelTest : public LayerTreeTest { gfx::Size size, const TextureMailbox& texture_mailbox); - TextureMailbox CopyBitmapToTextureMailboxAsTexture(const SkBitmap& bitmap); + void CopyBitmapToTextureMailboxAsTexture( + const SkBitmap& bitmap, + TextureMailbox* texture_mailbox, + scoped_ptr<SingleReleaseCallback>* release_callback); void ReleaseTextureMailbox( scoped_ptr<WebKit::WebGraphicsContext3D> context3d, diff --git a/cc/trees/layer_tree_host_pixeltest_readback.cc b/cc/trees/layer_tree_host_pixeltest_readback.cc index 1c8380b..28b80b9 100644 --- a/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/cc/trees/layer_tree_host_pixeltest_readback.cc @@ -58,13 +58,15 @@ class LayerTreeHostReadbackPixelTest : public LayerTreePixelTest { EXPECT_TRUE(proxy()->IsMainThread()); EXPECT_TRUE(result->HasTexture()); - scoped_ptr<TextureMailbox> texture_mailbox = result->TakeTexture().Pass(); - EXPECT_TRUE(texture_mailbox->IsValid()); - EXPECT_TRUE(texture_mailbox->IsTexture()); + TextureMailbox texture_mailbox; + scoped_ptr<SingleReleaseCallback> release_callback; + result->TakeTexture(&texture_mailbox, &release_callback); + EXPECT_TRUE(texture_mailbox.IsValid()); + EXPECT_TRUE(texture_mailbox.IsTexture()); scoped_ptr<SkBitmap> bitmap = - CopyTextureMailboxToBitmap(result->size(), *texture_mailbox); - texture_mailbox->RunReleaseCallback(0, false); + CopyTextureMailboxToBitmap(result->size(), texture_mailbox); + release_callback->Run(0, false); ReadbackResultAsBitmap(CopyOutputResult::CreateBitmapResult(bitmap.Pass())); } |