Move CompositableMap into ImageBridge. (bug 1325784 part 2, r=nical)
authorDavid Anderson <dvander@alliedmods.net>
Wed, 04 Jan 2017 10:19:29 -0500
changeset 327957 db794b9c38c0126d6e38cc7043d8cea1b2defec9
parent 327956 41e358afd35190bf33fdebbec2ef23972a0932e6
child 327958 f27059c293c8ca40470054612b457304c42616c2
push id31160
push userphilringnalda@gmail.com
push dateThu, 05 Jan 2017 02:33:44 +0000
treeherdermozilla-central@f13abb8ba9f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1325784
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Move CompositableMap into ImageBridge. (bug 1325784 part 2, r=nical)
gfx/layers/composite/CompositableHost.cpp
gfx/layers/composite/CompositableHost.h
gfx/layers/ipc/ImageBridgeParent.cpp
gfx/layers/ipc/ImageBridgeParent.h
gfx/layers/ipc/LayerTransactionParent.cpp
--- a/gfx/layers/composite/CompositableHost.cpp
+++ b/gfx/layers/composite/CompositableHost.cpp
@@ -37,35 +37,29 @@ class Compositor;
  * by either the CompositableChild's deletion, or by the IPDL communication
  * going down.
  */
 class CompositableParent : public ParentActor<PCompositableParent>
 {
 public:
   CompositableParent(CompositableParentManager* aMgr,
                      const TextureInfo& aTextureInfo,
-                     uint64_t aID = 0,
                      PImageContainerParent* aImageContainer = nullptr)
   {
     MOZ_COUNT_CTOR(CompositableParent);
     mHost = CompositableHost::Create(aTextureInfo);
-    mHost->SetAsyncID(aID);
-    if (aID) {
-      CompositableMap::Set(aID, this);
-    }
     if (aImageContainer) {
       mHost->SetImageContainer(
           static_cast<ImageContainerParent*>(aImageContainer));
     }
   }
 
   ~CompositableParent()
   {
     MOZ_COUNT_DTOR(CompositableParent);
-    CompositableMap::Erase(mHost->GetAsyncID());
   }
 
   virtual void Destroy() override
   {
     if (mHost) {
       mHost->Detach(nullptr, CompositableHost::FORCE_DETACH);
     }
   }
@@ -89,20 +83,19 @@ CompositableHost::CompositableHost(const
 CompositableHost::~CompositableHost()
 {
   MOZ_COUNT_DTOR(CompositableHost);
 }
 
 PCompositableParent*
 CompositableHost::CreateIPDLActor(CompositableParentManager* aMgr,
                                   const TextureInfo& aTextureInfo,
-                                  uint64_t aID,
                                   PImageContainerParent* aImageContainer)
 {
-  return new CompositableParent(aMgr, aTextureInfo, aID, aImageContainer);
+  return new CompositableParent(aMgr, aTextureInfo, aImageContainer);
 }
 
 bool
 CompositableHost::DestroyIPDLActor(PCompositableParent* aActor)
 {
   delete aActor;
   return true;
 }
@@ -226,67 +219,10 @@ CompositableHost::DumpTextureHost(std::s
 }
 
 void
 CompositableHost::ReceivedDestroy(PCompositableParent* aActor)
 {
   static_cast<CompositableParent*>(aActor)->RecvDestroy();
 }
 
-namespace CompositableMap {
-
-typedef std::map<uint64_t, PCompositableParent*> CompositableMap_t;
-static CompositableMap_t* sCompositableMap = nullptr;
-bool IsCreated() {
-  return sCompositableMap != nullptr;
-}
-PCompositableParent* Get(uint64_t aID)
-{
-  if (!IsCreated() || aID == 0) {
-    return nullptr;
-  }
-  CompositableMap_t::iterator it = sCompositableMap->find(aID);
-  if (it == sCompositableMap->end()) {
-    return nullptr;
-  }
-  return it->second;
-}
-void Set(uint64_t aID, PCompositableParent* aParent)
-{
-  if (!IsCreated() || aID == 0) {
-    return;
-  }
-  (*sCompositableMap)[aID] = aParent;
-}
-void Erase(uint64_t aID)
-{
-  if (!IsCreated() || aID == 0) {
-    return;
-  }
-  CompositableMap_t::iterator it = sCompositableMap->find(aID);
-  if (it != sCompositableMap->end()) {
-    sCompositableMap->erase(it);
-  }
-}
-void Clear()
-{
-  if (!IsCreated()) {
-    return;
-  }
-  sCompositableMap->clear();
-}
-void Create()
-{
-  if (sCompositableMap == nullptr) {
-    sCompositableMap = new CompositableMap_t;
-  }
-}
-void Destroy()
-{
-  Clear();
-  delete sCompositableMap;
-  sCompositableMap = nullptr;
-}
-
-} // namespace CompositableMap
-
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/composite/CompositableHost.h
+++ b/gfx/layers/composite/CompositableHost.h
@@ -208,17 +208,16 @@ public:
   void BumpFlashCounter() {
     mFlashCounter = mFlashCounter >= DIAGNOSTIC_FLASH_COUNTER_MAX
                   ? DIAGNOSTIC_FLASH_COUNTER_MAX : mFlashCounter + 1;
   }
 
   static PCompositableParent*
   CreateIPDLActor(CompositableParentManager* mgr,
                   const TextureInfo& textureInfo,
-                  uint64_t asyncID,
                   PImageContainerParent* aImageContainer = nullptr);
 
   static bool DestroyIPDLActor(PCompositableParent* actor);
 
   static CompositableHost* FromIPDLActor(PCompositableParent* actor);
 
   uint64_t GetCompositorID() const { return mCompositorID; }
 
@@ -270,49 +269,12 @@ public:
 
   bool Failed() const { return !mSucceeded; }
 
 private:
   RefPtr<CompositableHost> mHost;
   bool mSucceeded;
 };
 
-/**
- * Global CompositableMap, to use in the compositor thread only.
- *
- * PCompositable and PLayer can, in the case of async textures, be managed by
- * different top level protocols. In this case they don't share the same
- * communication channel and we can't send an OpAttachCompositable (PCompositable,
- * PLayer) message.
- *
- * In order to attach a layer and the right compositable if the the compositable
- * is async, we store references to the async compositables in a CompositableMap
- * that is accessed only on the compositor thread. During a layer transaction we
- * send the message OpAttachAsyncCompositable(ID, PLayer), and on the compositor
- * side we lookup the ID in the map and attach the corresponding compositable to
- * the layer.
- *
- * CompositableMap must be global because the image bridge doesn't have any
- * reference to whatever we have created with PLayerTransaction. So, the only way to
- * actually connect these two worlds is to have something global that they can
- * both query (in the same  thread). The map is not allocated the map on the
- * stack to avoid the badness of static initialization.
- *
- * Also, we have a compositor/PLayerTransaction protocol/etc. per layer manager, and the
- * ImageBridge is used by all the existing compositors that have a video, so
- * there isn't an instance or "something" that lives outside the boudaries of a
- * given layer manager on the compositor thread except the image bridge and the
- * thread itself.
- */
-namespace CompositableMap {
-  void Create();
-  void Destroy();
-  PCompositableParent* Get(uint64_t aID);
-  void Set(uint64_t aID, PCompositableParent* aParent);
-  void Erase(uint64_t aID);
-  void Clear();
-} // namespace CompositableMap
-
-
 } // namespace layers
 } // namespace mozilla
 
 #endif
--- a/gfx/layers/ipc/ImageBridgeParent.cpp
+++ b/gfx/layers/ipc/ImageBridgeParent.cpp
@@ -54,17 +54,16 @@ ImageBridgeParent::ImageBridgeParent(Mes
   , mSetChildThreadPriority(false)
   , 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
-  CompositableMap::Create();
   sImageBridges[aChildProcessId] = this;
   SetOtherProcessId(aChildProcessId);
 }
 
 ImageBridgeParent::~ImageBridgeParent()
 {
   nsTArray<PImageContainerParent*> parents;
   ManagedPImageContainerParent(parents);
@@ -246,23 +245,32 @@ static  uint64_t GenImageContainerID() {
   return sNextImageID;
 }
 
 PCompositableParent*
 ImageBridgeParent::AllocPCompositableParent(const TextureInfo& aInfo,
                                             PImageContainerParent* aImageContainer,
                                             uint64_t* aID)
 {
+  PCompositableParent* actor = CompositableHost::CreateIPDLActor(this, aInfo, aImageContainer);
+  CompositableHost* host = CompositableHost::FromIPDLActor(actor);
+
   uint64_t id = GenImageContainerID();
+  host->SetAsyncID(id);
+  mCompositables[id] = host;
+
   *aID = id;
-  return CompositableHost::CreateIPDLActor(this, aInfo, id, aImageContainer);
+  return actor;
 }
 
 bool ImageBridgeParent::DeallocPCompositableParent(PCompositableParent* aActor)
 {
+  if (CompositableHost* host = CompositableHost::FromIPDLActor(aActor)) {
+    mCompositables.erase(host->GetAsyncID());
+  }
   return CompositableHost::DestroyIPDLActor(aActor);
 }
 
 PTextureParent*
 ImageBridgeParent::AllocPTextureParent(const SurfaceDescriptor& aSharedData,
                                        const LayersBackend& aLayersBackend,
                                        const TextureFlags& aFlags,
                                        const uint64_t& aSerial)
@@ -445,10 +453,20 @@ ImageBridgeParent::NotifyNotUsed(PTextur
   mPendingAsyncMessage.push_back(
     OpNotifyNotUsed(textureId, aTransactionId));
 
   if (!IsAboutToSendAsyncMessages()) {
     SendPendingAsyncMessages();
   }
 }
 
+CompositableHost*
+ImageBridgeParent::FindCompositable(uint64_t aId)
+{
+  auto iter = mCompositables.find(aId);
+  if (iter == mCompositables.end()) {
+    return nullptr;
+  }
+  return iter->second;
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/ImageBridgeParent.h
+++ b/gfx/layers/ipc/ImageBridgeParent.h
@@ -122,16 +122,18 @@ public:
   static ImageBridgeParent* GetInstance(ProcessId aId);
 
   static bool NotifyImageComposites(nsTArray<ImageCompositeNotification>& aNotifications);
 
   virtual bool UsesImageBridge() const override { return true; }
 
   virtual bool IPCOpen() const override { return !mClosed; }
 
+  CompositableHost* FindCompositable(uint64_t aId);
+
 protected:
   void OnChannelConnected(int32_t pid) override;
 
   void Bind(Endpoint<PImageBridgeParent>&& aEndpoint);
 
 private:
   void DeferredDestroy();
   MessageLoop* mMessageLoop;
@@ -145,14 +147,41 @@ private:
   /**
    * Map of all living ImageBridgeParent instances
    */
   static std::map<base::ProcessId, ImageBridgeParent*> sImageBridges;
 
   static MessageLoop* sMainLoop;
 
   RefPtr<CompositorThreadHolder> mCompositorThreadHolder;
+
+  /**
+   * PCompositable and PLayer can, in the case of async textures, be managed by
+   * different top level protocols. In this case they don't share the same
+   * communication channel and we can't send an OpAttachCompositable (PCompositable,
+   * PLayer) message.
+   *
+   * In order to attach a layer and the right compositable if the the compositable
+   * is async, we store references to the async compositables in a CompositableMap
+   * that is accessed only on the compositor thread. During a layer transaction we
+   * send the message OpAttachAsyncCompositable(ID, PLayer), and on the compositor
+   * side we lookup the ID in the map and attach the corresponding compositable to
+   * the layer.
+   *
+   * CompositableMap must be global because the image bridge doesn't have any
+   * reference to whatever we have created with PLayerTransaction. So, the only way to
+   * actually connect these two worlds is to have something global that they can
+   * both query (in the same  thread). The map is not allocated the map on the
+   * stack to avoid the badness of static initialization.
+   *
+   * Also, we have a compositor/PLayerTransaction protocol/etc. per layer manager, and the
+   * ImageBridge is used by all the existing compositors that have a video, so
+   * there isn't an instance or "something" that lives outside the boudaries of a
+   * given layer manager on the compositor thread except the image bridge and the
+   * thread itself.
+   */
+  std::map<uint64_t, CompositableHost*> mCompositables;
 };
 
 } // namespace layers
 } // namespace mozilla
 
 #endif // gfx_layers_ipc_ImageBridgeParent_h_
--- a/gfx/layers/ipc/LayerTransactionParent.cpp
+++ b/gfx/layers/ipc/LayerTransactionParent.cpp
@@ -599,27 +599,30 @@ LayerTransactionParent::RecvUpdate(Infal
       }
       if (mLayerManager->GetCompositor()) {
         host->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID());
       }
       break;
     }
     case Edit::TOpAttachAsyncCompositable: {
       const OpAttachAsyncCompositable& op = edit.get_OpAttachAsyncCompositable();
-      PCompositableParent* compositableParent = CompositableMap::Get(op.containerID());
-      if (!compositableParent) {
-        NS_ERROR("CompositableParent not found in the map");
-        return IPC_FAIL_NO_REASON(this);
-      }
       if (mPendingCompositorUpdates) {
         // Do not attach compositables from old layer trees. Return true since
         // content cannot handle errors.
         return IPC_OK();
       }
-      CompositableHost* host = CompositableHost::FromIPDLActor(compositableParent);
+      ImageBridgeParent* imageBridge = ImageBridgeParent::GetInstance(OtherPid());
+      if (!imageBridge) {
+        return IPC_FAIL_NO_REASON(this);
+      }
+      CompositableHost* host = imageBridge->FindCompositable(op.containerID());
+      if (!host) {
+        NS_ERROR("CompositableHost not found in the map");
+        return IPC_FAIL_NO_REASON(this);
+      }
       if (!Attach(AsLayer(op.layer()), host, true)) {
         return IPC_FAIL_NO_REASON(this);
       }
       if (mLayerManager->GetCompositor()) {
         host->SetCompositorID(mLayerManager->GetCompositor()->GetCompositorID());
       }
       break;
     }