Split up CompositorBridgeParent initialization. (bug 1282348 part 1, r=mattwoodrow,billm)
authorDavid Anderson <dvander@alliedmods.net>
Sun, 17 Jul 2016 21:24:27 -0700
changeset 388839 842631f306bc5698c7f778270f57f42d704ff59e
parent 388838 7bda4f49e0f50b127a6510b6609f6e305c6458eb
child 388840 31ee282cfbbde6f4f9a4302f3810f60823c8a7b4
push id23247
push userbmo:jgilbert@mozilla.com
push dateMon, 18 Jul 2016 06:13:58 +0000
reviewersmattwoodrow, billm
bugs1282348
milestone50.0a1
Split up CompositorBridgeParent initialization. (bug 1282348 part 1, r=mattwoodrow,billm)
gfx/ipc/CompositorSession.cpp
gfx/ipc/CompositorSession.h
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
gfx/layers/ipc/CompositorThread.cpp
--- a/gfx/ipc/CompositorSession.cpp
+++ b/gfx/ipc/CompositorSession.cpp
@@ -12,89 +12,74 @@
 namespace mozilla {
 namespace layers {
 
 using namespace widget;
 
 class InProcessCompositorSession final : public CompositorSession
 {
 public:
-  InProcessCompositorSession(
-    nsIWidget* aWidget,
-    ClientLayerManager* aLayerManager,
-    CSSToLayoutDeviceScale aScale,
-    bool aUseAPZ,
-    bool aUseExternalSurfaceSize,
-    const gfx::IntSize& aSurfaceSize);
+  InProcessCompositorSession(widget::CompositorWidget* aWidget,
+                             CompositorBridgeChild* aChild,
+                             CompositorBridgeParent* aParent);
 
   CompositorBridgeParent* GetInProcessBridge() const override;
   void SetContentController(GeckoContentController* aController) override;
   uint64_t RootLayerTreeId() const override;
   already_AddRefed<APZCTreeManager> GetAPZCTreeManager() const override;
   void Shutdown() override;
 
 private:
   RefPtr<CompositorBridgeParent> mCompositorBridgeParent;
   RefPtr<CompositorWidget> mCompositorWidget;
 };
 
-already_AddRefed<CompositorSession>
+RefPtr<CompositorSession>
 CompositorSession::CreateInProcess(nsIWidget* aWidget,
                                    ClientLayerManager* aLayerManager,
                                    CSSToLayoutDeviceScale aScale,
                                    bool aUseAPZ,
                                    bool aUseExternalSurfaceSize,
                                    const gfx::IntSize& aSurfaceSize)
 {
-  RefPtr<InProcessCompositorSession> session = new InProcessCompositorSession(
-    aWidget,
-    aLayerManager,
-    aScale,
-    aUseAPZ,
-    aUseExternalSurfaceSize,
-    aSurfaceSize);
-  return session.forget();
+  CompositorWidgetInitData initData;
+  aWidget->GetCompositorWidgetInitData(&initData);
+
+  RefPtr<CompositorWidget> widget = CompositorWidget::CreateLocal(initData, aWidget);
+  RefPtr<CompositorBridgeChild> child = new CompositorBridgeChild(aLayerManager);
+  RefPtr<CompositorBridgeParent> parent =
+    child->InitSameProcess(widget, aScale, aUseAPZ, aUseExternalSurfaceSize, aSurfaceSize);
+
+  return new InProcessCompositorSession(widget, child, parent);
 }
 
-CompositorSession::CompositorSession()
- : mCompositorWidgetDelegate(nullptr)
+CompositorSession::CompositorSession(CompositorWidgetDelegate* aDelegate,
+                                     CompositorBridgeChild* aChild)
+ : mCompositorWidgetDelegate(nullptr),
+   mCompositorBridgeChild(aChild)
 {
 }
 
 CompositorSession::~CompositorSession()
 {
 }
 
 CompositorBridgeChild*
 CompositorSession::GetCompositorBridgeChild()
 {
   return mCompositorBridgeChild;
 }
 
-InProcessCompositorSession::InProcessCompositorSession(nsIWidget* aWidget,
-                                                       ClientLayerManager* aLayerManager,
-                                                       CSSToLayoutDeviceScale aScale,
-                                                       bool aUseAPZ,
-                                                       bool aUseExternalSurfaceSize,
-                                                       const gfx::IntSize& aSurfaceSize)
+InProcessCompositorSession::InProcessCompositorSession(widget::CompositorWidget* aWidget,
+                                                       CompositorBridgeChild* aChild,
+                                                       CompositorBridgeParent* aParent)
+ : CompositorSession(aWidget->AsDelegate(), aChild),
+   mCompositorBridgeParent(aParent),
+   mCompositorWidget(aWidget)
 {
-  CompositorWidgetInitData initData;
-  aWidget->GetCompositorWidgetInitData(&initData);
-  mCompositorWidget = CompositorWidget::CreateLocal(initData, aWidget);
-  mCompositorWidgetDelegate = mCompositorWidget->AsDelegate();
-
-  mCompositorBridgeParent = new CompositorBridgeParent(
-    mCompositorWidget,
-    aScale,
-    aUseAPZ,
-    aUseExternalSurfaceSize,
-    aSurfaceSize);
-  mCompositorBridgeChild = new CompositorBridgeChild(aLayerManager);
-  mCompositorBridgeChild->OpenSameProcess(mCompositorBridgeParent);
-  mCompositorBridgeParent->SetOtherProcessId(base::GetCurrentProcId());
 }
 
 CompositorBridgeParent*
 InProcessCompositorSession::GetInProcessBridge() const
 {
   return mCompositorBridgeParent;
 }
 
--- a/gfx/ipc/CompositorSession.h
+++ b/gfx/ipc/CompositorSession.h
@@ -60,30 +60,31 @@ public:
   CompositorBridgeChild* GetCompositorBridgeChild();
 
   // Return the proxy for accessing the compositor's widget.
   CompositorWidgetDelegate* GetCompositorWidgetDelegate() {
     return mCompositorWidgetDelegate;
   }
 
 protected:
-  CompositorSession();
+  CompositorSession(CompositorWidgetDelegate* aDelegate,
+                    CompositorBridgeChild* aChild);
   virtual ~CompositorSession();
 
-  static already_AddRefed<CompositorSession> CreateInProcess(
+  static RefPtr<CompositorSession> CreateInProcess(
     nsIWidget* aWidget,
     ClientLayerManager* aLayerManager,
     CSSToLayoutDeviceScale aScale,
     bool aUseAPZ,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
 protected:
+  CompositorWidgetDelegate* mCompositorWidgetDelegate;
   RefPtr<CompositorBridgeChild> mCompositorBridgeChild;
-  CompositorWidgetDelegate* mCompositorWidgetDelegate;
 
 private:
   DISALLOW_COPY_AND_ASSIGN(CompositorSession);
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -144,17 +144,17 @@ GPUProcessManager::DestroyProcess()
     return;
   }
 
   mProcess->Shutdown();
   mProcess = nullptr;
   mGPUChild = nullptr;
 }
 
-already_AddRefed<CompositorSession>
+RefPtr<CompositorSession>
 GPUProcessManager::CreateTopLevelCompositor(nsIWidget* aWidget,
                                             ClientLayerManager* aLayerManager,
                                             CSSToLayoutDeviceScale aScale,
                                             bool aUseAPZ,
                                             bool aUseExternalSurfaceSize,
                                             const gfx::IntSize& aSurfaceSize)
 {
   return CompositorSession::CreateInProcess(
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -55,17 +55,17 @@ public:
   // If not using a GPU process, launch a new GPU process asynchronously.
   void EnableGPUProcess();
 
   // Ensure that GPU-bound methods can be used. If no GPU process is being
   // used, or one is launched and ready, this function returns immediately.
   // Otherwise it blocks until the GPU process has finished launching.
   void EnsureGPUReady();
 
-  already_AddRefed<layers::CompositorSession> CreateTopLevelCompositor(
+  RefPtr<layers::CompositorSession> CreateTopLevelCompositor(
     nsIWidget* aWidget,
     layers::ClientLayerManager* aLayerManager,
     CSSToLayoutDeviceScale aScale,
     bool aUseAPZ,
     bool aUseExternalSurfaceSize,
     const gfx::IntSize& aSurfaceSize);
 
   layers::PCompositorBridgeParent* CreateTabCompositorBridge(
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -184,26 +184,33 @@ CompositorBridgeChild::Create(Transport*
   int32_t width;
   int32_t height;
   sCompositorBridge->SendGetTileSize(&width, &height);
   gfxPlatform::GetPlatform()->SetTileSize(width, height);
 
   return sCompositorBridge;
 }
 
-bool
-CompositorBridgeChild::OpenSameProcess(CompositorBridgeParent* aParent)
+CompositorBridgeParent*
+CompositorBridgeChild::InitSameProcess(widget::CompositorWidget* aWidget,
+                                       CSSToLayoutDeviceScale aScale,
+                                       bool aUseAPZ,
+                                       bool aUseExternalSurface,
+                                       const gfx::IntSize& aSurfaceSize)
 {
-  MOZ_ASSERT(aParent);
+  mCompositorBridgeParent =
+    new CompositorBridgeParent(aScale, aUseExternalSurface, aSurfaceSize);
 
-  mCompositorBridgeParent = aParent;
   mCanSend = Open(mCompositorBridgeParent->GetIPCChannel(),
                   CompositorThreadHolder::Loop(),
                   ipc::ChildSide);
-  return mCanSend;
+  MOZ_RELEASE_ASSERT(mCanSend);
+
+  mCompositorBridgeParent->InitSameProcess(aWidget, aUseAPZ);
+  return mCompositorBridgeParent;
 }
 
 /*static*/ CompositorBridgeChild*
 CompositorBridgeChild::Get()
 {
   // This is only expected to be used in child processes.
   MOZ_ASSERT(!XRE_IsParentProcess());
   return sCompositorBridge;
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -18,19 +18,23 @@
 #include "nsHashKeys.h"                 // for nsUint64HashKey
 #include "nsISupportsImpl.h"            // for NS_INLINE_DECL_REFCOUNTING
 #include "ThreadSafeRefcountingWithMainThreadDestruction.h"
 #include "nsWeakReference.h"
 
 namespace mozilla {
 
 namespace dom {
-  class TabChild;
+class TabChild;
 } // namespace dom
 
+namespace widget {
+class CompositorWidget;
+} // namespace widget
+
 namespace layers {
 
 using mozilla::dom::TabChild;
 
 class ClientLayerManager;
 class CompositorBridgeParent;
 class TextureClient;
 class TextureClientPool;
@@ -58,20 +62,25 @@ public:
    * We're asked to create a new Compositor in response to an Opens()
    * or Bridge() request from our parent process.  The Transport is to
    * the compositor's context.
    */
   static PCompositorBridgeChild*
   Create(Transport* aTransport, ProcessId aOtherProcess);
 
   /**
-   * Initialize the CompositorBridgeChild and open the connection in the non-multi-process
-   * case.
+   * Initialize the CompositorBridgeChild, create CompositorBridgeParent, and
+   * open a same-process connection.
    */
-  bool OpenSameProcess(CompositorBridgeParent* aParent);
+  CompositorBridgeParent* InitSameProcess(
+    widget::CompositorWidget* aWidget,
+    CSSToLayoutDeviceScale aScale,
+    bool aUseAPZ,
+    bool aUseExternalSurface,
+    const gfx::IntSize& aSurfaceSize);
 
   static CompositorBridgeChild* Get();
 
   static bool ChildProcessHasCompositorBridge();
 
   void AddOverfillObserver(ClientLayerManager* aLayerManager);
 
   virtual bool
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -153,17 +153,17 @@ CompositorBridgeParent::ForEachIndirectL
   * This map is used by the ImageBridge protocol to trigger
   * compositions without having to keep references to the
   * compositor
   */
 typedef map<uint64_t,CompositorBridgeParent*> CompositorMap;
 static StaticAutoPtr<CompositorMap> sCompositorMap;
 
 void
-CompositorBridgeParent::Initialize()
+CompositorBridgeParent::Setup()
 {
   EnsureLayerTreeMapReady();
 
   MOZ_ASSERT(!sCompositorMap);
   sCompositorMap = new CompositorMap;
 }
 
 void
@@ -582,23 +582,22 @@ CompositorVsyncScheduler::ComposeToTarge
 }
 
 static inline MessageLoop*
 CompositorLoop()
 {
   return CompositorThreadHolder::Loop();
 }
 
-CompositorBridgeParent::CompositorBridgeParent(widget::CompositorWidget* aWidget,
-                                               CSSToLayoutDeviceScale aScale,
-                                               bool aUseAPZ,
+CompositorBridgeParent::CompositorBridgeParent(CSSToLayoutDeviceScale aScale,
                                                bool aUseExternalSurfaceSize,
                                                const gfx::IntSize& aSurfaceSize)
   : CompositorBridgeParentIPCAllocator("CompositorBridgeParent")
-  , mWidget(aWidget)
+  , mWidget(nullptr)
+  , mScale(aScale)
   , mIsTesting(false)
   , mPendingTransaction(0)
   , mPaused(false)
   , mUseExternalSurfaceSize(aUseExternalSurfaceSize)
   , mEGLSurfaceSize(aSurfaceSize)
   , mPauseCompositionMonitor("PauseCompositionMonitor")
   , mResumeCompositionMonitor("ResumeCompositionMonitor")
   , mResetCompositorMonitor("ResetCompositorMonitor")
@@ -608,16 +607,36 @@ CompositorBridgeParent::CompositorBridge
   , mCompositorThreadHolder(CompositorThreadHolder::GetSingleton())
   , mCompositorScheduler(nullptr)
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
   , mLastPluginUpdateLayerTreeId(0)
   , mDeferPluginWindows(false)
   , mPluginWindowsHidden(false)
 #endif
 {
+}
+
+void
+CompositorBridgeParent::InitSameProcess(widget::CompositorWidget* aWidget, bool aUseAPZ)
+{
+  mWidget = aWidget;
+  if (aUseAPZ) {
+    mApzcTreeManager = new APZCTreeManager();
+  }
+
+  // IPDL initialization. mSelfRef is cleared in DeferredDestroy.
+  SetOtherProcessId(base::GetCurrentProcId());
+  mSelfRef = this;
+
+  Initialize();
+}
+
+void
+CompositorBridgeParent::Initialize()
+{
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(CompositorThread(),
              "The compositor thread must be Initialized before instanciating a CompositorBridgeParent.");
 
   // Always run destructor on the main thread
   SetMessageLoopToPostDestructionTo(MessageLoop::current());
 
   mCompositorID = 0;
@@ -631,25 +650,18 @@ CompositorBridgeParent::CompositorBridge
   CompositorLoop()->PostTask(NewRunnableFunction(SetThreadPriority));
 
 
   { // scope lock
     MonitorAutoLock lock(*sIndirectLayerTreesLock);
     sIndirectLayerTrees[mRootLayerTreeID].mParent = this;
   }
 
-  if (aUseAPZ) {
-    mApzcTreeManager = new APZCTreeManager();
-  }
-
-  mCompositorScheduler = new CompositorVsyncScheduler(this, aWidget);
-  LayerScope::SetPixelScale(aScale.scale);
-
-  // mSelfRef is cleared in DeferredDestroy.
-  mSelfRef = this;
+  mCompositorScheduler = new CompositorVsyncScheduler(this, mWidget);
+  LayerScope::SetPixelScale(mScale.scale);
 }
 
 uint64_t
 CompositorBridgeParent::RootLayerTreeId()
 {
   return mRootLayerTreeID;
 }
 
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -207,22 +207,25 @@ class CompositorBridgeParent final : pub
                                      public ShmemAllocator
 {
   friend class CompositorVsyncScheduler;
   friend class CompositorThreadHolder;
   friend class InProcessCompositorSession;
   friend class gfx::GPUProcessManager;
 
 public:
-  explicit CompositorBridgeParent(widget::CompositorWidget* aWidget,
-                                  CSSToLayoutDeviceScale aScale,
-                                  bool aUseAPZ,
+  explicit CompositorBridgeParent(CSSToLayoutDeviceScale aScale,
                                   bool aUseExternalSurfaceSize,
                                   const gfx::IntSize& aSurfaceSize);
 
+  // Must only be called by CompositorBridgeChild. After invoking this, the
+  // IPC channel is active and RecvWillStop/ActorDestroy must be called to
+  // free the compositor.
+  void InitSameProcess(widget::CompositorWidget* aWidget, bool aUseAPZ);
+
   virtual bool RecvGetFrameUniformity(FrameUniformityData* aOutData) override;
   virtual bool RecvRequestOverfill() override;
   virtual bool RecvWillClose() override;
   virtual bool RecvPause() override;
   virtual bool RecvResume() override;
   virtual bool RecvNotifyHidden(const uint64_t& id) override { return true; }
   virtual bool RecvNotifyVisible(const uint64_t& id) override { return true; }
   virtual bool RecvNotifyChildCreated(const uint64_t& child) override;
@@ -471,16 +474,19 @@ public:
 
   void ForceComposeToTarget(gfx::DrawTarget* aTarget, const gfx::IntRect* aRect = nullptr);
 
   bool AsyncPanZoomEnabled() const {
     return !!mApzcTreeManager;
   }
 
 private:
+
+  void Initialize();
+
   /**
    * Called during destruction in order to release resources as early as possible.
    */
   void StopAndClearResources();
 
   /**
    * This returns a reference to the APZCTreeManager to which
    * pan/zoom-related events can be sent.
@@ -556,17 +562,17 @@ protected:
   /**
    * Remove a compositor from the global compositor map.
    */
   static CompositorBridgeParent* RemoveCompositor(uint64_t id);
 
   /**
    * Creates the global compositor map.
    */
-  static void Initialize();
+  static void Setup();
 
   /**
    * Destroys the compositor thread and global compositor map.
    */
   static void Shutdown();
 
   /**
    * Finish the shutdown operation on the compositor thread.
@@ -586,16 +592,17 @@ protected:
   template <typename Lambda>
   inline void ForEachIndirectLayerTree(const Lambda& aCallback);
 
   RefPtr<LayerManagerComposite> mLayerManager;
   RefPtr<Compositor> mCompositor;
   RefPtr<AsyncCompositionManager> mCompositionManager;
   widget::CompositorWidget* mWidget;
   TimeStamp mTestTime;
+  CSSToLayoutDeviceScale mScale;
   bool mIsTesting;
 
   uint64_t mPendingTransaction;
 
   bool mPaused;
 
   bool mUseExternalSurfaceSize;
   gfx::IntSize mEGLSurfaceSize;
--- a/gfx/layers/ipc/CompositorThread.cpp
+++ b/gfx/layers/ipc/CompositorThread.cpp
@@ -102,17 +102,17 @@ CompositorThreadHolder::CreateCompositor
   options.message_loop_type = MessageLoop::TYPE_UI;
 #endif
 
   if (!compositorThread->StartWithOptions(options)) {
     delete compositorThread;
     return nullptr;
   }
 
-  CompositorBridgeParent::Initialize();
+  CompositorBridgeParent::Setup();
 
   return compositorThread;
 }
 
 void
 CompositorThreadHolder::Start()
 {
   MOZ_ASSERT(NS_IsMainThread(), "Should be on the main Thread!");