Open content VRManagers using endpoints. (bug 1287597 part 1, r=billm)
authorDavid Anderson <danderson@mozilla.com>
Thu, 21 Jul 2016 00:14:59 -0700
changeset 346064 6f859f324dce2551bd30d42a0bce38f2134e35a9
parent 346063 3c9f2a1d387e77449e55d8b74580c6fe2d286638
child 346065 50a3f84f013e41ea7b5f38c380e6872e86f3a171
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1287597
milestone50.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
Open content VRManagers using endpoints. (bug 1287597 part 1, r=billm)
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/vr/ipc/VRManagerChild.cpp
gfx/vr/ipc/VRManagerChild.h
gfx/vr/ipc/VRManagerParent.cpp
gfx/vr/ipc/VRManagerParent.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1249,30 +1249,29 @@ ContentChild::RecvInitCompositor(Endpoin
 }
 
 bool
 ContentChild::RecvInitImageBridge(Endpoint<PImageBridgeChild>&& aEndpoint)
 {
   return ImageBridgeChild::InitForContent(Move(aEndpoint));
 }
 
+bool
+ContentChild::RecvInitVRManager(Endpoint<PVRManagerChild>&& aEndpoint)
+{
+  return gfx::VRManagerChild::InitForContent(Move(aEndpoint));
+}
+
 PSharedBufferManagerChild*
 ContentChild::AllocPSharedBufferManagerChild(mozilla::ipc::Transport* aTransport,
                                               base::ProcessId aOtherProcess)
 {
   return SharedBufferManagerChild::StartUpInChildProcess(aTransport, aOtherProcess);
 }
 
-gfx::PVRManagerChild*
-ContentChild::AllocPVRManagerChild(Transport* aTransport,
-                                   ProcessId aOtherProcess)
-{
-  return gfx::VRManagerChild::StartUpInChildProcess(aTransport, aOtherProcess);
-}
-
 PBackgroundChild*
 ContentChild::AllocPBackgroundChild(Transport* aTransport,
                                     ProcessId aOtherProcess)
 {
   return BackgroundChild::Alloc(aTransport, aOtherProcess);
 }
 
 PProcessHangMonitorChild*
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -147,29 +147,27 @@ public:
   AllocPAPZChild(const TabId& aTabId) override;
   bool
   DeallocPAPZChild(PAPZChild* aActor) override;
 
   bool
   RecvInitCompositor(Endpoint<PCompositorBridgeChild>&& aEndpoint) override;
   bool
   RecvInitImageBridge(Endpoint<PImageBridgeChild>&& aEndpoint) override;
+  bool
+  RecvInitVRManager(Endpoint<PVRManagerChild>&& aEndpoint) override;
 
   PSharedBufferManagerChild*
   AllocPSharedBufferManagerChild(mozilla::ipc::Transport* aTransport,
                                   base::ProcessId aOtherProcess) override;
 
   PProcessHangMonitorChild*
   AllocPProcessHangMonitorChild(Transport* aTransport,
                                 ProcessId aOtherProcess) override;
 
-  PVRManagerChild*
-  AllocPVRManagerChild(Transport* aTransport,
-                       ProcessId aOtherProcess) override;
-
   virtual bool RecvSetProcessSandbox(const MaybeFileDesc& aBroker) override;
 
   PBackgroundChild*
   AllocPBackgroundChild(Transport* aTransport, ProcessId aOtherProcess)
                         override;
 
   virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
                                             const IPCTabContext& aContext,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -270,18 +270,16 @@ using namespace mozilla::system;
 #ifdef XP_WIN
 #include "mozilla/widget/AudioSession.h"
 #endif
 
 #ifdef MOZ_CRASHREPORTER
 #include "nsThread.h"
 #endif
 
-#include "VRManagerParent.h"            // for VRManagerParent
-
 // For VP9Benchmark::sBenchmarkFpsPref
 #include "Benchmark.h"
 
 static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
 
 #if defined(XP_WIN)
 // e10s forced enable pref, defined in nsAppRunner.cpp
 extern const char* kForceEnableE10sPref;
@@ -2444,18 +2442,21 @@ ContentParent::InitInternal(ProcessPrior
         Endpoint<PImageBridgeChild> endpoint;
         DebugOnly<bool> opened =
           gpm->CreateContentImageBridge(OtherPid(), &endpoint);
         MOZ_ASSERT(opened);
         Unused << SendInitImageBridge(Move(endpoint));
       }
 
       {
-        DebugOnly<bool> opened = gfx::PVRManager::Open(this);
+        Endpoint<PVRManagerChild> endpoint;
+        DebugOnly<bool> opened =
+          gpm->CreateContentVRManager(OtherPid(), &endpoint);
         MOZ_ASSERT(opened);
+        Unused << SendInitVRManager(Move(endpoint));
       }
     }
 #ifdef MOZ_WIDGET_GONK
     DebugOnly<bool> opened = PSharedBufferManager::Open(this);
     MOZ_ASSERT(opened);
 #endif
   }
 
@@ -3236,23 +3237,16 @@ ContentParent::AllocPAPZParent(const Tab
 }
 
 bool
 ContentParent::DeallocPAPZParent(PAPZParent* aActor)
 {
   return true;
 }
 
-gfx::PVRManagerParent*
-ContentParent::AllocPVRManagerParent(Transport* aTransport,
-                                     ProcessId aOtherProcess)
-{
-  return gfx::VRManagerParent::CreateCrossProcess(aTransport, aOtherProcess);
-}
-
 PBackgroundParent*
 ContentParent::AllocPBackgroundParent(Transport* aTransport,
                                       ProcessId aOtherProcess)
 {
   return BackgroundParent::Alloc(this, aTransport, aOtherProcess);
 }
 
 PProcessHangMonitorParent*
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -752,20 +752,16 @@ private:
   PBackgroundParent*
   AllocPBackgroundParent(Transport* aTransport, ProcessId aOtherProcess)
                          override;
 
   PProcessHangMonitorParent*
   AllocPProcessHangMonitorParent(Transport* aTransport,
                                  ProcessId aOtherProcess) override;
 
-  PVRManagerParent*
-  AllocPVRManagerParent(Transport* aTransport,
-                        ProcessId aOtherProcess) override;
-
   virtual bool RecvGetProcessAttributes(ContentParentId* aCpId,
                                         bool* aIsForApp,
                                         bool* aIsForBrowser) override;
 
   virtual bool
   RecvGetXPCOMProcessAttributes(bool* aIsOffline,
                                 bool* aIsConnected,
                                 bool* aIsLangRTL,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -382,17 +382,16 @@ struct BlobURLRegistrationData
 
 prio(normal upto urgent) sync protocol PContent
 {
     parent spawns PPluginModule;
 
     parent opens PProcessHangMonitor;
     parent opens PSharedBufferManager;
     parent opens PGMPService;
-    parent opens PVRManager;
     child opens PBackground;
 
     manages PAPZ;
     manages PBlob;
     manages PBluetooth;
     manages PBrowser;
     manages PCellBroadcast;
     manages PContentPermissionRequest;
@@ -467,16 +466,17 @@ both:
     // ignored and should be null/zero.
     async PWebBrowserPersistDocument(nullable PBrowser aBrowser,
                                      uint64_t aOuterWindowID);
 
 child:
     // Give the content process its endpoints to the compositor.
     async InitCompositor(Endpoint<PCompositorBridgeChild> compositor);
     async InitImageBridge(Endpoint<PImageBridgeChild> bridge);
+    async InitVRManager(Endpoint<PVRManagerChild> endpoint);
 
     /**
      * Enable system-level sandboxing features, if available.  Can
      * usually only be performed zero or one times.  The child may
      * abnormally exit if this fails; the details are OS-specific.
      */
     async SetProcessSandbox(MaybeFileDesc aBroker);
 
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -12,16 +12,17 @@
 #include "mozilla/layers/InProcessCompositorSession.h"
 #include "mozilla/layers/RemoteCompositorSession.h"
 #include "mozilla/widget/PlatformWidgetTypes.h"
 #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
 # include "mozilla/widget/CompositorWidgetChild.h"
 #endif
 #include "nsBaseWidget.h"
 #include "nsContentUtils.h"
+#include "VRManagerParent.h"
 #include "VsyncBridgeChild.h"
 #include "VsyncIOThreadHolder.h"
 
 namespace mozilla {
 namespace gfx {
 
 using namespace mozilla::layers;
 
@@ -413,16 +414,42 @@ GPUProcessManager::CreateContentImageBri
       return false;
     }
   }
 
   *aOutEndpoint = Move(childPipe);
   return true;
 }
 
+bool
+GPUProcessManager::CreateContentVRManager(base::ProcessId aOtherProcess,
+                                          ipc::Endpoint<PVRManagerChild>* aOutEndpoint)
+{
+  base::ProcessId gpuPid = base::GetCurrentProcId();
+
+  ipc::Endpoint<PVRManagerParent> parentPipe;
+  ipc::Endpoint<PVRManagerChild> childPipe;
+  nsresult rv = PVRManager::CreateEndpoints(
+    gpuPid,
+    aOtherProcess,
+    &parentPipe,
+    &childPipe);
+  if (NS_FAILED(rv)) {
+    gfxCriticalNote << "Could not create content compositor bridge: " << hexa(int(rv));
+    return false;
+  }
+
+  if (!VRManagerParent::CreateForContent(Move(parentPipe))) {
+    return false;
+  }
+
+  *aOutEndpoint = Move(childPipe);
+  return true;
+}
+
 already_AddRefed<APZCTreeManager>
 GPUProcessManager::GetAPZCTreeManagerForLayers(uint64_t aLayersId)
 {
   return CompositorBridgeParent::GetAPZCTreeManager(aLayersId);
 }
 
 uint64_t
 GPUProcessManager::AllocateLayerTreeId()
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -40,16 +40,17 @@ class TabParent;
 namespace ipc {
 class GeckoChildProcessHost;
 } // namespace ipc
 namespace gfx {
 
 class GPUChild;
 class VsyncBridgeChild;
 class VsyncIOThreadHolder;
+class PVRManagerChild;
 
 // The GPUProcessManager is a singleton responsible for creating GPU-bound
 // objects that may live in another process. Currently, it provides access
 // to the compositor via CompositorBridgeParent.
 class GPUProcessManager final : public GPUProcessHost::Listener
 {
   typedef layers::APZCTreeManager APZCTreeManager;
   typedef layers::ClientLayerManager ClientLayerManager;
@@ -78,19 +79,20 @@ public:
     ClientLayerManager* aLayerManager,
     CSSToLayoutDeviceScale aScale,
     bool aUseAPZ,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
   bool CreateContentCompositorBridge(base::ProcessId aOtherProcess,
                                      ipc::Endpoint<PCompositorBridgeChild>* aOutEndpoint);
-
   bool CreateContentImageBridge(base::ProcessId aOtherProcess,
                                 ipc::Endpoint<PImageBridgeChild>* aOutEndpoint);
+  bool CreateContentVRManager(base::ProcessId aOtherProcess,
+                              ipc::Endpoint<PVRManagerChild>* aOutEndpoint);
 
   // This returns a reference to the APZCTreeManager to which
   // pan/zoom-related events can be sent.
   already_AddRefed<APZCTreeManager> GetAPZCTreeManagerForLayers(uint64_t aLayersId);
 
   // Allocate an ID that can be used to refer to a layer tree and
   // associated resources that live only on the compositor thread.
   //
--- a/gfx/vr/ipc/VRManagerChild.cpp
+++ b/gfx/vr/ipc/VRManagerChild.cpp
@@ -38,33 +38,29 @@ VRManagerChild::~VRManagerChild()
 
 /*static*/ VRManagerChild*
 VRManagerChild::Get()
 {
   MOZ_ASSERT(sVRManagerChildSingleton);
   return sVRManagerChildSingleton;
 }
 
-/*static*/ VRManagerChild*
-VRManagerChild::StartUpInChildProcess(Transport* aTransport, ProcessId aOtherPid)
+/* static */ bool
+VRManagerChild::InitForContent(Endpoint<PVRManagerChild>&& aEndpoint)
 {
   MOZ_ASSERT(NS_IsMainThread());
-
-  // There's only one VRManager per child process.
   MOZ_ASSERT(!sVRManagerChildSingleton);
 
   RefPtr<VRManagerChild> child(new VRManagerChild());
-  if (!child->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ChildSide)) {
+  if (!aEndpoint.Bind(child, nullptr)) {
     NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
-    return nullptr;
+    return false;
   }
-
   sVRManagerChildSingleton = child;
-
-  return sVRManagerChildSingleton;
+  return true;
 }
 
 /*static*/ void
 VRManagerChild::StartUpSameProcess()
 {
   NS_ASSERTION(NS_IsMainThread(), "Should be on the main Thread!");
   if (sVRManagerChildSingleton == nullptr) {
     sVRManagerChildSingleton = new VRManagerChild();
--- a/gfx/vr/ipc/VRManagerChild.h
+++ b/gfx/vr/ipc/VRManagerChild.h
@@ -23,20 +23,19 @@ class VRDeviceProxy;
 class VRManagerChild : public PVRManagerChild
 {
 public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(VRManagerChild)
 
   int GetInputFrameID();
   bool GetVRDevices(nsTArray<RefPtr<VRDeviceProxy> >& aDevices);
   bool RefreshVRDevicesWithCallback(dom::Navigator* aNavigator);
-  static VRManagerChild* StartUpInChildProcess(Transport* aTransport,
-                                               ProcessId aOtherProcess);
 
   static void StartUpSameProcess();
+  static bool InitForContent(Endpoint<PVRManagerChild>&& aEndpoint);
   static void ShutDown();
 
 
   static VRManagerChild* Get();
 
 protected:
   explicit VRManagerChild();
   ~VRManagerChild();
--- a/gfx/vr/ipc/VRManagerParent.cpp
+++ b/gfx/vr/ipc/VRManagerParent.cpp
@@ -12,19 +12,17 @@
 #include "mozilla/TimeStamp.h"               // for TimeStamp
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/unused.h"
 #include "VRManager.h"
 
 namespace mozilla {
 namespace gfx {
 
-VRManagerParent::VRManagerParent(MessageLoop* aLoop,
-                                 Transport* aTransport,
-                                 ProcessId aChildProcessId)
+VRManagerParent::VRManagerParent(ProcessId aChildProcessId)
 {
   MOZ_COUNT_CTOR(VRManagerParent);
   MOZ_ASSERT(NS_IsMainThread());
 
   SetOtherProcessId(aChildProcessId);
 }
 
 VRManagerParent::~VRManagerParent()
@@ -45,47 +43,50 @@ void VRManagerParent::RegisterWithManage
 
 void VRManagerParent::UnregisterFromManager()
 {
   VRManager* vm = VRManager::Get();
   vm->RemoveVRManagerParent(this);
   mVRManagerHolder = nullptr;
 }
 
-/*static*/ void
-VRManagerParent::ConnectVRManagerInParentProcess(VRManagerParent* aVRManager,
-                                ipc::Transport* aTransport,
-                                base::ProcessId aOtherPid)
+/* static */ bool
+VRManagerParent::CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint)
 {
-  aVRManager->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop(), ipc::ParentSide);
-  aVRManager->RegisterWithManager();
+  MessageLoop* loop = layers::CompositorThreadHolder::Loop();
+
+  RefPtr<VRManagerParent> vmp = new VRManagerParent(aEndpoint.OtherPid());
+  loop->PostTask(NewRunnableMethod<Endpoint<PVRManagerParent>&&>(
+    vmp, &VRManagerParent::Bind, Move(aEndpoint)));
+
+  return true;
 }
 
-/*static*/ VRManagerParent*
-VRManagerParent::CreateCrossProcess(Transport* aTransport, ProcessId aChildProcessId)
+void
+VRManagerParent::Bind(Endpoint<PVRManagerParent>&& aEndpoint)
 {
-  MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
-  RefPtr<VRManagerParent> vmp = new VRManagerParent(loop, aTransport, aChildProcessId);
-  vmp->mSelfRef = vmp;
-  loop->PostTask(NewRunnableFunction(ConnectVRManagerInParentProcess,
-                                     vmp.get(), aTransport, aChildProcessId));
-  return vmp.get();
+  if (!aEndpoint.Bind(this, nullptr)) {
+    return;
+  }
+  mSelfRef = this;
+
+  RegisterWithManager();
 }
 
 /*static*/ void
 VRManagerParent::RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager)
 {
   aVRManager->RegisterWithManager();
 }
 
 /*static*/ VRManagerParent*
 VRManagerParent::CreateSameProcess()
 {
   MessageLoop* loop = mozilla::layers::CompositorThreadHolder::Loop();
-  RefPtr<VRManagerParent> vmp = new VRManagerParent(loop, nullptr, base::GetCurrentProcId());
+  RefPtr<VRManagerParent> vmp = new VRManagerParent(base::GetCurrentProcId());
   vmp->mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
   vmp->mSelfRef = vmp;
   loop->PostTask(NewRunnableFunction(RegisterVRManagerInCompositorThread, vmp.get()));
   return vmp.get();
 }
 
 void
 VRManagerParent::DeferredDestroy()
@@ -101,29 +102,17 @@ VRManagerParent::ActorDestroy(ActorDestr
   MessageLoop::current()->PostTask(NewRunnableMethod(this, &VRManagerParent::DeferredDestroy));
 }
 
 mozilla::ipc::IToplevelProtocol*
 VRManagerParent::CloneToplevel(const InfallibleTArray<mozilla::ipc::ProtocolFdMapping>& aFds,
                                base::ProcessHandle aPeerProcess,
                                mozilla::ipc::ProtocolCloneContext* aCtx)
 {
-  for (unsigned int i = 0; i < aFds.Length(); i++) {
-    if (aFds[i].protocolId() == unsigned(GetProtocolId())) {
-      UniquePtr<Transport> transport =
-        OpenDescriptor(aFds[i].fd(), Transport::MODE_SERVER);
-      PVRManagerParent* vm = CreateCrossProcess(transport.get(), base::GetProcId(aPeerProcess));
-      vm->CloneManagees(this, aCtx);
-      vm->IToplevelProtocol::SetTransport(Move(transport));
-      // The reference to the compositor thread is held in OnChannelConnected().
-      // We need to do this for cloned actors, too.
-      vm->OnChannelConnected(base::GetProcId(aPeerProcess));
-      return vm;
-    }
-  }
+  MOZ_ASSERT_UNREACHABLE("Not supported");
   return nullptr;
 }
 
 void
 VRManagerParent::OnChannelConnected(int32_t aPid)
 {
   mCompositorThreadHolder = layers::CompositorThreadHolder::GetSingleton();
 }
--- a/gfx/vr/ipc/VRManagerParent.h
+++ b/gfx/vr/ipc/VRManagerParent.h
@@ -18,21 +18,20 @@ namespace mozilla {
 namespace gfx {
 
 class VRManager;
 
 class VRManagerParent final : public PVRManagerParent
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(VRManagerParent)
 public:
-  VRManagerParent(MessageLoop* aLoop, Transport* aTransport, ProcessId aChildProcessId);
+  explicit VRManagerParent(ProcessId aChildProcessId);
 
-  static VRManagerParent* CreateCrossProcess(Transport* aTransport,
-                                              ProcessId aOtherProcess);
   static VRManagerParent* CreateSameProcess();
+  static bool CreateForContent(Endpoint<PVRManagerParent>&& aEndpoint);
 
 
   // Overriden from IToplevelProtocol
   ipc::IToplevelProtocol*
   CloneToplevel(const InfallibleTArray<ipc::ProtocolFdMapping>& aFds,
                 base::ProcessHandle aPeerProcess,
                 mozilla::ipc::ProtocolCloneContext* aCtx) override;
 
@@ -47,24 +46,22 @@ protected:
   virtual bool RecvKeepSensorTracking(const uint32_t& aDeviceID) override;
   virtual bool RecvSetFOV(const uint32_t& aDeviceID,
                           const VRFieldOfView& aFOVLeft,
                           const VRFieldOfView& aFOVRight,
                           const double& zNear,
                           const double& zFar) override;
 
 private:
-
   void RegisterWithManager();
   void UnregisterFromManager();
 
+  void Bind(Endpoint<PVRManagerParent>&& aEndpoint);
+
   static void RegisterVRManagerInCompositorThread(VRManagerParent* aVRManager);
-  static void ConnectVRManagerInParentProcess(VRManagerParent* aVRManager,
-                                              ipc::Transport* aTransport,
-                                              base::ProcessId aOtherPid);
 
   void DeferredDestroy();
 
   // This keeps us alive until ActorDestroy(), at which point we do a
   // deferred destruction of ourselves.
   RefPtr<VRManagerParent> mSelfRef;
 
   // Keep the compositor thread alive, until we have destroyed ourselves.