Bug 1289650 - Convert APZChild into a wrapper around GeckoContentController. draft
authorRyan Hunt <rhunt@mozilla.com>
Wed, 10 Aug 2016 16:51:45 -0700
changeset 399743 b69651db30a16f2d434cbedd496250b57e5403f5
parent 399742 0f575778efcdefae23382f754a3d114c99a8936e
child 528050 9c14c0f1fe19483ef4b1221088ca80db1684bbeb
push id25971
push userbmo:rhunt@mozilla.com
push dateThu, 11 Aug 2016 23:41:34 +0000
bugs1289650
milestone51.0a1
Bug 1289650 - Convert APZChild into a wrapper around GeckoContentController.
dom/ipc/TabChild.cpp
gfx/ipc/GPUProcessManager.cpp
gfx/ipc/GPUProcessManager.h
gfx/layers/apz/util/ContentProcessController.cpp
gfx/layers/apz/util/ContentProcessController.h
gfx/layers/ipc/APZChild.cpp
gfx/layers/ipc/APZChild.h
gfx/layers/ipc/PAPZ.ipdl
gfx/layers/ipc/RemoteContentController.cpp
gfx/layers/ipc/RemoteContentController.h
gfx/layers/moz.build
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -24,16 +24,17 @@
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/ipc/DocumentRendererChild.h"
 #include "mozilla/ipc/URIUtils.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 #include "mozilla/layers/APZChild.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/APZEventState.h"
+#include "mozilla/layers/ContentProcessController.h"
 #include "mozilla/layers/CompositorBridgeChild.h"
 #include "mozilla/layers/DoubleTapToZoom.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"
@@ -1662,17 +1663,17 @@ TabChild::RecvSizeModeChanged(const nsSi
     }
   }
   return true;
 }
 
 bool
 TabChild::RecvNotifyLayerAllocated(const dom::TabId& aTabId, const uint64_t& aLayersId)
 {
-  APZChild* apz = APZChild::Create(aTabId);
+  APZChild* apz = ContentProcessController::Create(aTabId);
   return CompositorBridgeChild::Get()->SendPAPZConstructor(apz, aLayersId);
 }
 
 bool
 TabChild::UpdateFrame(const FrameMetrics& aFrameMetrics)
 {
   return TabChildBase::UpdateFrameHandler(aFrameMetrics);
 }
--- a/gfx/ipc/GPUProcessManager.cpp
+++ b/gfx/ipc/GPUProcessManager.cpp
@@ -483,22 +483,16 @@ GPUProcessManager::CreateContentVRManage
       return false;
     }
   }
 
   *aOutEndpoint = Move(childPipe);
   return true;
 }
 
-already_AddRefed<IAPZCTreeManager>
-GPUProcessManager::GetAPZCTreeManagerForLayers(uint64_t aLayersId)
-{
-  return CompositorBridgeParent::GetAPZCTreeManager(aLayersId);
-}
-
 uint64_t
 GPUProcessManager::AllocateLayerTreeId()
 {
   MOZ_ASSERT(NS_IsMainThread());
   return ++mNextLayerTreeId;
 }
 
 void
--- a/gfx/ipc/GPUProcessManager.h
+++ b/gfx/ipc/GPUProcessManager.h
@@ -84,20 +84,16 @@ public:
 
   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<IAPZCTreeManager> 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.
   //
   // Must run on the content main thread.
   uint64_t AllocateLayerTreeId();
 
   // Release compositor-thread resources referred to by |aID|.
   //
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/util/ContentProcessController.cpp
@@ -0,0 +1,184 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ContentProcessController.h"
+
+#include "mozilla/dom/TabChild.h"
+#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
+{
+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;
+}
+
+APZChild*
+ContentProcessController::Create(const dom::TabId& aTabId)
+{
+  RefPtr<dom::TabChild> browser = dom::TabChild::FindTabChild(aTabId);
+
+  nsAutoPtr<APZChild> apz(new APZChild);
+
+  // APZChild will own controller
+  ContentProcessController* controller = new ContentProcessController();
+  apz->SetController(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");
+  } else if (mBrowser) {
+    mBrowser->SetAPZChild(nullptr);
+  }
+}
+
+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);
+  }
+}
+
+void
+ContentProcessController::HandleTap(
+                        TapType aType,
+                        const LayoutDevicePoint& aPoint,
+                        Modifiers aModifiers,
+                        const ScrollableLayerGuid& aGuid,
+                        uint64_t aInputBlockId)
+{
+  if (mBrowser) {
+    mBrowser->HandleTap(aType, aPoint - mBrowser->GetChromeDisplacement(), aModifiers, aGuid,
+        aInputBlockId, (aType == TapType::eSingleTap));
+  }
+}
+
+void
+ContentProcessController::NotifyAPZStateChange(
+                                  const ScrollableLayerGuid& aGuid,
+                                  APZStateChange aChange,
+                                  int aArg)
+{
+  if (mBrowser) {
+    mBrowser->NotifyAPZStateChange(aGuid.mScrollId, aChange, aArg);
+  }
+}
+
+void
+ContentProcessController::NotifyMozMouseScrollEvent(
+                                  const FrameMetrics::ViewID& aScrollId,
+                                  const nsString& aEvent)
+{
+  if (mBrowser) {
+    APZCCallbackHelper::NotifyMozMouseScrollEvent(aScrollId, aEvent);
+  }
+}
+
+void
+ContentProcessController::NotifyFlushComplete()
+{
+  if (mBrowser) {
+    nsCOMPtr<nsIPresShell> shell;
+    if (nsCOMPtr<nsIDocument> doc = mBrowser->GetDocument()) {
+      shell = doc->GetShell();
+    }
+    APZCCallbackHelper::NotifyFlushComplete(shell.get());
+  }
+}
+
+} // namespace layers
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/util/ContentProcessController.h
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=4 ts=8 et tw=80 : */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_layers_ContentProcessController_h
+#define mozilla_layers_ContentProcessController_h
+
+#include "mozilla/layers/GeckoContentController.h"
+
+class nsIObserver;
+
+namespace mozilla {
+
+namespace dom {
+class TabChild;
+} // namespace dom
+
+namespace layers {
+
+class APZChild;
+
+class ContentProcessController final
+      : public GeckoContentController
+{
+public:
+  ~ContentProcessController();
+
+  static APZChild* Create(const dom::TabId& aTabId);
+
+  // ContentProcessController
+
+  void SetBrowser(dom::TabChild* aBrowser);
+
+  // GeckoContentController
+
+  void RequestContentRepaint(const FrameMetrics& frame) override;
+
+  void HandleTap(TapType aType,
+                 const LayoutDevicePoint& aPoint,
+                 Modifiers aModifiers,
+                 const ScrollableLayerGuid& aGuid,
+                 uint64_t aInputBlockId) override;
+
+  void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
+                            APZStateChange aChange,
+                            int aArg) override;
+
+  void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
+                                 const nsString& aEvent) override;
+
+  void NotifyFlushComplete() override;
+
+  // This is not implemented because ContentProcessController is only used
+  // by APZChild for remoting into the content process, and won't ever be called.
+  void PostDelayedTask(already_AddRefed<Runnable> aRunnable, int aDelayMs) 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/APZChild.cpp
+++ b/gfx/layers/ipc/APZChild.cpp
@@ -1,181 +1,138 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set sw=4 ts=8 et tw=80 : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/layers/APZChild.h"
+#include "mozilla/layers/GeckoContentController.h"
 
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/layers/APZCCallbackHelper.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
-{
-public:
-  TabChildCreatedObserver(APZChild* aAPZChild, const dom::TabId& aTabId)
-    : mAPZChild(aAPZChild),
-      mTabId(aTabId)
-  {}
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIOBSERVER
-
-private:
-  virtual ~TabChildCreatedObserver()
-  {}
-
-  // TabChildCreatedObserver is owned by mAPZChild, and mAPZChild outlives its
-  // TabChildCreatedObserver, so the raw pointer is fine.
-  APZChild* mAPZChild;
-  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) {
-    mAPZChild->SetBrowser(browser);
-  }
-  return NS_OK;
-}
-
-APZChild*
-APZChild::Create(const dom::TabId& aTabId)
-{
-  RefPtr<dom::TabChild> browser = dom::TabChild::FindTabChild(aTabId);
-  nsAutoPtr<APZChild> apz(new APZChild);
-  if (browser) {
-    apz->SetBrowser(browser);
-  } else {
-    RefPtr<TabChildCreatedObserver> observer =
-      new TabChildCreatedObserver(apz, aTabId);
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    if (!os ||
-        NS_FAILED(os->AddObserver(observer, "tab-child-created", false))) {
-      return nullptr;
-    }
-    apz->SetObserver(observer);
-  }
-
-  return apz.forget();
-}
+// APZChild
 
 APZChild::APZChild()
-  : mDestroyed(false)
+  : mDestroyed(false), mController(nullptr)
 {
 }
 
 APZChild::~APZChild()
 {
-  if (mObserver) {
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    os->RemoveObserver(mObserver, "tab-child-created");
-  } else if (mBrowser) {
-    mBrowser->SetAPZChild(nullptr);
+  if (mController) {
+    mController->Destroy();
+    mController = nullptr;
   }
 }
 
+void
+APZChild::SetController(RefPtr<GeckoContentController> aController)
+{
+  if (mController) {
+    mController->Destroy();
+    mController = nullptr;
+  }
+
+  mController = aController;
+}
+
 bool
 APZChild::RecvRequestContentRepaint(const FrameMetrics& aFrameMetrics)
 {
-  return mBrowser->UpdateFrame(aFrameMetrics);
+  if (mController) {
+    mController->RequestContentRepaint(aFrameMetrics);
+  }
+  return true;
 }
 
 bool
 APZChild::RecvHandleTap(const TapType& aType,
                         const LayoutDevicePoint& aPoint,
                         const Modifiers& aModifiers,
                         const ScrollableLayerGuid& aGuid,
                         const uint64_t& aInputBlockId,
                         const bool& aCallTakeFocusForClickFromTap)
 {
-  mBrowser->HandleTap(aType, aPoint - mBrowser->GetChromeDisplacement(), aModifiers, aGuid,
-      aInputBlockId, aCallTakeFocusForClickFromTap);
+  if (mController) {
+    mController->HandleTap(aType, aPoint, aModifiers, aGuid,
+        aInputBlockId);
+  }
+  return true;
+}
+
+bool
+APZChild::RecvUpdateOverscrollVelocity(const float& aX, const float& aY)
+{
+  if (mController) {
+    mController->UpdateOverscrollVelocity(aX, aY);
+  }
+  return true;
+}
+
+bool
+APZChild::RecvUpdateOverscrollOffset(const float& aX, const float& aY)
+{
+  if (mController) {
+    mController->UpdateOverscrollOffset(aX, aY);
+  }
+  return true;
+}
+
+bool
+APZChild::RecvSetScrollingRootContent(const bool& isRootContent)
+{
+  if (mController) {
+    mController->SetScrollingRootContent(isRootContent);
+  }
   return true;
 }
 
 bool
 APZChild::RecvNotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
                                         const nsString& aEvent)
 {
-  if (mBrowser) {
-    APZCCallbackHelper::NotifyMozMouseScrollEvent(aScrollId, aEvent);
+  if (mController) {
+    mController->NotifyMozMouseScrollEvent(aScrollId, aEvent);
   }
   return true;
 }
 
 bool
 APZChild::RecvNotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                    const APZStateChange& aChange,
                                    const int& aArg)
 {
-  return mBrowser->NotifyAPZStateChange(aGuid.mScrollId, aChange, aArg);
+  if (mController) {
+    mController->NotifyAPZStateChange(aGuid, aChange, aArg);
+  }
+  return true;
 }
 
 bool
 APZChild::RecvNotifyFlushComplete()
 {
-  nsCOMPtr<nsIPresShell> shell;
-  if (nsCOMPtr<nsIDocument> doc = mBrowser->GetDocument()) {
-    shell = doc->GetShell();
+  if (mController) {
+    mController->NotifyFlushComplete();
   }
-  APZCCallbackHelper::NotifyFlushComplete(shell.get());
   return true;
 }
 
 bool
 APZChild::RecvDestroy()
 {
   mDestroyed = true;
-  if (mBrowser) {
-    mBrowser->SetAPZChild(nullptr);
-    mBrowser = nullptr;
+  if (mController) {
+    mController->Destroy();
+    mController = nullptr;
   }
   return true;
 }
 
-void
-APZChild::SetObserver(nsIObserver* aObserver)
-{
-  MOZ_ASSERT(!mBrowser);
-  mObserver = aObserver;
-}
-
-void
-APZChild::SetBrowser(dom::TabChild* aBrowser)
-{
-  MOZ_ASSERT(!mBrowser);
-  if (mObserver) {
-    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
-    os->RemoveObserver(mObserver, "tab-child-created");
-    mObserver = nullptr;
-  }
-  // We might get the tab-child-created notification after we receive a
-  // Destroy message from the parent. In that case we don't want to install
-  // ourselves with the browser.
-  if (!mDestroyed) {
-    mBrowser = aBrowser;
-    mBrowser->SetAPZChild(this);
-  }
-}
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/ipc/APZChild.h
+++ b/gfx/layers/ipc/APZChild.h
@@ -4,62 +4,60 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_APZChild_h
 #define mozilla_layers_APZChild_h
 
 #include "mozilla/layers/PAPZChild.h"
 
-class nsIObserver;
-
 namespace mozilla {
 
-namespace dom {
-class TabChild;
-} // namespace dom
-
 namespace layers {
 
-class APZChild final : public PAPZChild
+class GeckoContentController;
+
+class APZChild final
+      : public PAPZChild
 {
 public:
-  static APZChild* Create(const dom::TabId& aTabId);
-
+  APZChild();
   ~APZChild();
 
-  void SetBrowser(dom::TabChild* aBrowser);
+  void SetController(RefPtr<GeckoContentController> aController);
 
   bool RecvRequestContentRepaint(const FrameMetrics& frame) override;
 
   bool RecvHandleTap(const TapType& aType,
                      const LayoutDevicePoint& aPoint,
                      const Modifiers& aModifiers,
                      const ScrollableLayerGuid& aGuid,
                      const uint64_t& aInputBlockId,
                      const bool& aCallTakeFocusForClickFromTap) override;
 
+  bool RecvUpdateOverscrollVelocity(const float& aX, const float& aY) override;
+
+  bool RecvUpdateOverscrollOffset(const float& aX, const float& aY) override;
+
+  bool RecvSetScrollingRootContent(const bool& isRootContent) override;
+
   bool RecvNotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
                                      const nsString& aEvent) override;
 
   bool RecvNotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                 const APZStateChange& aChange,
                                 const int& aArg) override;
 
   bool RecvNotifyFlushComplete() override;
 
   bool RecvDestroy() override;
 
 private:
-  APZChild();
-
-  void SetObserver(nsIObserver* aObserver);
+  bool mDestroyed;
 
-  RefPtr<dom::TabChild> mBrowser;
-  RefPtr<nsIObserver> mObserver;
-  bool mDestroyed;
+  RefPtr<GeckoContentController> mController;
 };
 
 } // namespace layers
 
 } // namespace mozilla
 
 #endif // mozilla_layers_APZChild_h
--- a/gfx/layers/ipc/PAPZ.ipdl
+++ b/gfx/layers/ipc/PAPZ.ipdl
@@ -52,16 +52,22 @@ child:
 
   // The aCallTakeFocusForClickFromTap argument is used for eSingleTap types,
   // to request that the child take focus before dispatching the mouse events
   // for the tap (otherwise the resulting focus behaviour is incorrect).
   async HandleTap(TapType aType, LayoutDevicePoint point, Modifiers aModifiers,
                   ScrollableLayerGuid aGuid, uint64_t aInputBlockId,
                   bool aCallTakeFocusForClickFromTap);
 
+  async UpdateOverscrollVelocity(float aX, float aY);
+
+  async UpdateOverscrollOffset(float aX, float aY);
+
+  async SetScrollingRootContent(bool isRootContent);
+
   async NotifyMozMouseScrollEvent(ViewID aScrollId, nsString aEvent);
 
   async NotifyAPZStateChange(ScrollableLayerGuid aGuid, APZStateChange aChange, int aArg);
 
   async NotifyFlushComplete();
 
   async Destroy();
 };
--- a/gfx/layers/ipc/RemoteContentController.cpp
+++ b/gfx/layers/ipc/RemoteContentController.cpp
@@ -114,16 +114,54 @@ RemoteContentController::NotifyAPZStateC
                                              &RemoteContentController::NotifyAPZStateChange,
                                              aGuid, aChange, aArg));
     return;
   }
   Unused << SendNotifyAPZStateChange(aGuid, aChange, aArg);
 }
 
 void
+RemoteContentController::UpdateOverscrollVelocity(const float aX, const float aY)
+{
+  if (MessageLoop::current() != mUILoop) {
+    mUILoop->PostTask(NewRunnableMethod<float,
+                                        float>(this,
+                                             &RemoteContentController::UpdateOverscrollVelocity,
+                                             aX, aY));
+    return;
+  }
+  Unused << SendUpdateOverscrollVelocity(aX, aY);
+}
+
+void
+RemoteContentController::UpdateOverscrollOffset(const float aX, const float aY)
+{
+  if (MessageLoop::current() != mUILoop) {
+    mUILoop->PostTask(NewRunnableMethod<float,
+                                        float>(this,
+                                             &RemoteContentController::UpdateOverscrollOffset,
+                                             aX, aY));
+    return;
+  }
+  Unused << SendUpdateOverscrollOffset(aX, aY);
+}
+
+void
+RemoteContentController::SetScrollingRootContent(const bool isRootContent)
+{
+  if (MessageLoop::current() != mUILoop) {
+    mUILoop->PostTask(NewRunnableMethod<bool>(this,
+                                             &RemoteContentController::SetScrollingRootContent,
+                                             isRootContent));
+    return;
+  }
+  Unused << SendSetScrollingRootContent(isRootContent);
+}
+
+void
 RemoteContentController::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
                                                    const nsString& aEvent)
 {
   if (MessageLoop::current() != mUILoop) {
     mUILoop->PostTask(NewRunnableMethod<FrameMetrics::ViewID,
                                         nsString>(this,
                                                   &RemoteContentController::NotifyMozMouseScrollEvent,
                                                   aScrollId, aEvent));
--- a/gfx/layers/ipc/RemoteContentController.h
+++ b/gfx/layers/ipc/RemoteContentController.h
@@ -51,16 +51,22 @@ public:
   virtual void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs) override;
 
   virtual bool GetTouchSensitiveRegion(CSSRect* aOutRegion) override;
 
   virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
                                     APZStateChange aChange,
                                     int aArg) override;
 
+  virtual void UpdateOverscrollVelocity(const float aX, const float aY) override;
+
+  virtual void UpdateOverscrollOffset(const float aX, const float aY) override;
+
+  virtual void SetScrollingRootContent(const bool isRootContent) override;
+
   virtual void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId,
                                          const nsString& aEvent) override;
 
   // Needs to be called on the main thread.
   virtual void NotifyFlushComplete() override;
 
   virtual bool RecvUpdateHitRegion(const nsRegion& aRegion) override;
 
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -107,16 +107,17 @@ EXPORTS.mozilla.layers += [
     'apz/src/AsyncPanZoomAnimation.h',
     'apz/src/TouchCounter.h',
     'apz/testutil/APZTestData.h',
     'apz/util/ActiveElementManager.h',
     'apz/util/APZCCallbackHelper.h',
     'apz/util/APZEventState.h',
     'apz/util/APZThreadUtils.h',
     'apz/util/ChromeProcessController.h',
+    'apz/util/ContentProcessController.h',
     'apz/util/DoubleTapToZoom.h',
     'apz/util/InputAPZContext.h',
     'apz/util/ScrollInputMethods.h',
     'apz/util/ScrollLinkedEffectDetector.h',
     'apz/util/TouchActionHelper.h',
     'AsyncCanvasRenderer.h',
     'AtomicRefCountedWithFinalize.h',
     'AxisPhysicsModel.h',
@@ -281,16 +282,17 @@ UNIFIED_SOURCES += [
     'apz/src/WheelScrollAnimation.cpp',
     'apz/testutil/APZTestData.cpp',
     'apz/util/ActiveElementManager.cpp',
     'apz/util/APZCCallbackHelper.cpp',
     'apz/util/APZEventState.cpp',
     'apz/util/APZThreadUtils.cpp',
     'apz/util/CheckerboardReportService.cpp',
     'apz/util/ChromeProcessController.cpp',
+    'apz/util/ContentProcessController.cpp',
     'apz/util/DoubleTapToZoom.cpp',
     'apz/util/InputAPZContext.cpp',
     'apz/util/ScrollLinkedEffectDetector.cpp',
     'apz/util/TouchActionHelper.cpp',
     'AsyncCanvasRenderer.cpp',
     'AxisPhysicsModel.cpp',
     'AxisPhysicsMSDModel.cpp',
     'basic/BasicCanvasLayer.cpp',