summaryrefslogtreecommitdiffstats
path: root/gfx/layers/apz/public
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /gfx/layers/apz/public
parentInitial commit. (diff)
downloadfirefox-upstream/124.0.1.tar.xz
firefox-upstream/124.0.1.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--gfx/layers/apz/public/APZInputBridge.h298
-rw-r--r--gfx/layers/apz/public/APZPublicUtils.h82
-rw-r--r--gfx/layers/apz/public/APZSampler.h154
-rw-r--r--gfx/layers/apz/public/APZUpdater.h236
-rw-r--r--gfx/layers/apz/public/CompositorController.h33
-rw-r--r--gfx/layers/apz/public/GeckoContentController.h189
-rw-r--r--gfx/layers/apz/public/GeckoContentControllerTypes.h68
-rw-r--r--gfx/layers/apz/public/IAPZCTreeManager.h151
-rw-r--r--gfx/layers/apz/public/MatrixMessage.h64
9 files changed, 1275 insertions, 0 deletions
diff --git a/gfx/layers/apz/public/APZInputBridge.h b/gfx/layers/apz/public/APZInputBridge.h
new file mode 100644
index 0000000000..117e4b7bb2
--- /dev/null
+++ b/gfx/layers/apz/public/APZInputBridge.h
@@ -0,0 +1,298 @@
+/* -*- 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 "Units.h" // for LayoutDeviceIntPoint
+#include "mozilla/EventForwards.h" // for WidgetInputEvent, nsEventStatus
+#include "mozilla/layers/APZPublicUtils.h" // for APZWheelAction
+#include "mozilla/layers/LayersTypes.h" // for ScrollDirections
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid
+
+namespace mozilla {
+
+class InputData;
+
+namespace layers {
+
+class APZInputBridgeParent;
+class AsyncPanZoomController;
+class InputBlockState;
+class TouchBlockState;
+struct ScrollableLayerGuid;
+struct TargetConfirmationFlags;
+struct PointerEventsConsumableFlags;
+
+enum class APZHandledPlace : uint8_t {
+ Unhandled = 0, // we know for sure that the event will not be handled
+ // by either the root APZC or others
+ HandledByRoot = 1, // we know for sure that the event will be handled
+ // by the root content APZC
+ HandledByContent = 2, // we know for sure it will be handled by a non-root
+ // APZC or by an event listener using preventDefault()
+ // in a document
+ Invalid = 3,
+ Last = Invalid
+};
+
+struct APZHandledResult {
+ APZHandledPlace mPlace = APZHandledPlace::Invalid;
+ SideBits mScrollableDirections = SideBits::eNone;
+ ScrollDirections mOverscrollDirections = ScrollDirections();
+
+ APZHandledResult() = default;
+ // A constructor for cases where we have the target of the input block this
+ // event is part of, the target might be adjusted to be the root in the
+ // ScrollingDownWillMoveDynamicToolbar case.
+ //
+ // NOTE: There's a case where |aTarget| is the APZC for the root content but
+ // |aPlace| has to be `HandledByContent`, for example, the root content has
+ // an event handler using preventDefault() in the callback, so call sites of
+ // this function should be responsible to set a proper |aPlace|.
+ APZHandledResult(APZHandledPlace aPlace,
+ const AsyncPanZoomController* aTarget,
+ bool aPopulateDirectionsForUnhandled = false);
+ APZHandledResult(APZHandledPlace aPlace, SideBits aScrollableDirections,
+ ScrollDirections aOverscrollDirections)
+ : mPlace(aPlace),
+ mScrollableDirections(aScrollableDirections),
+ mOverscrollDirections(aOverscrollDirections) {}
+
+ bool IsHandledByContent() const {
+ return mPlace == APZHandledPlace::HandledByContent;
+ }
+ bool IsHandledByRoot() const {
+ return mPlace == APZHandledPlace::HandledByRoot;
+ }
+ bool operator==(const APZHandledResult& aOther) const {
+ return mPlace == aOther.mPlace &&
+ mScrollableDirections == aOther.mScrollableDirections &&
+ mOverscrollDirections == aOther.mOverscrollDirections;
+ }
+};
+
+/**
+ * Represents the outcome of APZ receiving and processing an input event.
+ * This is returned from APZInputBridge::ReceiveInputEvent() and related APIs.
+ */
+struct APZEventResult {
+ /**
+ * Creates a default result with a status of eIgnore, no block ID, and empty
+ * target guid.
+ */
+ APZEventResult();
+
+ /**
+ * Creates a result with a status of eIgnore, no block ID, the guid of the
+ * given initial target, and an APZHandledResult if we are sure the event
+ * is not going to be dispatched to contents.
+ */
+ APZEventResult(const RefPtr<AsyncPanZoomController>& aInitialTarget,
+ TargetConfirmationFlags aFlags);
+
+ void SetStatusAsConsumeNoDefault() {
+ mStatus = nsEventStatus_eConsumeNoDefault;
+ }
+
+ void SetStatusAsIgnore() { mStatus = nsEventStatus_eIgnore; }
+
+ // Set mStatus to nsEventStatus_eConsumeDoDefault and set mHandledResult
+ // depending on |aTarget|.
+ void SetStatusAsConsumeDoDefault(
+ const RefPtr<AsyncPanZoomController>& aTarget);
+
+ // Set mStatus to nsEventStatus_eConsumeDoDefault, unlike above
+ // SetStatusAsConsumeDoDefault(const RefPtr<AsyncPanZoomController>&) this
+ // function doesn't mutate mHandledResult.
+ void SetStatusAsConsumeDoDefault() {
+ mStatus = nsEventStatus_eConsumeDoDefault;
+ }
+
+ // Set mStatus to nsEventStatus_eConsumeDoDefault and set mHandledResult
+ // depending on |aBlock|'s target APZC.
+ void SetStatusAsConsumeDoDefault(const InputBlockState& aBlock);
+ // Set mStatus and mHandledResult for a touch event which is not dropped
+ // altogether (i.e. the status is not eConsumeNoDefault).
+ void SetStatusForTouchEvent(const InputBlockState& aBlock,
+ TargetConfirmationFlags aFlags,
+ PointerEventsConsumableFlags aConsumableFlags,
+ const AsyncPanZoomController* aTarget);
+
+ // Set mStatus and mHandledResult during in a stat of fast fling.
+ void SetStatusForFastFling(const TouchBlockState& aBlock,
+ TargetConfirmationFlags aFlags,
+ PointerEventsConsumableFlags aConsumableFlags,
+ const AsyncPanZoomController* aTarget);
+
+ // DO NOT USE THIS UpdateStatus DIRECTLY. THIS FUNCTION IS ONLY FOR
+ // SERIALIZATION / DESERIALIZATION OF THIS STRUCT IN IPC.
+ void UpdateStatus(nsEventStatus aStatus) { mStatus = aStatus; }
+ nsEventStatus GetStatus() const { return mStatus; };
+
+ // DO NOT USE THIS UpdateHandledResult DIRECTLY. THIS FUNCTION IS ONLY FOR
+ // SERIALIZATION / DESERIALIZATION OF THIS STRUCT IN IPC.
+ void UpdateHandledResult(const Maybe<APZHandledResult>& aHandledResult) {
+ mHandledResult = aHandledResult;
+ }
+ const Maybe<APZHandledResult>& GetHandledResult() const {
+ return mHandledResult;
+ }
+
+ bool WillHaveDelayedResult() const {
+ return GetStatus() != nsEventStatus_eConsumeNoDefault &&
+ !GetHandledResult();
+ }
+
+ private:
+ void UpdateHandledResult(const InputBlockState& aBlock,
+ PointerEventsConsumableFlags aConsumableFlags,
+ const AsyncPanZoomController* aTarget,
+ bool aDispatchToContent);
+
+ /**
+ * A status flag indicated how APZ handled the event.
+ * The interpretation of each value is as follows:
+ *
+ * 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.
+ */
+ nsEventStatus mStatus;
+
+ /**
+ * This is:
+ * - set to HandledByRoot if we know for sure that the event will be handled
+ * by the root content APZC;
+ * - set to HandledByContent if we know for sure it will not be;
+ * - left empty if we are unsure.
+ */
+ Maybe<APZHandledResult> mHandledResult;
+
+ public:
+ /**
+ * The guid of the APZC initially targeted by this event.
+ * This will usually be the APZC that handles the event, but in cases
+ * where the event is dispatched to content, it may end up being
+ * handled by a different APZC.
+ */
+ ScrollableLayerGuid mTargetGuid;
+ /**
+ * If this event started or was added to an input block, the id of that
+ * input block, otherwise InputBlockState::NO_BLOCK_ID.
+ */
+ uint64_t mInputBlockId;
+};
+
+/**
+ * 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:
+ using InputBlockCallback = std::function<void(
+ uint64_t aInputBlockId, const APZHandledResult& aHandledResult)>;
+
+ /**
+ * 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.
+ *
+ * @param aEvent input event object; is modified in-place
+ * @param aCallback an optional callback to be invoked when the input block is
+ * ready for handling,
+ * @return The result of processing the event. Refer to the documentation of
+ * APZEventResult and its field.
+ */
+ virtual APZEventResult ReceiveInputEvent(
+ InputData& aEvent,
+ InputBlockCallback&& aCallback = InputBlockCallback()) = 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.
+ */
+ APZEventResult ReceiveInputEvent(
+ WidgetInputEvent& aEvent,
+ InputBlockCallback&& aCallback = InputBlockCallback());
+
+ // Returns the kind of wheel event action, if any, that will be (or was)
+ // performed by APZ. If this returns true, the event must not perform a
+ // synchronous scroll.
+ //
+ // Even if this returns Nothing(), all wheel events in APZ-aware widgets must
+ // be sent through APZ so they are transformed correctly for BrowserParent.
+ static Maybe<APZWheelAction> ActionForWheelEvent(WidgetWheelEvent* aEvent);
+
+ protected:
+ friend class APZInputBridgeParent;
+
+ // Methods to help process WidgetInputEvents (or manage conversion to/from
+ // InputData)
+
+ virtual void ProcessUnhandledEvent(LayoutDeviceIntPoint* aRefPoint,
+ ScrollableLayerGuid* aOutTargetGuid,
+ uint64_t* aOutFocusSequenceNumber,
+ LayersId* aOutLayersId) = 0;
+
+ virtual void UpdateWheelTransaction(
+ LayoutDeviceIntPoint aRefPoint, EventMessage aEventMessage,
+ const Maybe<ScrollableLayerGuid>& aTargetGuid) = 0;
+
+ virtual ~APZInputBridge() = default;
+};
+
+std::ostream& operator<<(std::ostream& aOut,
+ const APZHandledResult& aHandledResult);
+
+// This enum class is used for communicating between APZ and the browser gesture
+// support code. APZ needs to wait for the browser to send this response just
+// like APZ waits for the content's response if there's an APZ ware event
+// listener in the content process.
+enum class BrowserGestureResponse : bool {
+ NotConsumed = 0, // Representing the browser doesn't consume the gesture
+ Consumed = 1, // Representing the browser has started consuming the gesture.
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_APZInputBridge_h
diff --git a/gfx/layers/apz/public/APZPublicUtils.h b/gfx/layers/apz/public/APZPublicUtils.h
new file mode 100644
index 0000000000..6433008b4c
--- /dev/null
+++ b/gfx/layers/apz/public/APZPublicUtils.h
@@ -0,0 +1,82 @@
+/* -*- 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_APZPublicUtils_h
+#define mozilla_layers_APZPublicUtils_h
+
+// This file is for APZ-related utilities that need to be consumed from outside
+// of gfx/layers. For internal utilities, prefer APZUtils.h.
+
+#include <stdint.h>
+#include <utility>
+#include "ScrollAnimationBezierPhysics.h"
+#include "Units.h"
+#include "mozilla/DefineEnum.h"
+#include "mozilla/ScrollOrigin.h"
+#include "mozilla/gfx/Point.h"
+#include "mozilla/ScrollTypes.h"
+
+namespace mozilla {
+
+namespace layers {
+
+struct FrameMetrics;
+
+// clang-format off
+MOZ_DEFINE_ENUM_CLASS_WITH_BASE(APZWheelAction, uint8_t, (
+ Scroll,
+ PinchZoom
+))
+// clang-format on
+
+namespace apz {
+
+/**
+ * Initializes the global state used in AsyncPanZoomController.
+ * This is normally called when it is first needed in the constructor
+ * of APZCTreeManager, but can be called manually to force it to be
+ * initialized earlier.
+ */
+void InitializeGlobalState();
+
+/**
+ * See AsyncPanZoomController::CalculatePendingDisplayPort. This
+ * function simply delegates to that one, so that non-layers code
+ * never needs to include AsyncPanZoomController.h
+ */
+const ScreenMargin CalculatePendingDisplayPort(
+ const FrameMetrics& aFrameMetrics, const ParentLayerPoint& aVelocity);
+
+/**
+ * Returns a width and height multiplier, each of which is a power of two
+ * between 1 and 8 inclusive. The multiplier is chosen based on the provided
+ * base size, such that multiplier is larger when the base size is larger.
+ * The exact details are somewhat arbitrary and tuned by hand.
+ * This function is intended to only be used with WebRender, because that is
+ * the codepath that wants to use a larger displayport alignment, because
+ * moving the displayport is relatively expensive with WebRender.
+ */
+gfx::IntSize GetDisplayportAlignmentMultiplier(const ScreenSize& aBaseSize);
+
+/**
+ * Calculate the physics parameters for smooth scroll animations for the
+ * given origin, based on pref values.
+ */
+ScrollAnimationBezierPhysicsSettings ComputeBezierAnimationSettingsForOrigin(
+ ScrollOrigin aOrigin);
+
+/**
+ * Calculate if the scrolling should be instant or smooth based based on
+ * preferences and the origin
+ */
+ScrollMode GetScrollModeForOrigin(ScrollOrigin origin);
+
+} // namespace apz
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_APZPublicUtils_h
diff --git a/gfx/layers/apz/public/APZSampler.h b/gfx/layers/apz/public/APZSampler.h
new file mode 100644
index 0000000000..a870c2d688
--- /dev/null
+++ b/gfx/layers/apz/public/APZSampler.h
@@ -0,0 +1,154 @@
+/* -*- 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_APZSampler_h
+#define mozilla_layers_APZSampler_h
+
+#include <unordered_map>
+
+#include "apz/src/APZCTreeManager.h"
+#include "base/platform_thread.h" // for PlatformThreadId
+#include "mozilla/layers/APZUtils.h"
+#include "mozilla/layers/SampleTime.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/StaticPtr.h"
+#include "mozilla/webrender/WebRenderTypes.h"
+#include "Units.h"
+#include "VsyncSource.h"
+
+namespace mozilla {
+
+class TimeStamp;
+
+namespace wr {
+struct Transaction;
+class TransactionWrapper;
+struct WrWindowId;
+} // namespace wr
+
+namespace layers {
+
+struct ScrollbarData;
+
+/**
+ * This interface exposes APZ methods related to "sampling" (i.e. reading the
+ * async transforms produced by APZ). These methods should all be called on
+ * the sampler thread.
+ */
+class APZSampler {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZSampler)
+
+ public:
+ APZSampler(const RefPtr<APZCTreeManager>& aApz, bool aIsUsingWebRender);
+
+ // Whoever creates this sampler is responsible for calling Destroy() on it
+ // before releasing the owning refptr.
+ void Destroy();
+
+ void SetWebRenderWindowId(const wr::WindowId& aWindowId);
+
+ /**
+ * This function is invoked from rust on the render backend thread when it
+ * is created. It effectively tells the APZSampler "the current thread is
+ * the sampler thread for this window id" and allows APZSampler to remember
+ * which thread it is.
+ */
+ static void SetSamplerThread(const wr::WrWindowId& aWindowId);
+ static void SampleForWebRender(const wr::WrWindowId& aWindowId,
+ const uint64_t* aGeneratedFrameId,
+ wr::Transaction* aTransaction);
+
+ void SetSampleTime(const SampleTime& aSampleTime);
+ void SampleForWebRender(const Maybe<VsyncId>& aGeneratedFrameId,
+ wr::TransactionWrapper& aTxn);
+
+ /**
+ * Similar to above GetCurrentAsyncTransform, but get the current transform
+ * with LayersId and ViewID.
+ * NOTE: This function should NOT be called on the compositor thread.
+ */
+ AsyncTransform GetCurrentAsyncTransform(
+ const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId,
+ AsyncTransformComponents aComponents,
+ const MutexAutoLock& aProofOfMapLock) const;
+
+ /**
+ * Returns the composition bounds of the APZC corresponding to the pair of
+ * |aLayersId| and |aScrollId|.
+ */
+ ParentLayerRect GetCompositionBounds(
+ const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId,
+ const MutexAutoLock& aProofOfMapLock) const;
+
+ struct ScrollOffsetAndRange {
+ CSSPoint mOffset;
+ CSSRect mRange;
+ };
+ /**
+ * Returns the scroll offset and scroll range of the APZC corresponding to the
+ * pair of |aLayersId| and |aScrollId|
+ *
+ * Note: This is called from OMTA Sampler thread, or Compositor thread for
+ * testing.
+ */
+ Maybe<ScrollOffsetAndRange> GetCurrentScrollOffsetAndRange(
+ const LayersId& aLayersId, const ScrollableLayerGuid::ViewID& aScrollId,
+ const MutexAutoLock& aProofOfMapLock) const;
+
+ /**
+ * This can be used to assert that the current thread is the
+ * sampler thread (which samples the async transform).
+ * This does nothing if thread assertions are disabled.
+ */
+ void AssertOnSamplerThread() const;
+
+ /**
+ * Returns true if currently on the APZSampler's "sampler thread".
+ */
+ bool IsSamplerThread() const;
+
+ template <typename Callback>
+ void CallWithMapLock(Callback& aCallback) {
+ mApz->CallWithMapLock(aCallback);
+ }
+
+ protected:
+ virtual ~APZSampler();
+
+ static already_AddRefed<APZSampler> GetSampler(
+ const wr::WrWindowId& aWindowId);
+
+ private:
+ RefPtr<APZCTreeManager> mApz;
+ bool mIsUsingWebRender;
+
+ // Used to manage the mapping from a WR window id to APZSampler. These are
+ // only used if WebRender is enabled. Both sWindowIdMap and mWindowId should
+ // only be used while holding the sWindowIdLock. Note that we use a
+ // StaticAutoPtr wrapper on sWindowIdMap to avoid a static initializer for the
+ // unordered_map. This also avoids the initializer/memory allocation in cases
+ // where we're not using WebRender.
+ static StaticMutex sWindowIdLock MOZ_UNANNOTATED;
+ static StaticAutoPtr<std::unordered_map<uint64_t, RefPtr<APZSampler>>>
+ sWindowIdMap;
+ Maybe<wr::WrWindowId> mWindowId;
+
+ // Lock used to protected mSamplerThreadId
+ mutable Mutex mThreadIdLock MOZ_UNANNOTATED;
+ // If WebRender is enabled, this holds the thread id of the render backend
+ // thread (which is the sampler thread) for the compositor associated with
+ // this APZSampler instance.
+ Maybe<PlatformThreadId> mSamplerThreadId;
+
+ Mutex mSampleTimeLock MOZ_UNANNOTATED;
+ // Can only be accessed or modified while holding mSampleTimeLock.
+ SampleTime mSampleTime;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_APZSampler_h
diff --git a/gfx/layers/apz/public/APZUpdater.h b/gfx/layers/apz/public/APZUpdater.h
new file mode 100644
index 0000000000..66d040b356
--- /dev/null
+++ b/gfx/layers/apz/public/APZUpdater.h
@@ -0,0 +1,236 @@
+/* -*- 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_APZUpdater_h
+#define mozilla_layers_APZUpdater_h
+
+#include <deque>
+#include <unordered_map>
+
+#include "base/platform_thread.h" // for PlatformThreadId
+#include "LayersTypes.h"
+#include "mozilla/layers/APZTestData.h"
+#include "mozilla/layers/WebRenderScrollData.h"
+#include "mozilla/StaticMutex.h"
+#include "mozilla/StaticPtr.h"
+#include "mozilla/webrender/WebRenderTypes.h"
+#include "nsThreadUtils.h"
+#include "Units.h"
+
+namespace mozilla {
+
+namespace layers {
+
+class APZCTreeManager;
+class FocusTarget;
+class WebRenderScrollData;
+
+/**
+ * This interface is used to send updates or otherwise mutate APZ internal
+ * state. These functions is usually called from the compositor thread in
+ * response to IPC messages. The method implementations internally redispatch
+ * themselves to the updater thread in the case where the compositor thread
+ * is not the updater thread.
+ */
+class APZUpdater {
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(APZUpdater)
+
+ public:
+ APZUpdater(const RefPtr<APZCTreeManager>& aApz, bool aConnectedToWebRender);
+
+ bool HasTreeManager(const RefPtr<APZCTreeManager>& aApz);
+ void SetWebRenderWindowId(const wr::WindowId& aWindowId);
+
+ /**
+ * This function is invoked from rust on the scene builder thread when it
+ * is created. It effectively tells the APZUpdater "the current thread is
+ * the updater thread for this window id" and allows APZUpdater to remember
+ * which thread it is.
+ */
+ static void SetUpdaterThread(const wr::WrWindowId& aWindowId);
+ static void PrepareForSceneSwap(const wr::WrWindowId& aWindowId);
+ static void CompleteSceneSwap(const wr::WrWindowId& aWindowId,
+ const wr::WrPipelineInfo& aInfo);
+ static void ProcessPendingTasks(const wr::WrWindowId& aWindowId);
+
+ void ClearTree(LayersId aRootLayersId);
+ void UpdateFocusState(LayersId aRootLayerTreeId,
+ LayersId aOriginatingLayersId,
+ const FocusTarget& aFocusTarget);
+ /**
+ * This should be called (in the WR-enabled case) when the compositor receives
+ * a new WebRenderScrollData for a layers id. The |aScrollData| parameter is
+ * the scroll data for |aOriginatingLayersId| and |aEpoch| is the
+ * corresponding epoch for the transaction that transferred the scroll data.
+ * This function will store the new scroll data and update the focus state and
+ * hit-testing tree.
+ */
+ void UpdateScrollDataAndTreeState(LayersId aRootLayerTreeId,
+ LayersId aOriginatingLayersId,
+ const wr::Epoch& aEpoch,
+ WebRenderScrollData&& aScrollData);
+ /**
+ * This is called in the WR-enabled case when we get an empty transaction that
+ * has some scroll offset updates (from paint-skipped scrolling on the content
+ * side). This function will update the stored scroll offsets and the
+ * hit-testing tree.
+ */
+ void UpdateScrollOffsets(LayersId aRootLayerTreeId,
+ LayersId aOriginatingLayersId,
+ ScrollUpdatesMap&& aUpdates,
+ uint32_t aPaintSequenceNumber);
+
+ void NotifyLayerTreeAdopted(LayersId aLayersId,
+ const RefPtr<APZUpdater>& aOldUpdater);
+ void NotifyLayerTreeRemoved(LayersId aLayersId);
+
+ bool GetAPZTestData(LayersId aLayersId, APZTestData* aOutData);
+
+ void SetTestAsyncScrollOffset(LayersId aLayersId,
+ const ScrollableLayerGuid::ViewID& aScrollId,
+ const CSSPoint& aOffset);
+ void SetTestAsyncZoom(LayersId aLayersId,
+ const ScrollableLayerGuid::ViewID& aScrollId,
+ const LayerToParentLayerScale& aZoom);
+
+ // This can only be called on the updater thread.
+ const WebRenderScrollData* GetScrollData(LayersId aLayersId) const;
+
+ /**
+ * This can be used to assert that the current thread is the
+ * updater thread (which samples the async transform).
+ * This does nothing if thread assertions are disabled.
+ */
+ void AssertOnUpdaterThread() const;
+
+ /**
+ * Runs the given task on the APZ "updater thread" for this APZUpdater. If
+ * this function is called from the updater thread itself then the task is
+ * run immediately without getting queued.
+ *
+ * The layers id argument should be the id of the layer tree that is
+ * requesting this task to be run. Conceptually each layer tree has a separate
+ * task queue, so that if one layer tree is blocked waiting for a scene build
+ * then tasks for the other layer trees can still be processed.
+ */
+ void RunOnUpdaterThread(LayersId aLayersId, already_AddRefed<Runnable> aTask);
+
+ /**
+ * Returns true if currently on the APZUpdater's "updater thread".
+ */
+ bool IsUpdaterThread() const;
+
+ /**
+ * Dispatches the given task to the APZ "controller thread", but does it
+ * *from* the updater thread. That is, if the thread on which this function is
+ * called is not the updater thread, the task is first dispatched to the
+ * updater thread. When the updater thread runs it (or if this is called
+ * directly on the updater thread), that is when the task gets dispatched to
+ * the controller thread. The controller thread then actually runs the task.
+ *
+ * See the RunOnUpdaterThread method for details on the layers id argument.
+ */
+ void RunOnControllerThread(LayersId aLayersId,
+ already_AddRefed<Runnable> aTask);
+
+ void MarkAsDetached(LayersId aLayersId);
+
+ protected:
+ virtual ~APZUpdater();
+
+ // Return true if the APZUpdater is connected to WebRender and is
+ // using a WebRender scene builder thread as its updater thread.
+ // This is only false during GTests, and a shutdown codepath during
+ // which we create a dummy APZUpdater.
+ bool IsConnectedToWebRender() const;
+
+ static already_AddRefed<APZUpdater> GetUpdater(
+ const wr::WrWindowId& aWindowId);
+
+ void ProcessQueue();
+
+ private:
+ RefPtr<APZCTreeManager> mApz;
+ bool mDestroyed;
+ bool mConnectedToWebRender;
+
+ // Map from layers id to WebRenderScrollData. This can only be touched on
+ // the updater thread.
+ std::unordered_map<LayersId, WebRenderScrollData, LayersId::HashFn>
+ mScrollData;
+
+ // Stores epoch state for a particular layers id. This structure is only
+ // accessed on the updater thread.
+ struct EpochState {
+ // The epoch for the most recent scroll data sent from the content side.
+ wr::Epoch mRequired;
+ // The epoch for the most recent scene built and swapped in on the WR side.
+ Maybe<wr::Epoch> mBuilt;
+ // True if and only if the layers id is the root layers id for the
+ // compositor
+ bool mIsRoot;
+
+ EpochState();
+
+ // Whether or not the state for this layers id is such that it blocks
+ // processing of tasks for the layer tree. This happens if the root layers
+ // id or a "visible" layers id has scroll data for an epoch newer than what
+ // has been built. A "visible" layers id is one that is attached to the full
+ // layer tree (i.e. there is a chain of reflayer items from the root layer
+ // tree to the relevant layer subtree). This is not always the case; for
+ // instance a content process may send the compositor layers for a document
+ // before the chrome has attached the remote iframe to the root document.
+ // Since WR only builds pipelines for "visible" layers ids, |mBuilt| being
+ // populated means that the layers id is "visible".
+ bool IsBlocked() const;
+ };
+
+ // Map from layers id to epoch state.
+ // This data structure can only be touched on the updater thread.
+ std::unordered_map<LayersId, EpochState, LayersId::HashFn> mEpochData;
+
+ // Used to manage the mapping from a WR window id to APZUpdater. These are
+ // only used if WebRender is enabled. Both sWindowIdMap and mWindowId should
+ // only be used while holding the sWindowIdLock. Note that we use a
+ // StaticAutoPtr wrapper on sWindowIdMap to avoid a static initializer for the
+ // unordered_map. This also avoids the initializer/memory allocation in cases
+ // where we're not using WebRender.
+ static StaticMutex sWindowIdLock MOZ_UNANNOTATED;
+ static StaticAutoPtr<std::unordered_map<uint64_t, APZUpdater*>> sWindowIdMap;
+ Maybe<wr::WrWindowId> mWindowId;
+
+ // Lock used to protected mUpdaterThreadId;
+ mutable Mutex mThreadIdLock MOZ_UNANNOTATED;
+ // If WebRender and async scene building are enabled, this holds the thread id
+ // of the scene builder thread (which is the updater thread) for the
+ // compositor associated with this APZUpdater instance. It may be populated
+ // even if async scene building is not enabled, but in that case we don't
+ // care about the contents.
+ Maybe<PlatformThreadId> mUpdaterThreadId;
+
+ // Helper struct that pairs each queued runnable with the layers id that it is
+ // associated with. This allows us to easily implement the conceptual
+ // separation of mUpdaterQueue into independent queues per layers id.
+ struct QueuedTask {
+ LayersId mLayersId;
+ RefPtr<Runnable> mRunnable;
+ };
+
+ // Lock used to protect mUpdaterQueue
+ Mutex mQueueLock MOZ_UNANNOTATED;
+ // Holds a queue of tasks to be run on the updater thread, when the updater
+ // thread is a WebRender thread, since it won't have a message loop we can
+ // dispatch to. Note that although this is a single queue it is conceptually
+ // separated into multiple ones, one per layers id. Tasks for a given layers
+ // id will always run in FIFO order, but there is no guaranteed ordering for
+ // tasks with different layers ids.
+ std::deque<QueuedTask> mUpdaterQueue;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_APZUpdater_h
diff --git a/gfx/layers/apz/public/CompositorController.h b/gfx/layers/apz/public/CompositorController.h
new file mode 100644
index 0000000000..ad71a8faf5
--- /dev/null
+++ b/gfx/layers/apz/public/CompositorController.h
@@ -0,0 +1,33 @@
+/* -*- 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_CompositorController_h
+#define mozilla_layers_CompositorController_h
+
+#include "nsISupportsImpl.h" // for NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+#include "mozilla/Maybe.h"
+#include "mozilla/webrender/WebRenderTypes.h"
+
+namespace mozilla {
+namespace layers {
+
+class CompositorController {
+ public:
+ NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
+
+ /**
+ * Ask the compositor to schedule a new composite.
+ */
+ virtual void ScheduleRenderOnCompositorThread(wr::RenderReasons aReasons) = 0;
+
+ protected:
+ virtual ~CompositorController() = default;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_CompositorController_h
diff --git a/gfx/layers/apz/public/GeckoContentController.h b/gfx/layers/apz/public/GeckoContentController.h
new file mode 100644
index 0000000000..ad6246d4f8
--- /dev/null
+++ b/gfx/layers/apz/public/GeckoContentController.h
@@ -0,0 +1,189 @@
+/* -*- 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_GeckoContentController_h
+#define mozilla_layers_GeckoContentController_h
+
+#include "GeckoContentControllerTypes.h"
+#include "InputData.h" // for PinchGestureInput
+#include "LayersTypes.h" // for ScrollDirection
+#include "Units.h" // for CSSPoint, CSSRect, etc
+#include "mozilla/Assertions.h" // for MOZ_ASSERT_HELPER2
+#include "mozilla/Attributes.h" // for MOZ_CAN_RUN_SCRIPT
+#include "mozilla/DefineEnum.h" // for MOZ_DEFINE_ENUM
+#include "mozilla/EventForwards.h" // for Modifiers
+#include "mozilla/layers/APZThreadUtils.h"
+#include "mozilla/layers/MatrixMessage.h" // for MatrixMessage
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid, etc
+#include "nsISupportsImpl.h"
+
+namespace mozilla {
+
+class Runnable;
+
+namespace layers {
+
+struct DoubleTapToZoomMetrics;
+struct RepaintRequest;
+
+class GeckoContentController {
+ public:
+ using APZStateChange = GeckoContentController_APZStateChange;
+ using TapType = GeckoContentController_TapType;
+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GeckoContentController)
+
+ /**
+ * Notifies the content side of the most recently computed transforms for
+ * each layers subtree to the root. The nsTArray will contain one
+ * MatrixMessage for each layers id in the current APZ tree, along with the
+ * corresponding transform.
+ */
+ virtual void NotifyLayerTransforms(nsTArray<MatrixMessage>&& aTransforms) = 0;
+
+ /**
+ * Requests a paint of the given RepaintRequest |aRequest| from Gecko.
+ * Implementations per-platform are responsible for actually handling this.
+ *
+ * This method must always be called on the repaint thread, which depends
+ * on the GeckoContentController. For ChromeProcessController it is the
+ * Gecko main thread, while for RemoteContentController it is the compositor
+ * thread where it can send IPDL messages.
+ */
+ virtual void RequestContentRepaint(const RepaintRequest& aRequest) = 0;
+
+ /**
+ * Requests handling of a tap event. |aPoint| is in LD pixels, relative to the
+ * current scroll offset.
+ */
+ MOZ_CAN_RUN_SCRIPT
+ virtual void HandleTap(
+ TapType aType, const LayoutDevicePoint& aPoint, Modifiers aModifiers,
+ const ScrollableLayerGuid& aGuid, uint64_t aInputBlockId,
+ const Maybe<DoubleTapToZoomMetrics>& aDoubleTapTooZoomMetrics) = 0;
+
+ /**
+ * When the apz.allow_zooming pref is set to false, the APZ will not
+ * translate pinch gestures to actual zooming. Instead, it will call this
+ * method to notify gecko of the pinch gesture, and allow it to deal with it
+ * however it wishes. Note that this function is not called if the pinch is
+ * prevented by content calling preventDefault() on the touch events, or via
+ * use of the touch-action property.
+ * @param aType One of PINCHGESTURE_START, PINCHGESTURE_SCALE,
+ * PINCHGESTURE_FINGERLIFTED, or PINCHGESTURE_END, indicating the phase
+ * of the pinch.
+ * @param aGuid The guid of the APZ that is detecting the pinch. This is
+ * generally the root APZC for the layers id.
+ * @param aFocusPoint The focus point of the pinch event.
+ * @param aSpanChange For the START or END event, this is always 0.
+ * For a SCALE event, this is the difference in span between the
+ * previous state and the new state.
+ * @param aModifiers The keyboard modifiers depressed during the pinch.
+ */
+ virtual void NotifyPinchGesture(PinchGestureInput::PinchGestureType aType,
+ const ScrollableLayerGuid& aGuid,
+ const LayoutDevicePoint& aFocusPoint,
+ LayoutDeviceCoord aSpanChange,
+ Modifiers aModifiers) = 0;
+
+ /**
+ * Schedules a runnable to run on the controller thread at some time
+ * in the future.
+ * This method must always be called on the controller thread.
+ */
+ virtual void PostDelayedTask(already_AddRefed<Runnable> aRunnable,
+ int aDelayMs) {
+ APZThreadUtils::DelayedDispatch(std::move(aRunnable), aDelayMs);
+ }
+
+ /**
+ * Returns true if we are currently on the thread that can send repaint
+ * requests.
+ */
+ virtual bool IsRepaintThread() = 0;
+
+ /**
+ * Runs the given task on the "repaint" thread.
+ */
+ virtual void DispatchToRepaintThread(already_AddRefed<Runnable> aTask) = 0;
+
+ /**
+ * General notices of APZ state changes for consumers.
+ * |aGuid| identifies the APZC originating the state change.
+ * |aChange| identifies the type of state change
+ * |aArg| is used by some state changes to pass extra information (see
+ * the documentation for each state change above)
+ * |aInputBlockId| is populated for the |eStartTouch| and |eEndTouch|
+ * state changes and identifies the input block of the
+ * gesture that triggers the state change.
+ */
+ virtual void NotifyAPZStateChange(const ScrollableLayerGuid& aGuid,
+ APZStateChange aChange, int aArg = 0,
+ Maybe<uint64_t> aInputBlockId = Nothing()) {
+ }
+
+ /**
+ * Notify content of a MozMouseScrollFailed event.
+ */
+ virtual void NotifyMozMouseScrollEvent(
+ const ScrollableLayerGuid::ViewID& aScrollId, const nsString& aEvent) {}
+
+ /**
+ * Notify content that the repaint requests have been flushed.
+ */
+ virtual void NotifyFlushComplete() = 0;
+
+ /**
+ * If the async scrollbar-drag initiation code kicks in on the APZ side, then
+ * we need to let content know that we are dragging the scrollbar. Otherwise,
+ * by the time the mousedown events is handled by content, the scrollthumb
+ * could already have been moved via a RequestContentRepaint message at a
+ * new scroll position, and the mousedown might end up triggering a click-to-
+ * scroll on where the thumb used to be.
+ */
+ virtual void NotifyAsyncScrollbarDragInitiated(
+ uint64_t aDragBlockId, const ScrollableLayerGuid::ViewID& aScrollId,
+ ScrollDirection aDirection) = 0;
+ virtual void NotifyAsyncScrollbarDragRejected(
+ const ScrollableLayerGuid::ViewID& aScrollId) = 0;
+
+ virtual void NotifyAsyncAutoscrollRejected(
+ const ScrollableLayerGuid::ViewID& aScrollId) = 0;
+
+ virtual void CancelAutoscroll(const ScrollableLayerGuid& aGuid) = 0;
+
+ virtual void NotifyScaleGestureComplete(const ScrollableLayerGuid& aGuid,
+ float aScale) = 0;
+
+ virtual void UpdateOverscrollVelocity(const ScrollableLayerGuid& aGuid,
+ float aX, float aY,
+ bool aIsRootContent) {}
+ virtual void UpdateOverscrollOffset(const ScrollableLayerGuid& aGuid,
+ float aX, float aY, bool aIsRootContent) {
+ }
+
+ GeckoContentController() = default;
+
+ /**
+ * Needs to be called on the main thread.
+ */
+ virtual void Destroy() {}
+
+ /**
+ * Whether this is RemoteContentController.
+ */
+ virtual bool IsRemote() { return false; }
+
+ virtual PresShell* GetTopLevelPresShell() const { return nullptr; };
+
+ protected:
+ // Protected destructor, to discourage deletion outside of Release():
+ virtual ~GeckoContentController() = default;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_GeckoContentController_h
diff --git a/gfx/layers/apz/public/GeckoContentControllerTypes.h b/gfx/layers/apz/public/GeckoContentControllerTypes.h
new file mode 100644
index 0000000000..8ab478eab5
--- /dev/null
+++ b/gfx/layers/apz/public/GeckoContentControllerTypes.h
@@ -0,0 +1,68 @@
+/* -*- 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_GeckoContentControllerTypes_h
+#define mozilla_layers_GeckoContentControllerTypes_h
+
+#include "mozilla/DefineEnum.h"
+
+namespace mozilla {
+namespace layers {
+
+// clang-format off
+MOZ_DEFINE_ENUM_CLASS(GeckoContentController_APZStateChange, (
+ /**
+ * APZ started modifying the view (including panning, zooming, and fling).
+ */
+ eTransformBegin,
+ /**
+ * APZ finished modifying the view.
+ */
+ eTransformEnd,
+ /**
+ * APZ started a touch.
+ * |aArg| is 1 if touch can be a pan, 0 otherwise.
+ */
+ eStartTouch,
+ /**
+ * APZ started a pan.
+ */
+ eStartPanning,
+ /**
+ * APZ finished processing a touch.
+ * |aArg| is 1 if touch was a click, 0 otherwise.
+ */
+ eEndTouch
+));
+// clang-format on
+
+/**
+ * Different types of tap-related events that can be sent in
+ * the HandleTap function. The names should be relatively self-explanatory.
+ * Note that the eLongTapUp will always be preceded by an eLongTap, but not
+ * all eLongTap notifications will be followed by an eLongTapUp (for instance,
+ * if the user moves their finger after triggering the long-tap but before
+ * lifting it).
+ * The difference between eDoubleTap and eSecondTap is subtle - the eDoubleTap
+ * is for an actual double-tap "gesture" while eSecondTap is for the same user
+ * input but where a double-tap gesture is not allowed. This is used to fire
+ * a click event with detail=2 to web content (similar to what a mouse double-
+ * click would do).
+ */
+// clang-format off
+MOZ_DEFINE_ENUM_CLASS(GeckoContentController_TapType, (
+ eSingleTap,
+ eDoubleTap,
+ eSecondTap,
+ eLongTap,
+ eLongTapUp
+));
+// clang-format on
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_GeckoContentControllerTypes_h
diff --git a/gfx/layers/apz/public/IAPZCTreeManager.h b/gfx/layers/apz/public/IAPZCTreeManager.h
new file mode 100644
index 0000000000..59135699a1
--- /dev/null
+++ b/gfx/layers/apz/public/IAPZCTreeManager.h
@@ -0,0 +1,151 @@
+/* -*- 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_IAPZCTreeManager_h
+#define mozilla_layers_IAPZCTreeManager_h
+
+#include <stdint.h> // for uint64_t, uint32_t
+
+#include "mozilla/layers/LayersTypes.h" // for TouchBehaviorFlags
+#include "mozilla/layers/ScrollableLayerGuid.h" // for ScrollableLayerGuid, etc
+#include "mozilla/layers/ZoomConstraints.h" // for ZoomConstraints
+#include "nsTArrayForwardDeclare.h" // for nsTArray, nsTArray_Impl, etc
+#include "nsISupportsImpl.h" // for MOZ_COUNT_CTOR, etc
+#include "Units.h" // for CSSRect, etc
+
+namespace mozilla {
+namespace layers {
+
+class APZInputBridge;
+class KeyboardMap;
+struct ZoomTarget;
+
+enum AllowedTouchBehavior {
+ NONE = 0,
+ VERTICAL_PAN = 1 << 0,
+ HORIZONTAL_PAN = 1 << 1,
+ PINCH_ZOOM = 1 << 2,
+ ANIMATING_ZOOM = 1 << 3,
+ UNKNOWN = 1 << 4
+};
+
+enum ZoomToRectBehavior : uint32_t {
+ DEFAULT_BEHAVIOR = 0,
+ DISABLE_ZOOM_OUT = 1 << 0,
+ PAN_INTO_VIEW_ONLY = 1 << 1,
+ ONLY_ZOOM_TO_DEFAULT_SCALE = 1 << 2,
+ ZOOM_TO_FOCUSED_INPUT = 1 << 3,
+};
+
+enum class BrowserGestureResponse : bool;
+
+class AsyncDragMetrics;
+struct APZHandledResult;
+
+class IAPZCTreeManager {
+ NS_INLINE_DECL_THREADSAFE_VIRTUAL_REFCOUNTING(IAPZCTreeManager)
+
+ public:
+ /**
+ * 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
+ * up. |aRect| must be given in CSS pixels, relative to the document.
+ * |aFlags| is a combination of the ZoomToRectBehavior enum values.
+ */
+ virtual void ZoomToRect(const ScrollableLayerGuid& aGuid,
+ const ZoomTarget& aZoomTarget,
+ const uint32_t aFlags = DEFAULT_BEHAVIOR) = 0;
+
+ /**
+ * If we have touch listeners, this should always be called when we know
+ * definitively whether or not content has preventDefaulted any touch events
+ * that have come in. If |aPreventDefault| is true, any touch events in the
+ * queue will be discarded. This function must be called on the controller
+ * thread.
+ */
+ virtual void ContentReceivedInputBlock(uint64_t aInputBlockId,
+ bool aPreventDefault) = 0;
+
+ /**
+ * When the event regions code is enabled, this function should be invoked to
+ * to confirm the target of the input block. This is only needed in cases
+ * where the initial input event of the block hit a dispatch-to-content region
+ * but is safe to call for all input blocks. This function should always be
+ * invoked on the controller thread.
+ * The different elements in the array of targets correspond to the targets
+ * for the different touch points. In the case where the touch point has no
+ * target, or the target is not a scrollable frame, the target's |mScrollId|
+ * should be set to ScrollableLayerGuid::NULL_SCROLL_ID.
+ */
+ virtual void SetTargetAPZC(uint64_t aInputBlockId,
+ const nsTArray<ScrollableLayerGuid>& aTargets) = 0;
+
+ /**
+ * Updates any zoom constraints contained in the <meta name="viewport"> tag.
+ * If the |aConstraints| is Nothing() then previously-provided constraints for
+ * the given |aGuid| are cleared.
+ */
+ virtual void UpdateZoomConstraints(
+ const ScrollableLayerGuid& aGuid,
+ const Maybe<ZoomConstraints>& aConstraints) = 0;
+
+ virtual void SetDPI(float aDpiValue) = 0;
+
+ /**
+ * Sets allowed touch behavior values for current touch-session for specific
+ * input block (determined by aInputBlock).
+ * Should be invoked by the widget. Each value of the aValues arrays
+ * corresponds to the different touch point that is currently active.
+ * Must be called after receiving the TOUCH_START event that starts the
+ * touch-session.
+ * This must be called on the controller thread.
+ */
+ virtual void SetAllowedTouchBehavior(
+ uint64_t aInputBlockId, const nsTArray<TouchBehaviorFlags>& aValues) = 0;
+
+ virtual void SetBrowserGestureResponse(uint64_t aInputBlockId,
+ BrowserGestureResponse aResponse) = 0;
+
+ virtual void StartScrollbarDrag(const ScrollableLayerGuid& aGuid,
+ const AsyncDragMetrics& aDragMetrics) = 0;
+
+ virtual bool StartAutoscroll(const ScrollableLayerGuid& aGuid,
+ const ScreenPoint& aAnchorLocation) = 0;
+
+ virtual void StopAutoscroll(const ScrollableLayerGuid& aGuid) = 0;
+
+ /**
+ * 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 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:
+ // Discourage destruction outside of decref
+
+ virtual ~IAPZCTreeManager() = default;
+};
+
+} // namespace layers
+} // namespace mozilla
+
+#endif // mozilla_layers_IAPZCTreeManager_h
diff --git a/gfx/layers/apz/public/MatrixMessage.h b/gfx/layers/apz/public/MatrixMessage.h
new file mode 100644
index 0000000000..45050f7406
--- /dev/null
+++ b/gfx/layers/apz/public/MatrixMessage.h
@@ -0,0 +1,64 @@
+/* -*- 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_MatrixMessage_h
+#define mozilla_layers_MatrixMessage_h
+
+#include "mozilla/Maybe.h"
+#include "mozilla/gfx/Matrix.h"
+#include "mozilla/layers/LayersTypes.h"
+#include "Units.h" // for ScreenRect
+#include "UnitTransforms.h"
+
+namespace mozilla {
+namespace layers {
+class MatrixMessage {
+ public:
+ // Don't use this one directly
+ MatrixMessage() = default;
+
+ MatrixMessage(const Maybe<LayerToScreenMatrix4x4>& aMatrix,
+ const ScreenRect& aTopLevelViewportVisibleRectInBrowserCoords,
+ const LayersId& aLayersId)
+ : mMatrix(ToUnknownMatrix(aMatrix)),
+ mTopLevelViewportVisibleRectInBrowserCoords(
+ aTopLevelViewportVisibleRectInBrowserCoords),
+ mLayersId(aLayersId) {}
+
+ inline Maybe<LayerToScreenMatrix4x4> GetMatrix() const {
+ return LayerToScreenMatrix4x4::FromUnknownMatrix(mMatrix);
+ }
+
+ inline ScreenRect GetTopLevelViewportVisibleRectInBrowserCoords() const {
+ return mTopLevelViewportVisibleRectInBrowserCoords;
+ }
+
+ inline const LayersId& GetLayersId() const { return mLayersId; }
+
+ bool operator==(const MatrixMessage& aOther) const {
+ return aOther.mMatrix == mMatrix &&
+ aOther.mTopLevelViewportVisibleRectInBrowserCoords ==
+ mTopLevelViewportVisibleRectInBrowserCoords &&
+ aOther.mLayersId == mLayersId;
+ }
+
+ bool operator!=(const MatrixMessage& aOther) const {
+ return !(*this == aOther);
+ }
+ // Fields are public for IPC. Don't access directly
+ // elsewhere.
+ // Transform matrix to convert this layer to screen coordinate.
+ Maybe<gfx::Matrix4x4> mMatrix; // Untyped for IPC
+ // The remote iframe document rectangle corresponding to this layer.
+ // The rectangle is the result of clipped out by ancestor async scrolling so
+ // that the rectangle will be empty if it's completely scrolled out of view.
+ ScreenRect mTopLevelViewportVisibleRectInBrowserCoords;
+ LayersId mLayersId;
+};
+}; // namespace layers
+}; // namespace mozilla
+
+#endif // mozilla_layers_MatrixMessage_h