diff --git a/gfx/layers/ipc/CompositorThread.cpp b/gfx/layers/ipc/CompositorThread.cpp index 75d34a13a2d5..d813465ced36 100644 --- a/gfx/layers/ipc/CompositorThread.cpp +++ b/gfx/layers/ipc/CompositorThread.cpp @@ -7,6 +7,7 @@ #include "MainThreadUtils.h" #include "nsThreadUtils.h" #include "CompositorBridgeParent.h" +#include "mozilla/layers/ImageBridgeParent.h" #include "mozilla/media/MediaSystemResourceService.h" namespace mozilla { @@ -105,6 +106,7 @@ CompositorThreadHolder::CreateCompositorThread() } CompositorBridgeParent::Setup(); + ImageBridgeParent::Setup(); return compositorThread; } diff --git a/gfx/layers/ipc/ImageBridgeParent.cpp b/gfx/layers/ipc/ImageBridgeParent.cpp index 7138a17237c7..3dc62d69e967 100644 --- a/gfx/layers/ipc/ImageBridgeParent.cpp +++ b/gfx/layers/ipc/ImageBridgeParent.cpp @@ -10,6 +10,7 @@ #include "base/message_loop.h" // for MessageLoop #include "base/process.h" // for ProcessId #include "base/task.h" // for CancelableTask, DeleteTask, etc +#include "mozilla/ClearOnShutdown.h" #include "mozilla/gfx/Point.h" // for IntSize #include "mozilla/Hal.h" // for hal::SetCurrentThreadPriority() #include "mozilla/HalTypes.h" // for hal::THREAD_PRIORITY_COMPOSITOR @@ -23,6 +24,7 @@ #include "mozilla/layers/PImageBridgeParent.h" #include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL #include "mozilla/layers/Compositor.h" +#include "mozilla/Monitor.h" #include "mozilla/mozalloc.h" // for operator new, etc #include "mozilla/Unused.h" #include "nsDebug.h" // for NS_RUNTIMEABORT, etc @@ -42,11 +44,21 @@ using namespace mozilla::media; std::map ImageBridgeParent::sImageBridges; -MessageLoop* ImageBridgeParent::sMainLoop = nullptr; +StaticAutoPtr sImageBridgesLock; // defined in CompositorBridgeParent.cpp CompositorThreadHolder* GetCompositorThreadHolder(); +/* static */ void +ImageBridgeParent::Setup() +{ + MOZ_ASSERT(NS_IsMainThread()); + if (!sImageBridgesLock) { + sImageBridgesLock = new Monitor("ImageBridges"); + mozilla::ClearOnShutdown(&sImageBridgesLock); + } +} + ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop, ProcessId aChildProcessId) : mMessageLoop(aLoop) @@ -54,17 +66,18 @@ ImageBridgeParent::ImageBridgeParent(MessageLoop* aLoop, , mClosed(false) { MOZ_ASSERT(NS_IsMainThread()); - sMainLoop = MessageLoop::current(); // creates the map only if it has not been created already, so it is safe // with several bridges - sImageBridges[aChildProcessId] = this; + { + MonitorAutoLock lock(*sImageBridgesLock); + sImageBridges[aChildProcessId] = this; + } SetOtherProcessId(aChildProcessId); } ImageBridgeParent::~ImageBridgeParent() { - sImageBridges.erase(OtherPid()); } static StaticRefPtr sImageBridgeParentSingleton; @@ -105,7 +118,10 @@ ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy) // Can't alloc/dealloc shmems from now on. mClosed = true; mCompositables.clear(); - + { + MonitorAutoLock lock(*sImageBridgesLock); + sImageBridges.erase(OtherPid()); + } MessageLoop::current()->PostTask(NewRunnableMethod(this, &ImageBridgeParent::DeferredDestroy)); // It is very important that this method gets called at shutdown (be it a clean @@ -327,9 +343,11 @@ ImageBridgeParent::DeferredDestroy() mSelfRef = nullptr; // "this" ImageBridge may get deleted here. } -ImageBridgeParent* +RefPtr ImageBridgeParent::GetInstance(ProcessId aId) { + MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread()); + MonitorAutoLock lock(*sImageBridgesLock); NS_ASSERTION(sImageBridges.count(aId) == 1, "ImageBridgeParent for the process"); return sImageBridges[aId]; } @@ -377,26 +395,6 @@ bool ImageBridgeParent::IsSameProcess() const return OtherPid() == base::GetCurrentProcId(); } -/*static*/ void -ImageBridgeParent::SetAboutToSendAsyncMessages(base::ProcessId aChildProcessId) -{ - ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId); - if (!imageBridge) { - return; - } - imageBridge->SetAboutToSendAsyncMessages(); -} - -/*static*/ void -ImageBridgeParent::SendPendingAsyncMessages(base::ProcessId aChildProcessId) -{ - ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(aChildProcessId); - if (!imageBridge) { - return; - } - imageBridge->SendPendingAsyncMessages(); -} - void ImageBridgeParent::NotifyNotUsed(PTextureParent* aTexture, uint64_t aTransactionId) { diff --git a/gfx/layers/ipc/ImageBridgeParent.h b/gfx/layers/ipc/ImageBridgeParent.h index 640b9ecb9e4a..b41fdb73ab30 100644 --- a/gfx/layers/ipc/ImageBridgeParent.h +++ b/gfx/layers/ipc/ImageBridgeParent.h @@ -50,6 +50,11 @@ protected: public: ~ImageBridgeParent(); + /** + * Creates the globals of ImageBridgeParent. + */ + static void Setup(); + static ImageBridgeParent* CreateSameProcess(); static bool CreateForGPUProcess(Endpoint&& aEndpoint); static bool CreateForContent(Endpoint&& aEndpoint); @@ -107,13 +112,7 @@ public: virtual bool IsSameProcess() const override; - using CompositableParentManager::SetAboutToSendAsyncMessages; - static void SetAboutToSendAsyncMessages(base::ProcessId aChildProcessId); - - using CompositableParentManager::SendPendingAsyncMessages; - static void SendPendingAsyncMessages(base::ProcessId aChildProcessId); - - static ImageBridgeParent* GetInstance(ProcessId aId); + static RefPtr GetInstance(ProcessId aId); static bool NotifyImageComposites(nsTArray& aNotifications); @@ -141,8 +140,6 @@ private: */ static std::map sImageBridges; - static MessageLoop* sMainLoop; - RefPtr mCompositorThreadHolder; }; diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index 1be9ac465ecb..e0e1dad36dcd 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -111,13 +111,11 @@ public: , mActorsToDestroy(aDestroyActors) { mLayerTransaction->SetAboutToSendAsyncMessages(); - ImageBridgeParent::SetAboutToSendAsyncMessages(mLayerTransaction->GetChildProcessId()); } ~AutoLayerTransactionParentAsyncMessageSender() { mLayerTransaction->SendPendingAsyncMessages(); - ImageBridgeParent::SendPendingAsyncMessages(mLayerTransaction->GetChildProcessId()); if (mActorsToDestroy) { // Destroy the actors after sending the async messages because the latter may contain // references to some actors. @@ -409,7 +407,7 @@ LayerTransactionParent::RecvUpdate(const TransactionInfo& aInfo) } case Edit::TOpAttachAsyncCompositable: { const OpAttachAsyncCompositable& op = edit.get_OpAttachAsyncCompositable(); - ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(OtherPid()); + RefPtr imageBridge = ImageBridgeParent::GetInstance(OtherPid()); if (!imageBridge) { return IPC_FAIL_NO_REASON(this); } diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index 4a2b0f1ba7ba..1d4efb5d17d2 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -641,7 +641,7 @@ WebRenderBridgeParent::RecvAddExternalImageId(const ExternalImageId& aImageId, MOZ_ASSERT(!mExternalImageIds.Get(wr::AsUint64(aImageId)).get()); - ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(OtherPid()); + RefPtr imageBridge = ImageBridgeParent::GetInstance(OtherPid()); if (!imageBridge) { return IPC_FAIL_NO_REASON(this); }