Bug 1441324 - Extract an APZInputBridge interface from IAPZCTreeManager. r=rhunt
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 16 Mar 2018 16:28:18 -0400
changeset 408580 c85a2550e02c680fad269f32098998d6df701b14
parent 408579 3214b1a3f2355410e940991a4435aef2cbc38025
child 408581 908c0e96e38c1f9cd211d4203f61528fb4f3431d
push id33648
push userbtara@mozilla.com
push dateSat, 17 Mar 2018 10:06:03 +0000
treeherdermozilla-central@29dcc9cb77c3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrhunt
bugs1441324
milestone61.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
Bug 1441324 - Extract an APZInputBridge interface from IAPZCTreeManager. r=rhunt This separates the methods that are used to deliver input events synchronously over IPDL to the compositor; this interface will be remoted over a new APZInputBridge IPDL protocol in future patches. MozReview-Commit-ID: 1f3V9SUKlfW
gfx/layers/apz/public/APZInputBridge.h
gfx/layers/apz/public/IAPZCTreeManager.cpp
gfx/layers/apz/public/IAPZCTreeManager.h
gfx/layers/apz/src/APZCTreeManager.cpp
gfx/layers/apz/src/APZCTreeManager.h
gfx/layers/apz/src/APZInputBridge.cpp
gfx/layers/ipc/APZCTreeManagerChild.cpp
gfx/layers/ipc/APZCTreeManagerChild.h
gfx/layers/moz.build
widget/android/nsWindow.cpp
widget/cocoa/nsChildView.mm
widget/nsBaseWidget.cpp
new file mode 100644
--- /dev/null
+++ b/gfx/layers/apz/public/APZInputBridge.h
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 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_APZInputBridge_h
+#define mozilla_layers_APZInputBridge_h
+
+#include "mozilla/EventForwards.h"      // for WidgetInputEvent, nsEventStatus
+#include "Units.h"                      // for LayoutDeviceIntPoint
+
+namespace mozilla {
+
+class InputData;
+
+namespace layers {
+
+struct ScrollableLayerGuid;
+
+/**
+ * This class lives in the main process, and is accessed via the controller
+ * thread (which is the process main thread for desktop, and the Java UI
+ * thread for Android). This class exposes a synchronous API to deliver
+ * incoming input events to APZ and modify them in-place to unapply the APZ
+ * async transform. If there is a GPU process, then this class does sync IPC
+ * calls over to the GPU process in order to accomplish this. Otherwise,
+ * APZCTreeManager overrides and implements these methods directly.
+ */
+class APZInputBridge {
+public:
+  /**
+   * General handler for incoming input events. Manipulates the frame metrics
+   * based on what type of input it is. For example, a PinchGestureEvent will
+   * cause scaling. This should only be called externally to this class, and
+   * must be called on the controller thread.
+   *
+   * This function transforms |aEvent| to have its coordinates in DOM space.
+   * This is so that the event can be passed through the DOM and content can
+   * handle them. The event may need to be converted to a WidgetInputEvent
+   * by the caller if it wants to do this.
+   *
+   * The following values may be returned by this function:
+   * nsEventStatus_eConsumeNoDefault is returned to indicate the
+   *   APZ is consuming this event and the caller should discard the event with
+   *   extreme prejudice. The exact scenarios under which this is returned is
+   *   implementation-dependent and may vary.
+   * nsEventStatus_eIgnore is returned to indicate that the APZ code didn't
+   *   use this event. This might be because it was directed at a point on
+   *   the screen where there was no APZ, or because the thing the user was
+   *   trying to do was not allowed. (For example, attempting to pan a
+   *   non-pannable document).
+   * nsEventStatus_eConsumeDoDefault is returned to indicate that the APZ
+   *   code may have used this event to do some user-visible thing. Note that
+   *   in some cases CONSUMED is returned even if the event was NOT used. This
+   *   is because we cannot always know at the time of event delivery whether
+   *   the event will be used or not. So we err on the side of sending
+   *   CONSUMED when we are uncertain.
+   *
+   * @param aEvent input event object; is modified in-place
+   * @param aOutTargetGuid returns the guid of the apzc this event was
+   * delivered to. May be null.
+   * @param aOutInputBlockId returns the id of the input block that this event
+   * was added to, if that was the case. May be null.
+   */
+  virtual nsEventStatus ReceiveInputEvent(
+      InputData& aEvent,
+      ScrollableLayerGuid* aOutTargetGuid,
+      uint64_t* aOutInputBlockId) = 0;
+
+  /**
+   * WidgetInputEvent handler. Transforms |aEvent| (which is assumed to be an
+   * already-existing instance of an WidgetInputEvent which may be an
+   * WidgetTouchEvent) to have its coordinates in DOM space. This is so that the
+   * event can be passed through the DOM and content can handle them.
+   *
+   * NOTE: Be careful of invoking the WidgetInputEvent variant. This can only be
+   * called on the main thread. See widget/InputData.h for more information on
+   * why we have InputData and WidgetInputEvent separated. If this function is
+   * used, the controller thread must be the main thread, or undefined behaviour
+   * may occur.
+   * NOTE: On unix, mouse events are treated as touch and are forwarded
+   * to the appropriate apz as such.
+   *
+   * See documentation for other ReceiveInputEvent above.
+   */
+  nsEventStatus ReceiveInputEvent(
+      WidgetInputEvent& aEvent,
+      ScrollableLayerGuid* aOutTargetGuid,
+      uint64_t* aOutInputBlockId);
+
+  // Returns whether or not a wheel event action will be (or was) performed by
+  // APZ. If this returns true, the event must not perform a synchronous
+  // scroll.
+  //
+  // Even if this returns false, all wheel events in APZ-aware widgets must
+  // be sent through APZ so they are transformed correctly for TabParent.
+  static bool WillHandleWheelEvent(WidgetWheelEvent* aEvent);
+
+protected:
+
+  // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
+
+  virtual void ProcessUnhandledEvent(
+      LayoutDeviceIntPoint* aRefPoint,
+      ScrollableLayerGuid* aOutTargetGuid,
+      uint64_t* aOutFocusSequenceNumber) = 0;
+
+  virtual void UpdateWheelTransaction(
+      LayoutDeviceIntPoint aRefPoint,
+      EventMessage aEventMessage) = 0;
+
+  virtual ~APZInputBridge() { }
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_APZInputBridge_h
--- a/gfx/layers/apz/public/IAPZCTreeManager.h
+++ b/gfx/layers/apz/public/IAPZCTreeManager.h
@@ -5,27 +5,25 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_IAPZCTreeManager_h
 #define mozilla_layers_IAPZCTreeManager_h
 
 #include <stdint.h>                     // for uint64_t, uint32_t
 
 #include "FrameMetrics.h"               // for FrameMetrics, etc
-#include "mozilla/EventForwards.h"      // for WidgetInputEvent, nsEventStatus
-#include "mozilla/layers/LayersTypes.h"    // for TouchBehaviorFlags
+#include "mozilla/layers/LayersTypes.h" // for TouchBehaviorFlags
 #include "nsTArrayForwardDeclare.h"     // for nsTArray, nsTArray_Impl, etc
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
-#include "Units.h"                      // for CSSPoint, CSSRect, etc
+#include "Units.h"                      // for CSSRect, etc
 
 namespace mozilla {
-class InputData;
-
 namespace layers {
 
+class APZInputBridge;
 class KeyboardMap;
 
 enum AllowedTouchBehavior {
   NONE =               0,
   VERTICAL_PAN =       1 << 0,
   HORIZONTAL_PAN =     1 << 1,
   PINCH_ZOOM =         1 << 2,
   DOUBLE_TAP_ZOOM =    1 << 3,
@@ -40,77 +38,16 @@ enum ZoomToRectBehavior : uint32_t {
 };
 
 class AsyncDragMetrics;
 
 class IAPZCTreeManager {
   NS_INLINE_DECL_THREADSAFE_VIRTUAL_REFCOUNTING(IAPZCTreeManager)
 
 public:
-
-  /**
-   * General handler for incoming input events. Manipulates the frame metrics
-   * based on what type of input it is. For example, a PinchGestureEvent will
-   * cause scaling. This should only be called externally to this class, and
-   * must be called on the controller thread.
-   *
-   * This function transforms |aEvent| to have its coordinates in DOM space.
-   * This is so that the event can be passed through the DOM and content can
-   * handle them. The event may need to be converted to a WidgetInputEvent
-   * by the caller if it wants to do this.
-   *
-   * The following values may be returned by this function:
-   * nsEventStatus_eConsumeNoDefault is returned to indicate the
-   *   APZ is consuming this event and the caller should discard the event with
-   *   extreme prejudice. The exact scenarios under which this is returned is
-   *   implementation-dependent and may vary.
-   * nsEventStatus_eIgnore is returned to indicate that the APZ code didn't
-   *   use this event. This might be because it was directed at a point on
-   *   the screen where there was no APZ, or because the thing the user was
-   *   trying to do was not allowed. (For example, attempting to pan a
-   *   non-pannable document).
-   * nsEventStatus_eConsumeDoDefault is returned to indicate that the APZ
-   *   code may have used this event to do some user-visible thing. Note that
-   *   in some cases CONSUMED is returned even if the event was NOT used. This
-   *   is because we cannot always know at the time of event delivery whether
-   *   the event will be used or not. So we err on the side of sending
-   *   CONSUMED when we are uncertain.
-   *
-   * @param aEvent input event object; is modified in-place
-   * @param aOutTargetGuid returns the guid of the apzc this event was
-   * delivered to. May be null.
-   * @param aOutInputBlockId returns the id of the input block that this event
-   * was added to, if that was the case. May be null.
-   */
-  virtual nsEventStatus ReceiveInputEvent(
-      InputData& aEvent,
-      ScrollableLayerGuid* aOutTargetGuid,
-      uint64_t* aOutInputBlockId) = 0;
-
-  /**
-   * WidgetInputEvent handler. Transforms |aEvent| (which is assumed to be an
-   * already-existing instance of an WidgetInputEvent which may be an
-   * WidgetTouchEvent) to have its coordinates in DOM space. This is so that the
-   * event can be passed through the DOM and content can handle them.
-   *
-   * NOTE: Be careful of invoking the WidgetInputEvent variant. This can only be
-   * called on the main thread. See widget/InputData.h for more information on
-   * why we have InputData and WidgetInputEvent separated. If this function is
-   * used, the controller thread must be the main thread, or undefined behaviour
-   * may occur.
-   * NOTE: On unix, mouse events are treated as touch and are forwarded
-   * to the appropriate apz as such.
-   *
-   * See documentation for other ReceiveInputEvent above.
-   */
-  nsEventStatus ReceiveInputEvent(
-      WidgetInputEvent& aEvent,
-      ScrollableLayerGuid* aOutTargetGuid,
-      uint64_t* aOutInputBlockId);
-
   /**
    * Set the keyboard shortcuts to use for translating keyboard events.
    */
   virtual void SetKeyboardMap(const KeyboardMap& aKeyboardMap) = 0;
 
   /**
    * Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
    * in. The actual animation is done on the sampler thread after being set
@@ -185,38 +122,27 @@ public:
   /**
    * Function used to disable LongTap gestures.
    *
    * On slow running tests, drags and touch events can be misinterpreted
    * as a long tap. This allows tests to disable long tap gesture detection.
    */
   virtual void SetLongTapEnabled(bool aTapGestureEnabled) = 0;
 
-
-  // Returns whether or not a wheel event action will be (or was) performed by
-  // APZ. If this returns true, the event must not perform a synchronous
-  // scroll.
-  //
-  // Even if this returns false, all wheel events in APZ-aware widgets must
-  // be sent through APZ so they are transformed correctly for TabParent.
-  static bool WillHandleWheelEvent(WidgetWheelEvent* aEvent);
+  /**
+   * Returns an APZInputBridge interface that can be used to send input
+   * events to APZ in a synchronous manner. This will always be non-null, and
+   * the returned object's lifetime will match the lifetime of this
+   * IAPZCTreeManager implementation.
+   * It is only valid to call this function in the UI process.
+   */
+  virtual APZInputBridge* InputBridge() = 0;
 
 protected:
 
-  // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
-
-  virtual void ProcessUnhandledEvent(
-      LayoutDeviceIntPoint* aRefPoint,
-      ScrollableLayerGuid* aOutTargetGuid,
-      uint64_t* aOutFocusSequenceNumber) = 0;
-
-  virtual void UpdateWheelTransaction(
-      LayoutDeviceIntPoint aRefPoint,
-      EventMessage aEventMessage) = 0;
-
   // Discourage destruction outside of decref
 
   virtual ~IAPZCTreeManager() { }
 };
 
 } // namespace layers
 } // namespace mozilla
 
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -1072,17 +1072,17 @@ template<typename PanGestureOrScrollWhee
 static bool
 WillHandleInput(const PanGestureOrScrollWheelInput& aPanInput)
 {
   if (!XRE_IsParentProcess() || !NS_IsMainThread()) {
     return true;
   }
 
   WidgetWheelEvent wheelEvent = aPanInput.ToWidgetWheelEvent(nullptr);
-  return IAPZCTreeManager::WillHandleWheelEvent(&wheelEvent);
+  return APZInputBridge::WillHandleWheelEvent(&wheelEvent);
 }
 
 void
 APZCTreeManager::FlushApzRepaints(uint64_t aLayersId)
 {
   // Previously, paints were throttled and therefore this method was used to
   // ensure any pending paints were flushed. Now, paints are flushed
   // immediately, so it is safe to simply send a notification now.
--- a/gfx/layers/apz/src/APZCTreeManager.h
+++ b/gfx/layers/apz/src/APZCTreeManager.h
@@ -10,16 +10,17 @@
 #include <unordered_map>                          // for std::unordered_map
 
 #include "FocusState.h"                 // for FocusState
 #include "gfxPoint.h"                   // for gfxPoint
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT_HELPER2
 #include "mozilla/gfx/CompositorHitTestInfo.h"
 #include "mozilla/gfx/Logging.h"        // for gfx::TreeLog
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
+#include "mozilla/layers/APZInputBridge.h" // for APZInputBridge
 #include "mozilla/layers/APZTestData.h" // for APZTestData
 #include "mozilla/layers/IAPZCTreeManager.h" // for IAPZCTreeManager
 #include "mozilla/layers/KeyboardMap.h" // for KeyboardMap
 #include "mozilla/RecursiveMutex.h"     // for RecursiveMutex
 #include "mozilla/RefPtr.h"             // for RefPtr
 #include "mozilla/TimeStamp.h"          // for mozilla::TimeStamp
 #include "mozilla/UniquePtr.h"          // for UniquePtr
 #include "nsCOMPtr.h"                   // for already_AddRefed
@@ -94,17 +95,18 @@ struct ScrollThumbData;
  * user input events that drive panning and zooming, changes to the scroll viewport
  * area, and changes to pan/zoom constraints.
  *
  * Note that the ClearTree function MUST be called when this class is no longer needed;
  * see the method documentation for details.
  *
  * Behaviour of APZ is controlled by a number of preferences shown \ref APZCPrefs "here".
  */
-class APZCTreeManager : public IAPZCTreeManager {
+class APZCTreeManager : public IAPZCTreeManager
+                      , public APZInputBridge {
 
   typedef mozilla::layers::AllowedTouchBehavior AllowedTouchBehavior;
   typedef mozilla::layers::AsyncDragMetrics AsyncDragMetrics;
 
   // Helper struct to hold some state while we build the hit-testing tree. The
   // sole purpose of this struct is to shorten the argument list to
   // UpdateHitTestingTree. All the state that we don't need to
   // push on the stack during recursion and pop on unwind is stored here.
@@ -468,16 +470,18 @@ public:
   /**
    * Function used to disable LongTap gestures.
    *
    * On slow running tests, drags and touch events can be misinterpreted
    * as a long tap. This allows tests to disable long tap gesture detection.
    */
   void SetLongTapEnabled(bool aTapGestureEnabled) override;
 
+  APZInputBridge* InputBridge() override { return this; }
+
   // Methods to help process WidgetInputEvents (or manage conversion to/from InputData)
 
   void ProcessUnhandledEvent(
       LayoutDeviceIntPoint* aRefPoint,
       ScrollableLayerGuid*  aOutTargetGuid,
       uint64_t*             aOutFocusSequenceNumber) override;
 
   void UpdateWheelTransaction(
rename from gfx/layers/apz/public/IAPZCTreeManager.cpp
rename to gfx/layers/apz/src/APZInputBridge.cpp
--- a/gfx/layers/apz/public/IAPZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZInputBridge.cpp
@@ -1,19 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 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/IAPZCTreeManager.h"
+#include "mozilla/layers/APZInputBridge.h"
 
 #include "gfxPrefs.h"                       // for gfxPrefs
-#include "InputData.h"                      // for InputData, etc
-#include "mozilla/EventStateManager.h"      // for WheelPrefs
+#include "InputData.h"                      // for MouseInput, etc
+#include "mozilla/EventStateManager.h"      // for EventStateManager
 #include "mozilla/layers/APZThreadUtils.h"  // for AssertOnControllerThread, etc
 #include "mozilla/MouseEvents.h"            // for WidgetMouseEvent
 #include "mozilla/TextEvents.h"             // for WidgetKeyboardEvent
 #include "mozilla/TouchEvents.h"            // for WidgetTouchEvent
 #include "mozilla/WheelHandlingHelper.h"    // for AutoWheelDeltaAdjuster
 
 namespace mozilla {
 namespace layers {
@@ -24,26 +24,26 @@ WillHandleMouseEvent(const WidgetMouseEv
   return aEvent.mMessage == eMouseMove ||
          aEvent.mMessage == eMouseDown ||
          aEvent.mMessage == eMouseUp ||
          aEvent.mMessage == eDragEnd ||
          (gfxPrefs::TestEventsAsyncEnabled() && aEvent.mMessage == eMouseHitTest);
 }
 
 /* static */ bool
-IAPZCTreeManager::WillHandleWheelEvent(WidgetWheelEvent* aEvent)
+APZInputBridge::WillHandleWheelEvent(WidgetWheelEvent* aEvent)
 {
   return EventStateManager::WheelEventIsScrollAction(aEvent) &&
          (aEvent->mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_LINE ||
           aEvent->mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL ||
           aEvent->mDeltaMode == nsIDOMWheelEvent::DOM_DELTA_PAGE);
 }
 
 nsEventStatus
-IAPZCTreeManager::ReceiveInputEvent(
+APZInputBridge::ReceiveInputEvent(
     WidgetInputEvent& aEvent,
     ScrollableLayerGuid* aOutTargetGuid,
     uint64_t* aOutInputBlockId)
 {
   APZThreadUtils::AssertOnControllerThread();
 
   // Initialize aOutInputBlockId to a sane value, and then later we overwrite
   // it if the input event goes into a block.
--- a/gfx/layers/ipc/APZCTreeManagerChild.cpp
+++ b/gfx/layers/ipc/APZCTreeManagerChild.cpp
@@ -235,16 +235,22 @@ void APZCTreeManagerChild::ProcessUnhand
     uint64_t*             aOutFocusSequenceNumber)
 {
   SendProcessUnhandledEvent(*aRefPoint,
                             aRefPoint,
                             aOutTargetGuid,
                             aOutFocusSequenceNumber);
 }
 
+APZInputBridge*
+APZCTreeManagerChild::InputBridge()
+{
+  return this;
+}
+
 mozilla::ipc::IPCResult
 APZCTreeManagerChild::RecvHandleTap(const TapType& aType,
                                     const LayoutDevicePoint& aPoint,
                                     const Modifiers& aModifiers,
                                     const ScrollableLayerGuid& aGuid,
                                     const uint64_t& aInputBlockId)
 {
   MOZ_ASSERT(XRE_IsParentProcess());
--- a/gfx/layers/ipc/APZCTreeManagerChild.h
+++ b/gfx/layers/ipc/APZCTreeManagerChild.h
@@ -2,26 +2,28 @@
 /* vim: set ts=8 sts=2 et sw=2 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_APZCTreeManagerChild_h
 #define mozilla_layers_APZCTreeManagerChild_h
 
+#include "mozilla/layers/APZInputBridge.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/PAPZCTreeManagerChild.h"
 
 namespace mozilla {
 namespace layers {
 
 class RemoteCompositorSession;
 
 class APZCTreeManagerChild
   : public IAPZCTreeManager
+  , public APZInputBridge
   , public PAPZCTreeManagerChild
 {
 public:
   APZCTreeManagerChild();
 
   void SetCompositorSession(RemoteCompositorSession* aSession);
 
   nsEventStatus
@@ -84,16 +86,19 @@ public:
           ScrollableLayerGuid*  aOutTargetGuid,
           uint64_t*             aOutFocusSequenceNumber) override;
 
   void
   UpdateWheelTransaction(
           LayoutDeviceIntPoint aRefPoint,
           EventMessage aEventMessage) override;
 
+  APZInputBridge*
+  InputBridge() override;
+
 protected:
   mozilla::ipc::IPCResult RecvHandleTap(const TapType& aType,
                                         const LayoutDevicePoint& aPoint,
                                         const Modifiers& aModifiers,
                                         const ScrollableLayerGuid& aGuid,
                                         const uint64_t& aInputBlockId) override;
 
   mozilla::ipc::IPCResult RecvNotifyPinchGesture(const PinchGestureType& aType,
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -87,16 +87,17 @@ EXPORTS.gfxipc += [
 
 EXPORTS.mozilla.dom += [
     'apz/util/CheckerboardReportService.h',
 ]
 
 EXPORTS.mozilla.layers += [
     'AnimationHelper.h',
     'AnimationInfo.h',
+    'apz/public/APZInputBridge.h',
     'apz/public/APZSampler.h',
     'apz/public/CompositorController.h',
     'apz/public/GeckoContentController.h',
     'apz/public/IAPZCTreeManager.h',
     'apz/public/MetricsSharingController.h',
     # exporting things from apz/src is temporary until we extract a
     # proper interface for the code there
     'apz/src/APZUtils.h',
@@ -287,18 +288,18 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'andr
     ]
     EXPORTS.mozilla.layers += [
         'apz/src/AndroidDynamicToolbarAnimator.h',
     ]
 
 UNIFIED_SOURCES += [
     'AnimationHelper.cpp',
     'AnimationInfo.cpp',
-    'apz/public/IAPZCTreeManager.cpp',
     'apz/src/APZCTreeManager.cpp',
+    'apz/src/APZInputBridge.cpp',
     'apz/src/APZSampler.cpp',
     'apz/src/APZUtils.cpp',
     'apz/src/AsyncPanZoomController.cpp',
     'apz/src/AutoscrollAnimation.cpp',
     'apz/src/Axis.cpp',
     'apz/src/CheckerboardEvent.cpp',
     'apz/src/DragTracker.cpp',
     'apz/src/FocusState.cpp',
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -52,16 +52,17 @@ using mozilla::Unused;
 #include "nsGfxCIID.h"
 
 #include "gfxContext.h"
 
 #include "Layers.h"
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "mozilla/layers/AsyncCompositionManager.h"
 #include "mozilla/layers/APZEventState.h"
+#include "mozilla/layers/APZInputBridge.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "ScopedGLHelpers.h"
 #include "mozilla/layers/CompositorOGL.h"
 #include "AndroidContentController.h"
 
@@ -485,17 +486,17 @@ public:
                                ScrollWheelInput::SCROLLMODE_SMOOTH,
                                ScrollWheelInput::SCROLLDELTA_PIXEL,
                                origin,
                                aHScroll, aVScroll,
                                false);
 
         ScrollableLayerGuid guid;
         uint64_t blockId;
-        nsEventStatus status = controller->ReceiveInputEvent(input, &guid, &blockId);
+        nsEventStatus status = controller->InputBridge()->ReceiveInputEvent(input, &guid, &blockId);
 
         if (status == nsEventStatus_eConsumeNoDefault) {
             return true;
         }
 
         PostInputEvent([input, guid, blockId, status] (nsWindow* window) {
             WidgetWheelEvent wheelEvent = input.ToWidgetWheelEvent(window);
             window->ProcessUntransformedAPZEvent(&wheelEvent, guid,
@@ -599,17 +600,17 @@ public:
         }
 
         ScreenPoint origin = ScreenPoint(aX, aY);
 
         MouseInput input(mouseType, buttonType, nsIDOMMouseEvent::MOZ_SOURCE_MOUSE, ConvertButtons(buttons), origin, aTime, GetEventTimeStamp(aTime), GetModifiers(aMetaState));
 
         ScrollableLayerGuid guid;
         uint64_t blockId;
-        nsEventStatus status = controller->ReceiveInputEvent(input, &guid, &blockId);
+        nsEventStatus status = controller->InputBridge()->ReceiveInputEvent(input, &guid, &blockId);
 
         if (status == nsEventStatus_eConsumeNoDefault) {
             return true;
         }
 
         PostInputEvent([input, guid, blockId, status] (nsWindow* window) {
             WidgetMouseEvent mouseEvent = input.ToWidgetMouseEvent(window);
             window->ProcessUntransformedAPZEvent(&mouseEvent, guid,
@@ -721,17 +722,17 @@ public:
             input.mTouches.AppendElement(SingleTouchData(
                     pointerId[i], ScreenIntPoint::FromUnknownPoint(point),
                     ScreenSize::FromUnknownSize(radius), orien, pressure[i]));
         }
 
         ScrollableLayerGuid guid;
         uint64_t blockId;
         nsEventStatus status =
-            controller->ReceiveInputEvent(input, &guid, &blockId);
+            controller->InputBridge()->ReceiveInputEvent(input, &guid, &blockId);
 
         if (status == nsEventStatus_eConsumeNoDefault) {
             return true;
         }
 
         // Dispatch APZ input event on Gecko thread.
         PostInputEvent([input, guid, blockId, status] (nsWindow* window) {
             WidgetTouchEvent touchEvent = input.ToWidgetTouchEvent(window);
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -60,16 +60,17 @@
 #include "mozilla/layers/LayerManagerComposite.h"
 #include "GfxTexturesReporter.h"
 #include "GLTextureImage.h"
 #include "GLContextProvider.h"
 #include "GLContextCGL.h"
 #include "ScopedGLHelpers.h"
 #include "HeapCopyOfStackArray.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
+#include "mozilla/layers/APZInputBridge.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/GLManager.h"
 #include "mozilla/layers/CompositorOGL.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/BasicCompositor.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/IpcResourceUpdateQueue.h"
 #include "mozilla/layers/WebRenderBridgeChild.h"
@@ -2911,17 +2912,17 @@ nsChildView::DispatchAPZWheelInputEvent(
 
   if (mAPZC) {
     uint64_t inputBlockId = 0;
     ScrollableLayerGuid guid;
     nsEventStatus result = nsEventStatus_eIgnore;
 
     switch (aEvent.mInputType) {
       case PANGESTURE_INPUT: {
-        result = mAPZC->ReceiveInputEvent(aEvent, &guid, &inputBlockId);
+        result = mAPZC->InputBridge()->ReceiveInputEvent(aEvent, &guid, &inputBlockId);
         if (result == nsEventStatus_eConsumeNoDefault) {
           return;
         }
 
         PanGestureInput& panInput = aEvent.AsPanGestureInput();
 
         event = panInput.ToWidgetWheelEvent(this);
         if (aCanTriggerSwipe && panInput.mOverscrollBehaviorAllowsSwipe) {
@@ -2950,22 +2951,22 @@ nsChildView::DispatchAPZWheelInputEvent(
 
         if (mSwipeEventQueue && mSwipeEventQueue->inputBlockId == inputBlockId) {
           mSwipeEventQueue->queuedEvents.AppendElement(panInput);
         }
         break;
       }
       case SCROLLWHEEL_INPUT: {
         // For wheel events on OS X, send it to APZ using the WidgetInputEvent
-        // variant of ReceiveInputEvent, because the IAPZCTreeManager version of
+        // variant of ReceiveInputEvent, because the APZInputBridge version of
         // that function has special handling (for delta multipliers etc.) that
         // we need to run. Using the InputData variant would bypass that and
         // go straight to the APZCTreeManager subclass.
         event = aEvent.AsScrollWheelInput().ToWidgetWheelEvent(this);
-        result = mAPZC->ReceiveInputEvent(event, &guid, &inputBlockId);
+        result = mAPZC->InputBridge()->ReceiveInputEvent(event, &guid, &inputBlockId);
         if (result == nsEventStatus_eConsumeNoDefault) {
           return;
         }
         break;
       };
       default:
         MOZ_CRASH("unsupported event type");
         return;
@@ -5098,67 +5099,67 @@ GetIntegerDeltaForEvent(NSEvent* aEvent)
     // MayBegin and Cancelled are dispatched when the fingers start or stop
     // touching the touchpad before any scrolling has occurred. These events
     // can be used to control scrollbar visibility or interrupt scroll
     // animations. They are only dispatched on 10.8 or later, and only by
     // relatively modern devices.
     if (phase == NSEventPhaseMayBegin) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_MAYSTART, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
       return;
     }
     if (phase == NSEventPhaseCancelled) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_CANCELLED, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
       return;
     }
 
     // Legacy scroll events are dispatched by devices that do not have a
     // concept of a scroll gesture, for example by USB mice with
     // traditional mouse wheels.
     // For these kinds of scrolls, we want to surround every single scroll
     // event with a PANGESTURE_START and a PANGESTURE_END event. The APZC
     // needs to know that the real scroll gesture can end abruptly after any
     // one of these events.
     bool isLegacyScroll = (phase == NSEventPhaseNone &&
       momentumPhase == NSEventPhaseNone && delta != ScreenPoint(0, 0));
 
     if (phase == NSEventPhaseBegan || isLegacyScroll) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_START, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
     if (momentumPhase == NSEventPhaseNone && delta != ScreenPoint(0, 0)) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_PAN, eventTime,
                                eventTimeStamp, location, delta, 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
     if (phase == NSEventPhaseEnded || isLegacyScroll) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_END, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
 
     // Any device that can dispatch momentum events supports all three momentum phases.
     if (momentumPhase == NSEventPhaseBegan) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_MOMENTUMSTART, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
     if (momentumPhase == NSEventPhaseChanged && delta != ScreenPoint(0, 0)) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_MOMENTUMPAN, eventTime,
                                eventTimeStamp, location, delta, 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
     if (momentumPhase == NSEventPhaseEnded) {
       PanGestureInput panInput(PanGestureInput::PANGESTURE_MOMENTUMEND, eventTime,
                                eventTimeStamp, location, ScreenPoint(0, 0), 0);
-      apzctm->ReceiveInputEvent(panInput, &guid, nullptr);
+      apzctm->InputBridge()->ReceiveInputEvent(panInput, &guid, nullptr);
     }
   }
 }
 
 -(NSMenu*)menuForEvent:(NSEvent*)theEvent
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
 
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -52,16 +52,17 @@
 #include "mozilla/gfx/2D.h"
 #include "mozilla/MouseEvents.h"
 #include "GLConsts.h"
 #include "mozilla/Unused.h"
 #include "mozilla/IMEStateManager.h"
 #include "mozilla/VsyncDispatcher.h"
 #include "mozilla/layers/IAPZCTreeManager.h"
 #include "mozilla/layers/APZEventState.h"
+#include "mozilla/layers/APZInputBridge.h"
 #include "mozilla/layers/APZThreadUtils.h"
 #include "mozilla/layers/ChromeProcessController.h"
 #include "mozilla/layers/CompositorOptions.h"
 #include "mozilla/layers/InputAPZContext.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/WebRenderLayerManager.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/TabParent.h"
@@ -1159,17 +1160,17 @@ public:
     , mAPZC(aAPZC)
     , mWidget(aWidget)
     , mInputBlockId(0)
   {
   }
 
   NS_IMETHOD Run() override
   {
-    nsEventStatus result = mAPZC->ReceiveInputEvent(mWheelInput, &mGuid, &mInputBlockId);
+    nsEventStatus result = mAPZC->InputBridge()->ReceiveInputEvent(mWheelInput, &mGuid, &mInputBlockId);
     if (result == nsEventStatus_eConsumeNoDefault) {
       return NS_OK;
     }
     RefPtr<Runnable> r = new DispatchWheelEventOnMainThread(mWheelInput, mWidget, result, mInputBlockId, mGuid);
     mMainMessageLoop->PostTask(r.forget());
     return NS_OK;
   }
 
@@ -1186,17 +1187,17 @@ void
 nsBaseWidget::DispatchTouchInput(MultiTouchInput& aInput)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mAPZC) {
     MOZ_ASSERT(APZThreadUtils::IsControllerThread());
     uint64_t inputBlockId = 0;
     ScrollableLayerGuid guid;
 
-    nsEventStatus result = mAPZC->ReceiveInputEvent(aInput, &guid, &inputBlockId);
+    nsEventStatus result = mAPZC->InputBridge()->ReceiveInputEvent(aInput, &guid, &inputBlockId);
     if (result == nsEventStatus_eConsumeNoDefault) {
       return;
     }
 
     WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this);
     ProcessUntransformedAPZEvent(&event, guid, inputBlockId, result);
   } else {
     WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this);
@@ -1211,17 +1212,17 @@ nsBaseWidget::DispatchInputEvent(WidgetI
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mAPZC) {
     if (APZThreadUtils::IsControllerThread()) {
       uint64_t inputBlockId = 0;
       ScrollableLayerGuid guid;
 
       nsEventStatus result =
-        mAPZC->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
+        mAPZC->InputBridge()->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
       if (result == nsEventStatus_eConsumeNoDefault) {
         return result;
       }
       return ProcessUntransformedAPZEvent(aEvent, guid, inputBlockId, result);
     }
     WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent();
     if (wheelEvent) {
       RefPtr<Runnable> r =
@@ -1241,17 +1242,17 @@ nsBaseWidget::DispatchInputEvent(WidgetI
 void
 nsBaseWidget::DispatchEventToAPZOnly(mozilla::WidgetInputEvent* aEvent)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (mAPZC) {
     MOZ_ASSERT(APZThreadUtils::IsControllerThread());
     uint64_t inputBlockId = 0;
     ScrollableLayerGuid guid;
-    mAPZC->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
+    mAPZC->InputBridge()->ReceiveInputEvent(*aEvent, &guid, &inputBlockId);
   }
 }
 
 // static
 bool
 nsBaseWidget::ShowContextMenuAfterMouseUp()
 {
   static bool gContextMenuAfterMouseUp = false;