diff --git a/gfx/layers/ipc/CompositorChild.cpp b/gfx/layers/ipc/CompositorChild.cpp index 4de044fcb840..a2f281399e05 100644 --- a/gfx/layers/ipc/CompositorChild.cpp +++ b/gfx/layers/ipc/CompositorChild.cpp @@ -87,13 +87,15 @@ CompositorChild::AllocPLayerTransactionChild(const nsTArray& aBac TextureFactoryIdentifier*, bool*) { - return new LayerTransactionChild(); + LayerTransactionChild* c = new LayerTransactionChild(); + c->AddIPDLReference(); + return c; } bool CompositorChild::DeallocPLayerTransactionChild(PLayerTransactionChild* actor) { - delete actor; + static_cast(actor)->ReleaseIPDLReference(); return true; } diff --git a/gfx/layers/ipc/CompositorParent.cpp b/gfx/layers/ipc/CompositorParent.cpp index 57ce9baf1b15..4cd2b2a8cee4 100644 --- a/gfx/layers/ipc/CompositorParent.cpp +++ b/gfx/layers/ipc/CompositorParent.cpp @@ -742,20 +742,24 @@ CompositorParent::AllocPLayerTransactionParent(const nsTArray& aB if (!mLayerManager) { NS_WARNING("Failed to initialise Compositor"); *aSuccess = false; - return new LayerTransactionParent(nullptr, this, 0); + LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, 0); + p->AddIPDLReference(); + return p; } mCompositionManager = new AsyncCompositionManager(mLayerManager); + *aSuccess = true; *aTextureFactoryIdentifier = mLayerManager->GetTextureFactoryIdentifier(); - *aSuccess = true; - return new LayerTransactionParent(mLayerManager, this, 0); + LayerTransactionParent* p = new LayerTransactionParent(mLayerManager, this, 0); + p->AddIPDLReference(); + return p; } bool CompositorParent::DeallocPLayerTransactionParent(PLayerTransactionParent* actor) { - delete actor; + static_cast(actor)->ReleaseIPDLReference(); return true; } @@ -1056,14 +1060,18 @@ CrossProcessCompositorParent::AllocPLayerTransactionParent(const nsTArrayGetLayerManager(); *aTextureFactoryIdentifier = lm->GetTextureFactoryIdentifier(); *aSuccess = true; - return new LayerTransactionParent(lm, this, aId); + LayerTransactionParent* p = new LayerTransactionParent(lm, this, aId); + p->AddIPDLReference(); + return p; } NS_WARNING("Created child without a matching parent?"); // XXX: should be false, but that causes us to fail some tests on Mac w/ OMTC. // Bug 900745. change *aSuccess to false to see test failures. *aSuccess = true; - return new LayerTransactionParent(nullptr, this, aId); + LayerTransactionParent* p = new LayerTransactionParent(nullptr, this, aId); + p->AddIPDLReference(); + return p; } bool @@ -1071,7 +1079,7 @@ CrossProcessCompositorParent::DeallocPLayerTransactionParent(PLayerTransactionPa { LayerTransactionParent* slp = static_cast(aLayers); RemoveIndirectTree(slp->GetId()); - delete aLayers; + static_cast(aLayers)->ReleaseIPDLReference(); return true; } diff --git a/gfx/layers/ipc/LayerTransactionChild.h b/gfx/layers/ipc/LayerTransactionChild.h index c99667d7df5f..10b53f382ff4 100644 --- a/gfx/layers/ipc/LayerTransactionChild.h +++ b/gfx/layers/ipc/LayerTransactionChild.h @@ -13,16 +13,20 @@ #include "mozilla/Attributes.h" // for MOZ_OVERRIDE #include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/layers/PLayerTransactionChild.h" +#include "mozilla/RefPtr.h" namespace mozilla { + +namespace layout { +class RenderFrameChild; +} + namespace layers { class LayerTransactionChild : public PLayerTransactionChild + , public AtomicRefCounted { public: - LayerTransactionChild() { } - ~LayerTransactionChild() { } - /** * Clean this up, finishing with Send__delete__(). * @@ -32,7 +36,16 @@ public: */ void Destroy(); + bool IPCOpen() const { return mIPCOpen; } + protected: + LayerTransactionChild() + : mIPCOpen(false) + {} + ~LayerTransactionChild() { } + friend class AtomicRefCounted; + friend class detail::RefCounted; + virtual PGrallocBufferChild* AllocPGrallocBufferChild(const gfxIntSize&, const uint32_t&, const uint32_t&, @@ -46,6 +59,21 @@ protected: virtual PCompositableChild* AllocPCompositableChild(const TextureInfo& aInfo) MOZ_OVERRIDE; virtual bool DeallocPCompositableChild(PCompositableChild* actor) MOZ_OVERRIDE; virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE; + + void AddIPDLReference() { + MOZ_ASSERT(mIPCOpen == false); + mIPCOpen = true; + AddRef(); + } + void ReleaseIPDLReference() { + MOZ_ASSERT(mIPCOpen == true); + mIPCOpen = false; + Release(); + } + friend class CompositorChild; + friend class layout::RenderFrameChild; + + bool mIPCOpen; }; } // namespace layers diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 94f7874f3e96..d71dacf16a73 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -152,6 +152,7 @@ LayerTransactionParent::LayerTransactionParent(LayerManagerComposite* aManager, , mShadowLayersManager(aLayersManager) , mId(aId) , mDestroyed(false) + , mIPCOpen(false) { MOZ_COUNT_CTOR(LayerTransactionParent); } diff --git a/gfx/layers/ipc/LayerTransactionParent.h b/gfx/layers/ipc/LayerTransactionParent.h index 974ce508f391..6aa651765ae2 100644 --- a/gfx/layers/ipc/LayerTransactionParent.h +++ b/gfx/layers/ipc/LayerTransactionParent.h @@ -39,7 +39,8 @@ class CompositableParent; class ShadowLayersManager; class LayerTransactionParent : public PLayerTransactionParent, - public CompositableParentManager + public CompositableParentManager, + public AtomicRefCounted { typedef mozilla::layout::RenderFrameParent RenderFrameParent; typedef InfallibleTArray EditArray; @@ -110,6 +111,20 @@ protected: CompositableParent* aCompositable, bool aIsAsyncVideo); + void AddIPDLReference() { + MOZ_ASSERT(mIPCOpen == false); + mIPCOpen = true; + AddRef(); + } + void ReleaseIPDLReference() { + MOZ_ASSERT(mIPCOpen == true); + mIPCOpen = false; + Release(); + } + friend class CompositorParent; + friend class CrossProcessCompositorParent; + friend class layout::RenderFrameParent; + private: nsRefPtr mLayerManager; ShadowLayersManager* mShadowLayersManager; @@ -135,6 +150,8 @@ private: // vice versa. In both cases though, we want to ignore shadow-layer // transactions posted by the child. bool mDestroyed; + + bool mIPCOpen; }; } // namespace layers diff --git a/layout/ipc/RenderFrameChild.cpp b/layout/ipc/RenderFrameChild.cpp index 7e091338b05b..008fe5abccf7 100644 --- a/layout/ipc/RenderFrameChild.cpp +++ b/layout/ipc/RenderFrameChild.cpp @@ -35,13 +35,15 @@ RenderFrameChild::Destroy() PLayerTransactionChild* RenderFrameChild::AllocPLayerTransactionChild() { - return new LayerTransactionChild(); + LayerTransactionChild* c = new LayerTransactionChild(); + c->AddIPDLReference(); + return c; } bool RenderFrameChild::DeallocPLayerTransactionChild(PLayerTransactionChild* aLayers) { - delete aLayers; + static_cast(aLayers)->ReleaseIPDLReference(); return true; } diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index c1c9d6dbb3e5..c65ff48db0a9 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -915,13 +915,15 @@ RenderFrameParent::AllocPLayerTransactionParent() return nullptr; } nsRefPtr lm = GetFrom(mFrameLoader); - return new LayerTransactionParent(lm->AsLayerManagerComposite(), this, 0); + LayerTransactionParent* result = new LayerTransactionParent(lm->AsLayerManagerComposite(), this, 0); + result->AddIPDLReference(); + return result; } bool RenderFrameParent::DeallocPLayerTransactionParent(PLayerTransactionParent* aLayers) { - delete aLayers; + static_cast(aLayers)->ReleaseIPDLReference(); return true; }