diff options
42 files changed, 603 insertions, 371 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())); } diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 42e1869..ae2806e 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc @@ -21,6 +21,7 @@ #include "cc/output/compositor_frame_ack.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" +#include "cc/resources/single_release_callback.h" #include "cc/trees/layer_tree_host.h" #include "content/browser/accessibility/browser_accessibility_manager_android.h" #include "content/browser/android/content_view_core_impl.h" @@ -90,12 +91,12 @@ void SendImeEventAck(RenderWidgetHostImpl* host) { void CopyFromCompositingSurfaceFinished( const base::Callback<void(bool, const SkBitmap&)>& callback, - const cc::TextureMailbox::ReleaseCallback& release_callback, + scoped_ptr<cc::SingleReleaseCallback> release_callback, scoped_ptr<SkBitmap> bitmap, scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, bool result) { bitmap_pixels_lock.reset(); - release_callback.Run(0, false); + release_callback->Run(0, false); callback.Run(result, *bitmap); } @@ -1199,6 +1200,7 @@ WebKit::WebGraphicsContext3D* RenderWidgetHostViewAndroid::Context3d() { bool RenderWidgetHostViewAndroid::PrepareTextureMailbox( cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback, bool use_shared_memory) { return false; } @@ -1239,23 +1241,25 @@ void RenderWidgetHostViewAndroid::PrepareTextureCopyOutputResult( new SkAutoLockPixels(*bitmap)); uint8* pixels = static_cast<uint8*>(bitmap->getPixels()); - scoped_ptr<cc::TextureMailbox> texture_mailbox = result->TakeTexture(); - DCHECK(texture_mailbox->IsTexture()); - if (!texture_mailbox->IsTexture()) + cc::TextureMailbox texture_mailbox; + scoped_ptr<cc::SingleReleaseCallback> release_callback; + result->TakeTexture(&texture_mailbox, &release_callback); + DCHECK(texture_mailbox.IsTexture()); + if (!texture_mailbox.IsTexture()) return; ignore_result(scoped_callback_runner.Release()); gl_helper->CropScaleReadbackAndCleanMailbox( - texture_mailbox->name(), - texture_mailbox->sync_point(), + texture_mailbox.name(), + texture_mailbox.sync_point(), result->size(), gfx::Rect(result->size()), dst_size_in_pixel, pixels, base::Bind(&CopyFromCompositingSurfaceFinished, callback, - texture_mailbox->callback(), + base::Passed(&release_callback), base::Passed(&bitmap), base::Passed(&bitmap_pixels_lock))); } diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h index f541361..6f24807 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.h +++ b/content/browser/renderer_host/render_widget_host_view_android.h @@ -36,6 +36,7 @@ namespace cc { class CopyOutputResult; class DelegatedRendererLayer; class Layer; +class SingleReleaseCallback; class TextureLayer; } @@ -187,8 +188,10 @@ class RenderWidgetHostViewAndroid // cc::TextureLayerClient implementation. virtual unsigned PrepareTexture() OVERRIDE; virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE; - virtual bool PrepareTextureMailbox(cc::TextureMailbox* mailbox, - bool use_shared_memory) OVERRIDE; + virtual bool PrepareTextureMailbox( + cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE; // cc::DelegatedRendererLayerClient implementation. virtual void DidCommitFrameData() OVERRIDE; diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index 7abad81..2861b16 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -102,10 +102,10 @@ class MemoryHolder : public base::RefCounted<MemoryHolder> { frame_size_(frame_size), callback_(callback) {} - cc::TextureMailbox GetMailbox() { - return cc::TextureMailbox( - shared_memory_.get(), - frame_size_, + void GetMailbox(cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback) { + *mailbox = cc::TextureMailbox(shared_memory_.get(), frame_size_); + *release_callback = cc::SingleReleaseCallback::Create( base::Bind(ReleaseMailbox, make_scoped_refptr(this))); } @@ -1273,8 +1273,11 @@ void RenderWidgetHostViewAura::UpdateExternalTexture() { CheckResizeLock(); framebuffer_holder_ = NULL; } else if (is_compositing_active && framebuffer_holder_) { - cc::TextureMailbox mailbox = framebuffer_holder_->GetMailbox(); + cc::TextureMailbox mailbox; + scoped_ptr<cc::SingleReleaseCallback> callback; + framebuffer_holder_->GetMailbox(&mailbox, &callback); window_->layer()->SetTextureMailbox(mailbox, + callback.Pass(), last_swapped_surface_scale_factor_); current_frame_size_ = ConvertSizeToDIP(last_swapped_surface_scale_factor_, mailbox.shared_memory_size()); @@ -1531,13 +1534,17 @@ void RenderWidgetHostViewAura::SwapSoftwareFrame( frame_data->id))); bool first_frame = !framebuffer_holder_; framebuffer_holder_.swap(holder); - cc::TextureMailbox mailbox = framebuffer_holder_->GetMailbox(); + cc::TextureMailbox mailbox; + scoped_ptr<cc::SingleReleaseCallback> callback; + framebuffer_holder_->GetMailbox(&mailbox, &callback); DCHECK(mailbox.IsSharedMemory()); current_frame_size_ = frame_size_in_dip; released_front_lock_ = NULL; CheckResizeLock(); - window_->layer()->SetTextureMailbox(mailbox, frame_device_scale_factor); + window_->layer()->SetTextureMailbox(mailbox, + callback.Pass(), + frame_device_scale_factor); window_->SchedulePaintInRect( ConvertRectToDIP(frame_device_scale_factor, damage_rect)); @@ -1772,12 +1779,12 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResult( static void CopyFromCompositingSurfaceFinished( const base::Callback<void(bool, const SkBitmap&)>& callback, - const cc::TextureMailbox::ReleaseCallback& release_callback, + scoped_ptr<cc::SingleReleaseCallback> release_callback, scoped_ptr<SkBitmap> bitmap, scoped_ptr<SkAutoLockPixels> bitmap_pixels_lock, bool result) { bitmap_pixels_lock.reset(); - release_callback.Run(0, false); + release_callback->Run(0, false); callback.Run(result, *bitmap); } @@ -1809,23 +1816,25 @@ void RenderWidgetHostViewAura::PrepareTextureCopyOutputResult( new SkAutoLockPixels(*bitmap)); uint8* pixels = static_cast<uint8*>(bitmap->getPixels()); - scoped_ptr<cc::TextureMailbox> texture_mailbox = result->TakeTexture(); - DCHECK(texture_mailbox->IsTexture()); - if (!texture_mailbox->IsTexture()) + cc::TextureMailbox texture_mailbox; + scoped_ptr<cc::SingleReleaseCallback> release_callback; + result->TakeTexture(&texture_mailbox, &release_callback); + DCHECK(texture_mailbox.IsTexture()); + if (!texture_mailbox.IsTexture()) return; ignore_result(scoped_callback_runner.Release()); gl_helper->CropScaleReadbackAndCleanMailbox( - texture_mailbox->name(), - texture_mailbox->sync_point(), + texture_mailbox.name(), + texture_mailbox.sync_point(), result->size(), gfx::Rect(result->size()), dst_size_in_pixel, pixels, base::Bind(&CopyFromCompositingSurfaceFinished, callback, - texture_mailbox->callback(), + base::Passed(&release_callback), base::Passed(&bitmap), base::Passed(&bitmap_pixels_lock))); } @@ -1859,9 +1868,9 @@ void RenderWidgetHostViewAura::PrepareBitmapCopyOutputResult( static void CopyFromCompositingSurfaceFinishedForVideo( const base::Callback<void(bool)>& callback, - const cc::TextureMailbox::ReleaseCallback& release_callback, + scoped_ptr<cc::SingleReleaseCallback> release_callback, bool result) { - release_callback.Run(0, false); + release_callback->Run(0, false); callback.Run(result); } @@ -1934,9 +1943,11 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResultForVideo( if (!gl_helper) return; - scoped_ptr<cc::TextureMailbox> texture_mailbox = result->TakeTexture(); - DCHECK(texture_mailbox->IsTexture()); - if (!texture_mailbox->IsTexture()) + cc::TextureMailbox texture_mailbox; + scoped_ptr<cc::SingleReleaseCallback> release_callback; + result->TakeTexture(&texture_mailbox, &release_callback); + DCHECK(texture_mailbox.IsTexture()); + if (!texture_mailbox.IsTexture()) return; gfx::Rect result_rect(result->size()); @@ -1978,10 +1989,10 @@ void RenderWidgetHostViewAura::CopyFromCompositingSurfaceHasResultForVideo( base::Callback<void(bool result)> finished_callback = base::Bind( &CopyFromCompositingSurfaceFinishedForVideo, callback, - texture_mailbox->callback()); + base::Passed(&release_callback)); yuv_readback_pipeline->ReadbackYUV( - texture_mailbox->name(), - texture_mailbox->sync_point(), + texture_mailbox.name(), + texture_mailbox.sync_point(), video_frame.get(), finished_callback); } @@ -2522,12 +2533,14 @@ void RenderWidgetHostViewAura::DidRecreateLayer(ui::Layer *old_layer, if (old_buffer->memory() && new_buffer->memory()) { memcpy(new_buffer->memory(), old_buffer->memory(), size); base::SharedMemory* new_buffer_raw_ptr = new_buffer.get(); - cc::TextureMailbox::ReleaseCallback callback = - base::Bind(MailboxReleaseCallback, Passed(&new_buffer)); + scoped_ptr<cc::SingleReleaseCallback> callback = + cc::SingleReleaseCallback::Create(base::Bind(MailboxReleaseCallback, + Passed(&new_buffer))); cc::TextureMailbox new_mailbox(new_buffer_raw_ptr, - old_mailbox.shared_memory_size(), - callback); - new_layer->SetTextureMailbox(new_mailbox, mailbox_scale_factor); + old_mailbox.shared_memory_size()); + new_layer->SetTextureMailbox(new_mailbox, + callback.Pass(), + mailbox_scale_factor); } } // TODO(piman): handle delegated frames. diff --git a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc b/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc index 7d02f31..c7e1ae8 100644 --- a/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc +++ b/content/renderer/browser_plugin/browser_plugin_compositing_helper.cc @@ -8,6 +8,7 @@ #include "cc/layers/solid_color_layer.h" #include "cc/layers/texture_layer.h" #include "cc/output/context_provider.h" +#include "cc/resources/single_release_callback.h" #include "content/common/browser_plugin/browser_plugin_messages.h" #include "content/common/gpu/client/context_provider_command_buffer.h" #include "content/renderer/browser_plugin/browser_plugin_manager.h" @@ -238,21 +239,20 @@ void BrowserPluginCompositingHelper::OnBuffersSwappedPrivate( } cc::TextureMailbox texture_mailbox; + scoped_ptr<cc::SingleReleaseCallback> release_callback; if (current_mailbox_valid) { - cc::TextureMailbox::ReleaseCallback callback = + release_callback = cc::SingleReleaseCallback::Create( base::Bind(&BrowserPluginCompositingHelper::MailboxReleased, scoped_refptr<BrowserPluginCompositingHelper>(this), - mailbox); - if (is_software_frame) { - texture_mailbox = cc::TextureMailbox(mailbox.shared_memory, - mailbox.size, callback); - } else { - texture_mailbox = cc::TextureMailbox(mailbox.name, callback, sync_point); - } + mailbox)).Pass(); + if (is_software_frame) + texture_mailbox = cc::TextureMailbox(mailbox.shared_memory, mailbox.size); + else + texture_mailbox = cc::TextureMailbox(mailbox.name, sync_point); } texture_layer_->SetFlipped(!is_software_frame); - texture_layer_->SetTextureMailbox(texture_mailbox); + texture_layer_->SetTextureMailbox(texture_mailbox, release_callback.Pass()); texture_layer_->SetNeedsDisplay(); last_mailbox_valid_ = current_mailbox_valid; } diff --git a/content/renderer/pepper/pepper_graphics_2d_host.cc b/content/renderer/pepper/pepper_graphics_2d_host.cc index 31cdc6a..8fb9841 100644 --- a/content/renderer/pepper/pepper_graphics_2d_host.cc +++ b/content/renderer/pepper/pepper_graphics_2d_host.cc @@ -559,7 +559,9 @@ void ReleaseCallback(scoped_ptr<base::SharedMemory> memory, unsigned sync_point, bool lost_resource) {} -bool PepperGraphics2DHost::PrepareTextureMailbox(cc::TextureMailbox* mailbox) { +bool PepperGraphics2DHost::PrepareTextureMailbox( + cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback) { if (!texture_mailbox_modified_) return false; // TODO(jbauman): Send image_data_ through mailbox to avoid copy. @@ -573,11 +575,9 @@ bool PepperGraphics2DHost::PrepareTextureMailbox(cc::TextureMailbox* mailbox) { memcpy(memory->memory(), src, buffer_size); image_data_->Unmap(); - base::SharedMemory* mem = memory.get(); - *mailbox = - cc::TextureMailbox(mem, - pixel_image_size, - base::Bind(&ReleaseCallback, base::Passed(&memory))); + *mailbox = cc::TextureMailbox(memory.get(), pixel_image_size); + *release_callback = cc::SingleReleaseCallback::Create( + base::Bind(&ReleaseCallback, base::Passed(&memory))); texture_mailbox_modified_ = false; return true; } diff --git a/content/renderer/pepper/pepper_graphics_2d_host.h b/content/renderer/pepper/pepper_graphics_2d_host.h index ad8c94d..7179398 100644 --- a/content/renderer/pepper/pepper_graphics_2d_host.h +++ b/content/renderer/pepper/pepper_graphics_2d_host.h @@ -16,7 +16,10 @@ #include "ppapi/host/resource_host.h" #include "third_party/WebKit/public/platform/WebCanvas.h" -namespace cc { class TextureMailbox; } +namespace cc { +class SingleReleaseCallback; +class TextureMailbox; +} namespace gfx { class Point; @@ -59,7 +62,9 @@ class CONTENT_EXPORT PepperGraphics2DHost const gfx::Rect& plugin_rect, const gfx::Rect& paint_rect); - bool PrepareTextureMailbox(cc::TextureMailbox* mailbox); + bool PrepareTextureMailbox( + cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback); void AttachedToNewLayer(); // Notifications about the view's progress painting. See PluginInstance. diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index 52b33d7..ff9fda3 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -1841,7 +1841,8 @@ void PepperPluginInstanceImpl::UpdateLayer() { texture_layer_ = cc::TextureLayer::CreateForMailbox(NULL); opaque = bound_graphics_3d_->IsOpaque(); texture_layer_->SetTextureMailbox( - cc::TextureMailbox(mailbox, base::Bind(&IgnoreCallback), 0)); + cc::TextureMailbox(mailbox, 0), + cc::SingleReleaseCallback::Create(base::Bind(&IgnoreCallback))); } else { DCHECK(bound_graphics_2d_platform_); texture_layer_ = cc::TextureLayer::CreateForMailbox(this); @@ -1875,10 +1876,12 @@ WebKit::WebGraphicsContext3D* PepperPluginInstanceImpl::Context3d() { bool PepperPluginInstanceImpl::PrepareTextureMailbox( cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback, bool use_shared_memory) { if (!bound_graphics_2d_platform_) return false; - return bound_graphics_2d_platform_->PrepareTextureMailbox(mailbox); + return bound_graphics_2d_platform_->PrepareTextureMailbox( + mailbox, release_callback); } void PepperPluginInstanceImpl::AddPluginObject(PluginObject* plugin_object) { diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index 854dc4b..fc9cf7c 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h @@ -504,8 +504,10 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // cc::TextureLayerClient implementation. virtual unsigned PrepareTexture() OVERRIDE; virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE; - virtual bool PrepareTextureMailbox(cc::TextureMailbox* mailbox, - bool use_shared_memory) OVERRIDE; + virtual bool PrepareTextureMailbox( + cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE; private: friend class base::RefCounted<PepperPluginInstanceImpl>; diff --git a/ui/compositor/layer.cc b/ui/compositor/layer.cc index 1d30d91..e2ba65c 100644 --- a/ui/compositor/layer.cc +++ b/ui/compositor/layer.cc @@ -503,8 +503,10 @@ void Layer::SetExternalTexture(Texture* texture) { RecomputeDrawsContentAndUVRect(); } -void Layer::SetTextureMailbox(const cc::TextureMailbox& mailbox, - float scale_factor) { +void Layer::SetTextureMailbox( + const cc::TextureMailbox& mailbox, + scoped_ptr<cc::SingleReleaseCallback> release_callback, + float scale_factor) { DCHECK_EQ(type_, LAYER_TEXTURED); DCHECK(!solid_color_layer_.get()); layer_updated_externally_ = true; @@ -516,7 +518,7 @@ void Layer::SetTextureMailbox(const cc::TextureMailbox& mailbox, SwitchToLayer(new_layer); texture_layer_ = new_layer; } - texture_layer_->SetTextureMailbox(mailbox); + texture_layer_->SetTextureMailbox(mailbox, release_callback.Pass()); mailbox_ = mailbox; mailbox_scale_factor_ = scale_factor; RecomputeDrawsContentAndUVRect(); @@ -525,8 +527,7 @@ void Layer::SetTextureMailbox(const cc::TextureMailbox& mailbox, cc::TextureMailbox Layer::GetTextureMailbox(float* scale_factor) { if (scale_factor) *scale_factor = mailbox_scale_factor_; - cc::TextureMailbox::ReleaseCallback callback; - return mailbox_.CopyWithNewCallback(callback); + return mailbox_; } void Layer::SetDelegatedFrame(scoped_ptr<cc::DelegatedFrameData> frame, @@ -664,8 +665,10 @@ WebKit::WebGraphicsContext3D* Layer::Context3d() { return NULL; } -bool Layer::PrepareTextureMailbox(cc::TextureMailbox* mailbox, - bool use_shared_memory) { +bool Layer::PrepareTextureMailbox( + cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback, + bool use_shared_memory) { return false; } diff --git a/ui/compositor/layer.h b/ui/compositor/layer.h index 1416f5f..5b7e217 100644 --- a/ui/compositor/layer.h +++ b/ui/compositor/layer.h @@ -256,7 +256,9 @@ class COMPOSITOR_EXPORT Layer // Set new TextureMailbox for this layer. Note that |mailbox| may hold a // shared memory resource or an actual mailbox for a texture. - void SetTextureMailbox(const cc::TextureMailbox& mailbox, float scale_factor); + void SetTextureMailbox(const cc::TextureMailbox& mailbox, + scoped_ptr<cc::SingleReleaseCallback> release_callback, + float scale_factor); cc::TextureMailbox GetTextureMailbox(float* scale_factor); // Sets a delegated frame, coming from a child compositor. @@ -322,8 +324,10 @@ class COMPOSITOR_EXPORT Layer // TextureLayerClient virtual unsigned PrepareTexture() OVERRIDE; virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE; - virtual bool PrepareTextureMailbox(cc::TextureMailbox* mailbox, - bool use_shared_memory) OVERRIDE; + virtual bool PrepareTextureMailbox( + cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE; float device_scale_factor() const { return device_scale_factor_; } @@ -476,7 +480,7 @@ class COMPOSITOR_EXPORT Layer cc::Layer* cc_layer_; // If true, the layer scales the canvas and the texture with the device scale - // factor as appropriate. When true, the texture size is in DIP. + // factor as apporpriate. When true, the texture size is in DIP. bool scale_content_; // A cached copy of |Compositor::device_scale_factor()|. diff --git a/webkit/renderer/compositor_bindings/web_external_texture_layer_impl.cc b/webkit/renderer/compositor_bindings/web_external_texture_layer_impl.cc index 36b4994..209195f 100644 --- a/webkit/renderer/compositor_bindings/web_external_texture_layer_impl.cc +++ b/webkit/renderer/compositor_bindings/web_external_texture_layer_impl.cc @@ -6,6 +6,8 @@ #include "cc/layers/texture_layer.h" #include "cc/resources/resource_update_queue.h" +#include "cc/resources/single_release_callback.h" +#include "cc/resources/texture_mailbox.h" #include "third_party/WebKit/public/platform/WebExternalTextureLayerClient.h" #include "third_party/WebKit/public/platform/WebExternalTextureMailbox.h" #include "third_party/WebKit/public/platform/WebFloatRect.h" @@ -36,7 +38,8 @@ WebKit::WebLayer* WebExternalTextureLayerImpl::layer() { return layer_.get(); } void WebExternalTextureLayerImpl::clearTexture() { TextureLayer *layer = static_cast<TextureLayer*>(layer_->layer()); layer->WillModifyTexture(); - layer->SetTextureMailbox(cc::TextureMailbox()); + layer->SetTextureMailbox(cc::TextureMailbox(), + scoped_ptr<cc::SingleReleaseCallback>()); } void WebExternalTextureLayerImpl::setOpaque(bool opaque) { @@ -69,6 +72,7 @@ WebKit::WebGraphicsContext3D* WebExternalTextureLayerImpl::Context3d() { bool WebExternalTextureLayerImpl::PrepareTextureMailbox( cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback, bool use_shared_memory) { WebKit::WebExternalTextureMailbox client_mailbox; WebExternalBitmapImpl* bitmap = NULL; @@ -82,17 +86,17 @@ bool WebExternalTextureLayerImpl::PrepareTextureMailbox( } gpu::Mailbox name; name.SetName(client_mailbox.name); - cc::TextureMailbox::ReleaseCallback callback = - base::Bind(&WebExternalTextureLayerImpl::DidReleaseMailbox, - this->AsWeakPtr(), - client_mailbox, - bitmap); - if (bitmap) { - *mailbox = - cc::TextureMailbox(bitmap->shared_memory(), bitmap->size(), callback); - } else { - *mailbox = cc::TextureMailbox(name, callback, client_mailbox.syncPoint); - } + scoped_ptr<cc::SingleReleaseCallback> callback = + cc::SingleReleaseCallback::Create(base::Bind( + &WebExternalTextureLayerImpl::DidReleaseMailbox, + this->AsWeakPtr(), + client_mailbox, + bitmap)); + if (bitmap) + *mailbox = cc::TextureMailbox(bitmap->shared_memory(), bitmap->size()); + else + *mailbox = cc::TextureMailbox(name, client_mailbox.syncPoint); + *release_callback = callback.Pass(); return true; } diff --git a/webkit/renderer/compositor_bindings/web_external_texture_layer_impl.h b/webkit/renderer/compositor_bindings/web_external_texture_layer_impl.h index 3fb798a..5992d1a 100644 --- a/webkit/renderer/compositor_bindings/web_external_texture_layer_impl.h +++ b/webkit/renderer/compositor_bindings/web_external_texture_layer_impl.h @@ -9,10 +9,14 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/scoped_vector.h" #include "cc/layers/texture_layer_client.h" -#include "cc/resources/texture_mailbox.h" #include "third_party/WebKit/public/platform/WebExternalTextureLayer.h" #include "webkit/renderer/compositor_bindings/webkit_compositor_bindings_export.h" +namespace cc { +class SingleReleaseCallback; +class TextureMailbox; +} + namespace WebKit { struct WebFloatRect; struct WebExternalTextureMailbox; @@ -43,8 +47,10 @@ class WebExternalTextureLayerImpl // TextureLayerClient implementation. virtual unsigned PrepareTexture() OVERRIDE; virtual WebKit::WebGraphicsContext3D* Context3d() OVERRIDE; - virtual bool PrepareTextureMailbox(cc::TextureMailbox* mailbox, - bool use_shared_memory) OVERRIDE; + virtual bool PrepareTextureMailbox( + cc::TextureMailbox* mailbox, + scoped_ptr<cc::SingleReleaseCallback>* release_callback, + bool use_shared_memory) OVERRIDE; private: static void DidReleaseMailbox( |