Bug 1320817 - Move child process PAPZ initialization into TabChild::InitRenderingState. r=kats
authorRyan Hunt <rhunt@eqrion.net>
Mon, 28 Nov 2016 22:21:27 -0600
changeset 325322 1d9ec0ad1388284030757003dbffa93bcaf9c0e0
parent 325321 5ee72d9b8e3ef32e4dceca79a0682641b7401b83
child 325323 c30011abb0f2357132b5098c2d3e2ce35b880a12
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerskats
bugs1320817
milestone53.0a1
Bug 1320817 - Move child process PAPZ initialization into TabChild::InitRenderingState. r=kats
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/PContent.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
gfx/layers/apz/util/ContentProcessController.cpp
gfx/layers/apz/util/ContentProcessController.h
gfx/layers/ipc/CompositorBridgeChild.cpp
gfx/layers/ipc/CompositorBridgeChild.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1502,30 +1502,16 @@ ContentChild::RecvSetProcessSandbox(cons
 #endif /* XP_LINUX && !OS_ANDROID */
 #endif /* MOZ_CRASHREPORTER */
 #endif /* MOZ_CONTENT_SANDBOX */
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-ContentChild::RecvNotifyLayerAllocated(const dom::TabId& aTabId, const uint64_t& aLayersId)
-{
-  if (!CompositorBridgeChild::Get()->IPCOpen()) {
-    return IPC_OK();
-  }
-
-  // Note: sending the constructor could fail, but we do not propagate the
-  // error back since the GPU process is fallible.
-  APZChild* apz = ContentProcessController::Create(aTabId);
-  CompositorBridgeChild::Get()->SendPAPZConstructor(apz, aLayersId);
-  return IPC_OK();
-}
-
-mozilla::ipc::IPCResult
 ContentChild::RecvBidiKeyboardNotify(const bool& aIsLangRTL,
                                      const bool& aHaveBidiKeyboards)
 {
   // bidi is always of type PuppetBidiKeyboard* (because in the child, the only
   // possible implementation of nsIBidiKeyboard is PuppetBidiKeyboard).
   PuppetBidiKeyboard* bidi = static_cast<PuppetBidiKeyboard*>(nsContentUtils::GetBidiKeyboard());
   if (bidi) {
     bidi->SetBidiKeyboardInfo(aIsLangRTL, aHaveBidiKeyboards);
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -368,18 +368,16 @@ public:
 
   virtual bool DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild*) override;
 
   virtual mozilla::ipc::IPCResult RecvSetOffline(const bool& offline) override;
 
   virtual mozilla::ipc::IPCResult RecvSetConnectivity(const bool& connectivity) override;
   virtual mozilla::ipc::IPCResult RecvSetCaptivePortalState(const int32_t& state) override;
 
-  virtual mozilla::ipc::IPCResult RecvNotifyLayerAllocated(const dom::TabId& aTabId, const uint64_t& aLayersId) override;
-
   virtual mozilla::ipc::IPCResult RecvBidiKeyboardNotify(const bool& isLangRTL,
                                                          const bool& haveBidiKeyboards) override;
 
   virtual mozilla::ipc::IPCResult RecvNotifyVisited(const URIParams& aURI) override;
 
   // auto remove when alertfinished is received.
   nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
 
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -1376,21 +1376,17 @@ ContentParent::AllocateLayerTreeId(Conte
   *aId = gpu->AllocateLayerTreeId();
 
   if (!aContent || !aTopLevel) {
     return false;
   }
 
   gpu->MapLayerTreeId(*aId, aContent->OtherPid());
 
-  if (!gfxPlatform::AsyncPanZoomEnabled()) {
-    return true;
-  }
-
-  return aContent->SendNotifyLayerAllocated(aTabId, *aId);
+  return true;
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvAllocateLayerTreeId(const ContentParentId& aCpId,
                                        const TabId& aTabId, uint64_t* aId)
 {
   // Protect against spoofing by a compromised child. aCpId must either
   // correspond to the process that this ContentParent represents or be a
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -437,21 +437,16 @@ child:
      * abnormally exit if this fails; the details are OS-specific.
      */
     async SetProcessSandbox(MaybeFileDesc aBroker);
 
     async PMemoryReportRequest(uint32_t generation, bool anonymize,
                                bool minimizeMemoryUsage, MaybeFileDesc DMDFile);
 
     /**
-     * Sent to notify that aTabId has been allocated aLayersId
-     */
-    async NotifyLayerAllocated(TabId aTabId, uint64_t aLayersId);
-
-    /**
      * Communication between the PuppetBidiKeyboard and the actual
      * BidiKeyboard hosted by the parent
      */
     async BidiKeyboardNotify(bool isLangRTL, bool haveBidiKeyboards);
 
     /**
      * Dump this process's GC and CC logs to the provided files.
      *
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -22,20 +22,22 @@
 #include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
 #include "mozilla/plugins/PluginWidgetChild.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/ipc/DocumentRendererChild.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/layers/APZChild.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/APZCTreeManager.h"
+#include "mozilla/layers/APZCTreeManagerChild.h"
 #include "mozilla/layers/APZEventState.h"
 #include "mozilla/layers/ContentProcessController.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/DoubleTapToZoom.h"
+#include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/ShadowLayers.h"
 #include "mozilla/layout/RenderFrameChild.h"
 #include "mozilla/layout/RenderFrameParent.h"
 #include "mozilla/LookAndFeel.h"
 #include "mozilla/MouseEvents.h"
 #include "mozilla/Move.h"
@@ -2532,29 +2534,51 @@ TabChild::InitRenderingState(const Textu
       if (!sTabChildren) {
         sTabChildren = new TabChildMap;
       }
       MOZ_ASSERT(!sTabChildren->Get(aLayersId));
       sTabChildren->Put(aLayersId, this);
       mLayersId = aLayersId;
     }
 
-    mApzcTreeManager = CompositorBridgeChild::Get()->GetAPZCTreeManager(mLayersId);
+    InitAPZState();
 
     nsCOMPtr<nsIObserverService> observerService =
         mozilla::services::GetObserverService();
 
     if (observerService) {
         observerService->AddObserver(this,
                                      BEFORE_FIRST_PAINT,
                                      false);
     }
 }
 
 void
+TabChild::InitAPZState()
+{
+  auto cbc = CompositorBridgeChild::Get();
+
+  if (!cbc->GetAPZEnabled(mLayersId)) {
+    return;
+  }
+
+  // Initialize the ApzcTreeManager. This takes multiple casts because of ugly multiple inheritance.
+  PAPZCTreeManagerChild* baseProtocol = cbc->SendPAPZCTreeManagerConstructor(mLayersId);
+  APZCTreeManagerChild* derivedProtocol = static_cast<APZCTreeManagerChild*>(baseProtocol);
+
+  mApzcTreeManager = RefPtr<IAPZCTreeManager>(derivedProtocol);
+
+  // Initialize the GeckoContentController for this tab. We don't hold a reference because we don't need it.
+  // The ContentProcessController will hold a reference to the tab, and will be destroyed by the compositor or ipdl
+  // during destruction.
+  RefPtr<GeckoContentController> contentController = new ContentProcessController(this);
+  cbc->SendPAPZConstructor(new APZChild(contentController), mLayersId);
+}
+
+void
 TabChild::GetDPI(float* aDPI)
 {
     *aDPI = -1.0;
     if (!mRemoteFrame) {
         return;
     }
 
     if (mDPI > 0) {
@@ -2887,21 +2911,17 @@ TabChild::ReinitRendering()
     NS_WARNING("failed to re-construct LayersChild");
     return;
   }
 
   RefPtr<LayerManager> lm = mPuppetWidget->RecreateLayerManager(shadowManager);
   ShadowLayerForwarder* lf = lm->AsShadowForwarder();
   lf->IdentifyTextureHost(mTextureFactoryIdentifier);
 
-  mApzcTreeManager = CompositorBridgeChild::Get()->GetAPZCTreeManager(mLayersId);
-  if (mApzcTreeManager) {
-    APZChild* apz = ContentProcessController::Create(mUniqueId);
-    CompositorBridgeChild::Get()->SendPAPZConstructor(apz, mLayersId);
-  }
+  InitAPZState();
 
   nsCOMPtr<nsIDocument> doc(GetDocument());
   doc->NotifyLayerManagerRecreated();
 }
 
 void
 TabChild::CompositorUpdated(const TextureFactoryIdentifier& aNewIdentifier)
 {
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -717,16 +717,17 @@ private:
 
   void ActorDestroy(ActorDestroyReason why) override;
 
   bool InitTabChildGlobal();
 
   void InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
                           const uint64_t& aLayersId,
                           PRenderFrameChild* aRenderFrame);
+  void InitAPZState();
 
   void DestroyWindow();
 
   void ApplyShowInfo(const ShowInfo& aInfo);
 
   bool HasValidInnerSize();
 
   void SetTabId(const TabId& aTabId);
@@ -781,19 +782,16 @@ private:
   CSSSize mUnscaledInnerSize;
   bool mDidSetRealShowInfo;
   bool mDidLoadURLInit;
   bool mIsFreshProcess;
 
   AutoTArray<bool, NUMBER_OF_AUDIO_CHANNELS> mAudioChannelsActive;
 
   RefPtr<layers::IAPZCTreeManager> mApzcTreeManager;
-  // APZChild clears this pointer from its destructor, so it shouldn't be a
-  // dangling pointer.
-  layers::APZChild* mAPZChild;
 
   // The most recently seen layer observer epoch in RecvSetDocShellIsActive.
   uint64_t mLayerObserverEpoch;
 
 #if defined(XP_WIN) && defined(ACCESSIBILITY)
   // The handle associated with the native window that contains this tab
   uintptr_t mNativeWindowHandle;
 #endif // defined(XP_WIN)
--- a/gfx/layers/apz/util/ContentProcessController.cpp
+++ b/gfx/layers/apz/util/ContentProcessController.cpp
@@ -10,122 +10,22 @@
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/APZChild.h"
 
 #include "InputData.h"                  // for InputData
 
 namespace mozilla {
 namespace layers {
 
-/**
- * There are cases where we try to create the APZChild before the corresponding
- * TabChild has been created, we use an observer for the "tab-child-created"
- * topic to set the TabChild in the APZChild when it has been created.
- */
-class TabChildCreatedObserver : public nsIObserver
+ContentProcessController::ContentProcessController(const RefPtr<dom::TabChild>& aBrowser)
+    : mBrowser(aBrowser)
 {
-public:
-  TabChildCreatedObserver(ContentProcessController* aController, const dom::TabId& aTabId)
-    : mController(aController),
-      mTabId(aTabId)
-  {}
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIOBSERVER
-
-private:
-  virtual ~TabChildCreatedObserver()
-  {}
-
-  // TabChildCreatedObserver is owned by mController, and mController outlives its
-  // TabChildCreatedObserver, so the raw pointer is fine.
-  ContentProcessController* mController;
-  dom::TabId mTabId;
-};
-
-NS_IMPL_ISUPPORTS(TabChildCreatedObserver, nsIObserver)
-
-NS_IMETHODIMP
-TabChildCreatedObserver::Observe(nsISupports* aSubject,
-                                 const char* aTopic,
-                                 const char16_t* aData)
-{
-  MOZ_ASSERT(strcmp(aTopic, "tab-child-created") == 0);
-
-  nsCOMPtr<nsITabChild> tabChild(do_QueryInterface(aSubject));
-  NS_ENSURE_TRUE(tabChild, NS_ERROR_FAILURE);
-
-  dom::TabChild* browser = static_cast<dom::TabChild*>(tabChild.get());
-
-  if (browser->GetTabId() == mTabId) {
-    mController->SetBrowser(browser);
-  }
-  return NS_OK;
+  MOZ_ASSERT(mBrowser);
 }
 
-APZChild*
-ContentProcessController::Create(const dom::TabId& aTabId)
-{
-  RefPtr<dom::TabChild> browser = dom::TabChild::FindTabChild(aTabId);
-
-  ContentProcessController* controller = new ContentProcessController();
-
-  nsAutoPtr<APZChild> apz(new APZChild(controller));
-
-  if (browser) {
-
-    controller->SetBrowser(browser);
-
-  } else {
-
-    RefPtr<TabChildCreatedObserver> observer =
-      new TabChildCreatedObserver(controller, aTabId);
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    if (!os ||
-        NS_FAILED(os->AddObserver(observer, "tab-child-created", false))) {
-      return nullptr;
-    }
-    controller->SetObserver(observer);
-
-  }
-
-  return apz.forget();
-}
-
-ContentProcessController::ContentProcessController()
-    : mBrowser(nullptr)
-{
-}
-ContentProcessController::~ContentProcessController()
-{
-  if (mObserver) {
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    os->RemoveObserver(mObserver, "tab-child-created");
-  }
-}
-
-void
-ContentProcessController::SetObserver(nsIObserver* aObserver)
-{
-  MOZ_ASSERT(!mBrowser);
-  mObserver = aObserver;
-}
-
-void
-ContentProcessController::SetBrowser(dom::TabChild* aBrowser)
-{
-  MOZ_ASSERT(!mBrowser);
-  mBrowser = aBrowser;
-
-  if (mObserver) {
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    os->RemoveObserver(mObserver, "tab-child-created");
-    mObserver = nullptr;
-  }
-}
 void
 ContentProcessController::RequestContentRepaint(const FrameMetrics& aFrameMetrics)
 {
   if (mBrowser) {
     mBrowser->UpdateFrame(aFrameMetrics);
   }
 }
 
--- a/gfx/layers/apz/util/ContentProcessController.h
+++ b/gfx/layers/apz/util/ContentProcessController.h
@@ -31,23 +31,17 @@ class APZChild;
  *
  * If ContentProcessController needs to implement a new method on GeckoContentController
  * PAPZ, APZChild, and RemoteContentController must be updated to handle it.
  */
 class ContentProcessController final
       : public GeckoContentController
 {
 public:
-  ~ContentProcessController();
-
-  static APZChild* Create(const dom::TabId& aTabId);
-
-  // ContentProcessController
-
-  void SetBrowser(dom::TabChild* aBrowser);
+  explicit ContentProcessController(const RefPtr<dom::TabChild>& aBrowser);
 
   // GeckoContentController
 
   void RequestContentRepaint(const FrameMetrics& frame) override;
 
   void HandleTap(TapType aType,
                  const LayoutDevicePoint& aPoint,
                  Modifiers aModifiers,
@@ -70,21 +64,16 @@ public:
 
   void PostDelayedTask(already_AddRefed<Runnable> aRunnable, int aDelayMs) override;
 
   bool IsRepaintThread() override;
 
   void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) override;
 
 private:
-  ContentProcessController();
-
-  void SetObserver(nsIObserver* aObserver);
-
   RefPtr<dom::TabChild> mBrowser;
-  RefPtr<nsIObserver> mObserver;
 };
 
 } // namespace layers
 
 } // namespace mozilla
 
 #endif // mozilla_layers_ContentProcessController_h
--- a/gfx/layers/ipc/CompositorBridgeChild.cpp
+++ b/gfx/layers/ipc/CompositorBridgeChild.cpp
@@ -1087,33 +1087,22 @@ CompositorBridgeChild::DeallocPComposito
 #ifdef MOZ_WIDGET_SUPPORTS_OOP_COMPOSITING
   delete aActor;
   return true;
 #else
   return false;
 #endif
 }
 
-RefPtr<IAPZCTreeManager>
-CompositorBridgeChild::GetAPZCTreeManager(uint64_t aLayerTreeId)
+bool
+CompositorBridgeChild::GetAPZEnabled(uint64_t aLayerTreeId)
 {
-  bool apzEnabled = false;
-  Unused << SendAsyncPanZoomEnabled(aLayerTreeId, &apzEnabled);
-
-  if (!apzEnabled) {
-    return nullptr;
-  }
-
-  PAPZCTreeManagerChild* child = SendPAPZCTreeManagerConstructor(aLayerTreeId);
-  if (!child) {
-    return nullptr;
-  }
-  APZCTreeManagerChild* parent = static_cast<APZCTreeManagerChild*>(child);
-
-  return RefPtr<IAPZCTreeManager>(parent);
+  bool result = false;
+  Unused << SendAsyncPanZoomEnabled(aLayerTreeId, &result);
+  return result;
 }
 
 PAPZCTreeManagerChild*
 CompositorBridgeChild::AllocPAPZCTreeManagerChild(const uint64_t& aLayersId)
 {
   APZCTreeManagerChild* child = new APZCTreeManagerChild();
   child->AddRef();
   return child;
--- a/gfx/layers/ipc/CompositorBridgeChild.h
+++ b/gfx/layers/ipc/CompositorBridgeChild.h
@@ -215,17 +215,17 @@ public:
   virtual bool AllocShmem(size_t aSize,
                           mozilla::ipc::SharedMemory::SharedMemoryType aShmType,
                           mozilla::ipc::Shmem* aShmem) override;
   virtual bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
 
   PCompositorWidgetChild* AllocPCompositorWidgetChild(const CompositorWidgetInitData& aInitData) override;
   bool DeallocPCompositorWidgetChild(PCompositorWidgetChild* aActor) override;
 
-  RefPtr<IAPZCTreeManager> GetAPZCTreeManager(uint64_t aLayerTreeId);
+  bool GetAPZEnabled(uint64_t aLayerTreeId);
 
   PAPZCTreeManagerChild* AllocPAPZCTreeManagerChild(const uint64_t& aLayersId) override;
   bool DeallocPAPZCTreeManagerChild(PAPZCTreeManagerChild* aActor) override;
 
   PAPZChild* AllocPAPZChild(const uint64_t& aLayersId) override;
   bool DeallocPAPZChild(PAPZChild* aActor) override;
 
   void ProcessingError(Result aCode, const char* aReason) override;