tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AsyncPanZoomController.h (79917B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_layers_AsyncPanZoomController_h
      8 #define mozilla_layers_AsyncPanZoomController_h
      9 
     10 #include "Units.h"
     11 #include "apz/public/APZPublicUtils.h"
     12 #include "mozilla/layers/CompositorScrollUpdate.h"
     13 #include "mozilla/layers/GeckoContentController.h"
     14 #include "mozilla/layers/RepaintRequest.h"
     15 #include "mozilla/layers/SampleTime.h"
     16 #include "mozilla/layers/ScrollbarData.h"
     17 #include "mozilla/layers/ZoomConstraints.h"
     18 #include "mozilla/Atomics.h"
     19 #include "mozilla/Attributes.h"
     20 #include "mozilla/EventForwards.h"
     21 #include "mozilla/Monitor.h"
     22 #include "mozilla/RecursiveMutex.h"
     23 #include "mozilla/RefPtr.h"
     24 #include "mozilla/ScrollTypes.h"
     25 #include "mozilla/StaticPrefs_apz.h"
     26 #include "mozilla/UniquePtr.h"
     27 #include "InputData.h"
     28 #include "Axis.h"  // for Axis, Side, etc.
     29 #include "ExpectedGeckoMetrics.h"
     30 #include "FlingAccelerator.h"
     31 #include "InputQueue.h"
     32 #include "APZUtils.h"
     33 #include "LayersTypes.h"
     34 #include "mozilla/gfx/Matrix.h"
     35 #include "nsRegion.h"
     36 #include "nsTArray.h"
     37 #include "PotentialCheckerboardDurationTracker.h"
     38 #include "RecentEventsBuffer.h"  // for RecentEventsBuffer
     39 #include "SampledAPZCState.h"
     40 
     41 #include <iosfwd>
     42 
     43 namespace mozilla {
     44 
     45 namespace ipc {
     46 
     47 class SharedMemory;
     48 
     49 }  // namespace ipc
     50 
     51 namespace wr {
     52 struct MinimapData;
     53 struct SampledScrollOffset;
     54 }  // namespace wr
     55 
     56 namespace layers {
     57 
     58 class AsyncDragMetrics;
     59 class APZCTreeManager;
     60 struct ScrollableLayerGuid;
     61 class CompositorController;
     62 class GestureEventListener;
     63 struct AsyncTransform;
     64 class AsyncPanZoomAnimation;
     65 class StackScrollerFlingAnimation;
     66 template <typename FlingPhysics>
     67 class GenericFlingAnimation;
     68 class AndroidFlingPhysics;
     69 class DesktopFlingPhysics;
     70 class InputBlockState;
     71 struct FlingHandoffState;
     72 class TouchBlockState;
     73 class PanGestureBlockState;
     74 class OverscrollHandoffChain;
     75 struct OverscrollHandoffState;
     76 class StateChangeNotificationBlocker;
     77 class CheckerboardEvent;
     78 class OverscrollEffectBase;
     79 class WidgetOverscrollEffect;
     80 class GenericOverscrollEffect;
     81 class AndroidSpecificState;
     82 struct KeyboardScrollAction;
     83 struct ZoomTarget;
     84 
     85 namespace apz {
     86 struct AsyncScrollThumbTransformer;
     87 }
     88 
     89 // Base class for grouping platform-specific APZC state variables.
     90 class PlatformSpecificStateBase {
     91 public:
     92  virtual ~PlatformSpecificStateBase() = default;
     93  virtual AndroidSpecificState* AsAndroidSpecificState() { return nullptr; }
     94  // PLPPI = "ParentLayer pixels per (Screen) inch"
     95  virtual AsyncPanZoomAnimation* CreateFlingAnimation(
     96      AsyncPanZoomController& aApzc, const FlingHandoffState& aHandoffState,
     97      float aPLPPI);
     98  virtual UniquePtr<VelocityTracker> CreateVelocityTracker(Axis* aAxis);
     99 
    100  static void InitializeGlobalState() {}
    101 };
    102 
    103 /*
    104 * Represents a transform from the ParentLayer coordinate space of an APZC
    105 * to the ParentLayer coordinate space of its parent APZC.
    106 * Each layer along the way contributes to the transform. We track
    107 * contributions that are perspective transforms separately, as sometimes
    108 * these require special handling.
    109 */
    110 struct AncestorTransform {
    111  gfx::Matrix4x4 mTransform;
    112  gfx::Matrix4x4 mPerspectiveTransform;
    113 
    114  AncestorTransform() = default;
    115 
    116  AncestorTransform(const gfx::Matrix4x4& aTransform,
    117                    bool aTransformIsPerspective) {
    118    (aTransformIsPerspective ? mPerspectiveTransform : mTransform) = aTransform;
    119  }
    120 
    121  AncestorTransform(const gfx::Matrix4x4& aTransform,
    122                    const gfx::Matrix4x4& aPerspectiveTransform)
    123      : mTransform(aTransform), mPerspectiveTransform(aPerspectiveTransform) {}
    124 
    125  gfx::Matrix4x4 CombinedTransform() const {
    126    return mTransform * mPerspectiveTransform;
    127  }
    128 
    129  bool ContainsPerspectiveTransform() const {
    130    return !mPerspectiveTransform.IsIdentity();
    131  }
    132 
    133  gfx::Matrix4x4 GetPerspectiveTransform() const {
    134    return mPerspectiveTransform;
    135  }
    136 
    137  friend AncestorTransform operator*(const AncestorTransform& aA,
    138                                     const AncestorTransform& aB) {
    139    return AncestorTransform{
    140        aA.mTransform * aB.mTransform,
    141        aA.mPerspectiveTransform * aB.mPerspectiveTransform};
    142  }
    143 };
    144 
    145 // Flags returned by AsyncPanZoomController::ArePointerEventsConsumable().
    146 // See the function for more details.
    147 struct PointerEventsConsumableFlags {
    148  // The APZC has room to pan or zoom in response to the touch event.
    149  bool mHasRoom = false;
    150 
    151  // The panning or zooming is allowed by the touch-action property.
    152  bool mAllowedByTouchAction = false;
    153 
    154  bool IsConsumable() const { return mHasRoom && mAllowedByTouchAction; }
    155  friend bool operator==(const PointerEventsConsumableFlags& aLhs,
    156                         const PointerEventsConsumableFlags& aRhs);
    157  friend std::ostream& operator<<(std::ostream& aOut,
    158                                  const PointerEventsConsumableFlags& aFlags);
    159 };
    160 
    161 /**
    162 * Controller for all panning and zooming logic. Any time a user input is
    163 * detected and it must be processed in some way to affect what the user sees,
    164 * it goes through here. Listens for any input event from InputData and can
    165 * optionally handle WidgetGUIEvent-derived touch events, but this must be done
    166 * on the main thread. Note that this class completely cross-platform.
    167 *
    168 * Input events originate on the UI thread of the platform that this runs on,
    169 * and are then sent to this class. This class processes the event in some way;
    170 * for example, a touch move will usually lead to a panning of content (though
    171 * of course there are exceptions, such as if content preventDefaults the event,
    172 * or if the target frame is not scrollable). The compositor interacts with this
    173 * class by locking it and querying it for the current transform matrix based on
    174 * the panning and zooming logic that was invoked on the UI thread.
    175 *
    176 * Currently, each outer DOM window (i.e. a website in a tab, but not any
    177 * subframes) has its own AsyncPanZoomController. In the future, to support
    178 * asynchronously scrolled subframes, we want to have one AsyncPanZoomController
    179 * per frame.
    180 */
    181 class AsyncPanZoomController {
    182  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncPanZoomController)
    183 
    184  using MonitorAutoLock = mozilla::MonitorAutoLock;
    185  using Matrix4x4 = mozilla::gfx::Matrix4x4;
    186  using RepaintUpdateType =
    187      mozilla::layers::RepaintRequest::ScrollOffsetUpdateType;
    188  using ScrollAnimationKind = apz::ScrollAnimationKind;
    189 
    190 public:
    191  enum GestureBehavior {
    192    // The platform code is responsible for forwarding gesture events here. We
    193    // will not attempt to generate gesture events from MultiTouchInputs.
    194    DEFAULT_GESTURES,
    195    // An instance of GestureEventListener is used to detect gestures. This is
    196    // handled completely internally within this class.
    197    USE_GESTURE_DETECTOR
    198  };
    199 
    200  /**
    201   * Gets the DPI from the tree manager.
    202   */
    203  float GetDPI() const;
    204 
    205  /**
    206   * Constant describing the tolerance in distance we use, multiplied by the
    207   * device DPI, before we start panning the screen. This is to prevent us from
    208   * accidentally processing taps as touch moves, and from very short/accidental
    209   * touches moving the screen.
    210   * Note: It's an abuse of the 'Coord' class to use it to represent a 2D
    211   *       distance, but it's the closest thing we currently have.
    212   */
    213  ScreenCoord GetTouchStartTolerance() const;
    214  /**
    215   * Same as GetTouchStartTolerance, but the tolerance for how far the touch
    216   * has to move before it starts allowing touchmove events to be dispatched
    217   * to content, for non-scrollable content.
    218   */
    219  ScreenCoord GetTouchMoveTolerance() const;
    220  /**
    221   * Same as GetTouchStartTolerance, but the tolerance for how close the second
    222   * tap has to be to the first tap in order to be counted as part of a
    223   * multi-tap gesture (double-tap or one-touch-pinch).
    224   */
    225  ScreenCoord GetSecondTapTolerance() const;
    226 
    227  AsyncPanZoomController(LayersId aLayersId, APZCTreeManager* aTreeManager,
    228                         const RefPtr<InputQueue>& aInputQueue,
    229                         GeckoContentController* aController,
    230                         GestureBehavior aGestures = DEFAULT_GESTURES);
    231 
    232  // --------------------------------------------------------------------------
    233  // These methods must only be called on the gecko thread.
    234  //
    235 
    236  /**
    237   * Read the various prefs and do any global initialization for all APZC
    238   * instances. This must be run on the gecko thread before any APZC instances
    239   * are actually used for anything meaningful.
    240   */
    241  static void InitializeGlobalState();
    242 
    243  // --------------------------------------------------------------------------
    244  // These methods must only be called on the controller/UI thread.
    245  //
    246 
    247  /**
    248   * Kicks an animation to zoom to a rect. This may be either a zoom out or zoom
    249   * in. The actual animation is done on the sampler thread after being set
    250   * up.
    251   */
    252  void ZoomToRect(const ZoomTarget& aZoomTarget, const uint32_t aFlags);
    253 
    254  /**
    255   * Updates any zoom constraints contained in the <meta name="viewport"> tag.
    256   */
    257  void UpdateZoomConstraints(const ZoomConstraints& aConstraints);
    258 
    259  /**
    260   * Schedules a runnable to run on the controller/UI thread at some time
    261   * in the future.
    262   */
    263  void PostDelayedTask(already_AddRefed<Runnable> aTask, int aDelayMs);
    264 
    265  // --------------------------------------------------------------------------
    266  // These methods must only be called on the sampler thread.
    267  //
    268 
    269  /**
    270   * Advances any animations currently running to the given timestamp.
    271   * This may be called multiple times with the same timestamp.
    272   *
    273   * The return value indicates whether or not any currently running animation
    274   * should continue. If true, the compositor should schedule another composite.
    275   */
    276  bool AdvanceAnimations(const SampleTime& aSampleTime);
    277 
    278  bool UpdateAnimation(const RecursiveMutexAutoLock& aProofOfLock,
    279                       const SampleTime& aSampleTime,
    280                       nsTArray<RefPtr<Runnable>>* aOutDeferredTasks);
    281 
    282  // --------------------------------------------------------------------------
    283  // These methods must only be called on the updater thread.
    284  //
    285 
    286  struct LayersUpdateFlags {
    287    // Passed from the WebRender scroll data code indicating that the scroll
    288    // metadata being sent with this call are the initial metadata and the
    289    // initial paint of the frame has just happened.
    290    bool mIsFirstPaint : 1;
    291    // Whether this update was triggered by a paint for the LayersId (tab)
    292    // containing this scroll frame.
    293    bool mThisLayerTreeUpdated : 1;
    294  };
    295  /**
    296   * A WebRender scroll data has arrived. |aScrollMetdata| is the new
    297   * ScrollMetadata for the scroll container corresponding to this APZC.
    298   */
    299  void NotifyLayersUpdated(const ScrollMetadata& aScrollMetadata,
    300                           LayersUpdateFlags aLayersUpdateFlags);
    301 
    302  /**
    303   * The platform implementation must set the compositor controller so that we
    304   * can request composites.
    305   */
    306  void SetCompositorController(CompositorController* aCompositorController);
    307 
    308  // --------------------------------------------------------------------------
    309  // These methods can be called from any thread.
    310  //
    311 
    312  /**
    313   * Shut down the controller/UI thread state and prepare to be
    314   * deleted (which may happen from any thread).
    315   */
    316  void Destroy();
    317 
    318  /**
    319   * Returns true if Destroy() has already been called on this APZC instance.
    320   */
    321  bool IsDestroyed() const;
    322 
    323  /**
    324   * Returns the transform to take something from the coordinate space of the
    325   * last thing we know gecko painted, to the coordinate space of the last thing
    326   * we asked gecko to paint. In cases where that last request has not yet been
    327   * processed, this is needed to transform input events properly into a space
    328   * gecko will understand.
    329   *
    330   * This is meant to be called in the context of computing a chain of
    331   * transforms used for transforming event coordinates (specifically,
    332   * APZCTreeManager::GetApzcToGeckoTransform() and
    333   * HitTestingTreeNode::GetTransformToGecko()). The caller needs to pass
    334   * in |aForLayersId| the LayersId of the content for which the chain will be
    335   * used. If this content is in an out-of-process subdocument, the returned
    336   * transform includes the painted resolution transform (see bug 1827330 for
    337   * details).
    338   */
    339  Matrix4x4 GetTransformToLastDispatchedPaint(
    340      const AsyncTransformComponents& aComponents, LayersId aForLayersId) const;
    341 
    342  /**
    343   * Returns the number of CSS pixels of checkerboard according to the metrics
    344   * in this APZC. The argument provided by the caller is the composition bounds
    345   * of this APZC, additionally clipped by the composition bounds of any
    346   * ancestor APZCs, accounting for all the async transforms.
    347   */
    348  uint32_t GetCheckerboardMagnitude(
    349      const ParentLayerRect& aClippedCompositionBounds) const;
    350 
    351  /**
    352   * Report the number of CSSPixel-milliseconds of checkerboard to telemetry.
    353   * See GetCheckerboardMagnitude for documentation of the
    354   * aClippedCompositionBounds argument that needs to be provided by the caller.
    355   */
    356  void ReportCheckerboard(const SampleTime& aSampleTime,
    357                          const ParentLayerRect& aClippedCompositionBounds);
    358 
    359  /**
    360   * Flush any active checkerboard report that's in progress. This basically
    361   * pretends like any in-progress checkerboard event has terminated, and pushes
    362   * out the report to the checkerboard reporting service and telemetry. If the
    363   * checkerboard event has not really finished, it will start a new event
    364   * on the next composite.
    365   */
    366  void FlushActiveCheckerboardReport();
    367 
    368  /**
    369   * See documentation on corresponding method in APZPublicUtils.h
    370   */
    371  static gfx::Size GetDisplayportAlignmentMultiplier(
    372      const ScreenSize& aBaseSize);
    373 
    374  enum class ZoomInProgress {
    375    No,
    376    Yes,
    377  };
    378 
    379  /**
    380   * Enlarges the displayport along both axes based on the velocity.
    381   */
    382  static CSSSize CalculateDisplayPortSize(
    383      const CSSSize& aCompositionSize, const CSSPoint& aVelocity,
    384      AsyncPanZoomController::ZoomInProgress aZoomInProgress,
    385      const CSSToScreenScale2D& aDpPerCSS);
    386 
    387  /**
    388   * Recalculates the displayport. Ideally, this should paint an area bigger
    389   * than the composite-to dimensions so that when you scroll down, you don't
    390   * checkerboard immediately. This includes a bunch of logic, including
    391   * algorithms to bias painting in the direction of the velocity and other
    392   * such things.
    393   */
    394  static const ScreenMargin CalculatePendingDisplayPort(
    395      const FrameMetrics& aFrameMetrics, const ParentLayerPoint& aVelocity,
    396      ZoomInProgress aZoomInProgress);
    397 
    398  nsEventStatus HandleDragEvent(const MouseInput& aEvent,
    399                                const AsyncDragMetrics& aDragMetrics,
    400                                OuterCSSCoord aInitialThumbPos,
    401                                const CSSRect& aInitialScrollableRect);
    402 
    403  /**
    404   * Handler for events which should not be intercepted by the touch listener.
    405   */
    406  nsEventStatus HandleInputEvent(
    407      const InputData& aEvent,
    408      const ScreenToParentLayerMatrix4x4& aTransformToApzc);
    409 
    410  /**
    411   * Handler for gesture events.
    412   * Currently some gestures are detected in GestureEventListener that calls
    413   * APZC back through this handler in order to avoid recursive calls to
    414   * APZC::HandleInputEvent() which is supposed to do the work for
    415   * ReceiveInputEvent().
    416   */
    417  nsEventStatus HandleGestureEvent(const InputData& aEvent);
    418 
    419  /**
    420   * Start autoscrolling this APZC, anchored at the provided location.
    421   */
    422  void StartAutoscroll(const ScreenPoint& aAnchorLocation);
    423 
    424  /**
    425   * Stop autoscrolling this APZC.
    426   */
    427  void StopAutoscroll();
    428 
    429  /**
    430   * Populates the provided object (if non-null) with the scrollable guid of
    431   * this apzc.
    432   */
    433  void GetGuid(ScrollableLayerGuid* aGuidOut) const;
    434 
    435  /**
    436   * Returns the scrollable guid of this apzc.
    437   */
    438  ScrollableLayerGuid GetGuid() const;
    439 
    440  /**
    441   * Returns true if this APZC instance is for the layer identified by the guid.
    442   */
    443  bool Matches(const ScrollableLayerGuid& aGuid);
    444 
    445  /**
    446   * Returns true if the tree manager of this APZC is the same as the one
    447   * passed in.
    448   */
    449  bool HasTreeManager(const APZCTreeManager* aTreeManager) const;
    450 
    451  void StartAnimation(already_AddRefed<AsyncPanZoomAnimation> aAnimation);
    452 
    453  /**
    454   * Cancels any currently running animation.
    455   * aFlags is a bit-field to provide specifics of how to cancel the animation.
    456   * See CancelAnimationFlags.
    457   */
    458  void CancelAnimation(CancelAnimationFlags aFlags = Default);
    459 
    460  /**
    461   * Clear any overscroll on this APZC.
    462   */
    463  void ClearOverscroll();
    464  void ClearPhysicalOverscroll();
    465 
    466  /**
    467   * Returns whether this APZC has scroll snap points.
    468   */
    469  bool HasScrollSnapping() const {
    470    return mScrollMetadata.GetSnapInfo().HasScrollSnapping();
    471  }
    472 
    473  /**
    474   * Returns whether this APZC has room to be panned (in any direction).
    475   */
    476  bool IsPannable() const;
    477 
    478  /**
    479   * Returns whether this APZC represents a scroll info layer.
    480   */
    481  bool IsScrollInfoLayer() const;
    482 
    483  /**
    484   * Returns true if the APZC has been flung with a velocity greater than the
    485   * stop-on-tap fling velocity threshold (which is pref-controlled).
    486   */
    487  bool IsFlingingFast() const;
    488 
    489  /**
    490   * Returns whether this APZC is currently autoscrolling.
    491   */
    492  bool IsAutoscroll() const {
    493    RecursiveMutexAutoLock lock(mRecursiveMutex);
    494    return mState == AUTOSCROLL;
    495  }
    496 
    497  /**
    498   * Returns the identifier of the touch in the last touch event processed by
    499   * this APZC. This should only be called when the last touch event contained
    500   * only one touch.
    501   */
    502  int32_t GetLastTouchIdentifier() const;
    503 
    504  /**
    505   * Returns the matrix that transforms points from global screen space into
    506   * this APZC's ParentLayer space.
    507   * To respect the lock ordering, mRecursiveMutex must NOT be held when calling
    508   * this function (since this function acquires the tree lock).
    509   */
    510  ScreenToParentLayerMatrix4x4 GetTransformToThis() const;
    511 
    512  /**
    513   * Convert the vector |aVector|, rooted at the point |aAnchor|, from
    514   * this APZC's ParentLayer coordinates into screen coordinates.
    515   * The anchor is necessary because with 3D tranforms, the location of the
    516   * vector can affect the result of the transform.
    517   * To respect the lock ordering, mRecursiveMutex must NOT be held when calling
    518   * this function (since this function acquires the tree lock).
    519   */
    520  ScreenPoint ToScreenCoordinates(const ParentLayerPoint& aVector,
    521                                  const ParentLayerPoint& aAnchor) const;
    522 
    523  /**
    524   * Convert the vector |aVector|, rooted at the point |aAnchor|, from
    525   * screen coordinates into this APZC's ParentLayer coordinates.
    526   * The anchor is necessary because with 3D tranforms, the location of the
    527   * vector can affect the result of the transform.
    528   * To respect the lock ordering, mRecursiveMutex must NOT be held when calling
    529   * this function (since this function acquires the tree lock).
    530   */
    531  ParentLayerPoint ToParentLayerCoordinates(const ScreenPoint& aVector,
    532                                            const ScreenPoint& aAnchor) const;
    533 
    534  /**
    535   * Same as above, but uses an ExternalPoint as the anchor.
    536   */
    537  ParentLayerPoint ToParentLayerCoordinates(const ScreenPoint& aVector,
    538                                            const ExternalPoint& aAnchor) const;
    539 
    540  /**
    541   * Combines an offset defined as an external point, with a window-relative
    542   * offset to give an absolute external point.
    543   */
    544  static ExternalPoint ToExternalPoint(const ExternalPoint& aScreenOffset,
    545                                       const ScreenPoint& aScreenPoint);
    546 
    547  /**
    548   * Gets a vector where the head is the given point, and the tail is
    549   * the touch start position.
    550   */
    551  ScreenPoint PanVector(const ExternalPoint& aPos) const;
    552 
    553  // Return whether or not a wheel event will be able to scroll in either
    554  // direction.
    555  bool CanScroll(const InputData& aEvent) const;
    556 
    557  // Return the directions in which this APZC allows handoff (as governed by
    558  // overscroll-behavior).
    559  ScrollDirections GetAllowedHandoffDirections(
    560      HandoffConsumer aConsumer = HandoffConsumer::Scrolling) const;
    561 
    562  // Return the directions in which this APZC allows overscrolling.
    563  ScrollDirections GetOverscrollableDirections() const;
    564 
    565  // Return whether or not a scroll delta will be able to scroll in either
    566  // direction.
    567  bool CanScroll(const ParentLayerPoint& aDelta) const;
    568 
    569  // Return whether or not a scroll delta will be able to scroll in either
    570  // direction with wheel.
    571  bool CanScrollWithWheel(const ParentLayerPoint& aDelta) const;
    572 
    573  // Return whether or not there is room to scroll this APZC
    574  // in the given direction.
    575  bool CanScroll(ScrollDirection aDirection) const;
    576 
    577  // Return the directions in which this APZC is able to scroll.
    578  SideBits ScrollableDirections() const;
    579 
    580  // Return true if there is room to scroll along with moving the dynamic
    581  // toolbar.
    582  //
    583  // NOTE: This function should be used only for the root content APZC.
    584  bool CanVerticalScrollWithDynamicToolbar() const;
    585 
    586  // Return true if there is room to scroll downwards.
    587  bool CanScrollDownwards() const;
    588 
    589  // Return true if there is room to scroll upwards.
    590  bool CanOverscrollUpwards(
    591      HandoffConsumer aConsumer = HandoffConsumer::Scrolling) const;
    592 
    593  /**
    594   * Convert a point on the scrollbar from this APZC's ParentLayer coordinates
    595   * to OuterCSS coordinates relative to the beginning of the scroll track.
    596   * Only the component in the direction of scrolling is returned.
    597   */
    598  OuterCSSCoord ConvertScrollbarPoint(const ParentLayerPoint& aScrollbarPoint,
    599                                      const ScrollbarData& aThumbData) const;
    600 
    601  void NotifyMozMouseScrollEvent(const nsString& aString) const;
    602 
    603  bool OverscrollBehaviorAllowsSwipe() const;
    604 
    605  //|Metrics()| and |Metrics() const| are getter functions that both return
    606  // mScrollMetadata.mMetrics
    607 
    608  const FrameMetrics& Metrics() const;
    609  FrameMetrics& Metrics();
    610 
    611  class AutoRecordCompositorScrollUpdate;
    612  /**
    613   * Get the CompositorScrollUpdates to be sent to consumers for the current
    614   * composite.
    615   */
    616  std::vector<CompositorScrollUpdate> GetCompositorScrollUpdates();
    617 
    618 private:
    619  // Compositor scroll updates since the last time
    620  // SampleCompositedAsyncTransform() was called.
    621  // Access to this field should be protected by mRecursiveMutex.
    622  std::vector<CompositorScrollUpdate> mUpdatesSinceLastSample;
    623 
    624  CompositorScrollUpdate::Metrics GetCurrentMetricsForCompositorScrollUpdate(
    625      const RecursiveMutexAutoLock& aProofOfApzcLock) const;
    626 
    627 public:
    628  wr::MinimapData GetMinimapData() const;
    629 
    630  // Returns the cached current frame time.
    631  SampleTime GetFrameTime() const;
    632 
    633  bool IsZero(const ParentLayerPoint& aPoint) const;
    634  bool IsZero(ParentLayerCoord aCoord) const;
    635 
    636  bool FuzzyGreater(ParentLayerCoord aCoord1, ParentLayerCoord aCoord2) const;
    637 
    638 private:
    639  // Get whether the horizontal content of the honoured target of auto-dir
    640  // scrolling starts from right to left. If you don't know of auto-dir
    641  // scrolling or what a honoured target means,
    642  // @see mozilla::WheelDeltaAdjustmentStrategy
    643  bool IsContentOfHonouredTargetRightToLeft(bool aHonoursRoot) const;
    644 
    645 protected:
    646  // Protected destructor, to discourage deletion outside of Release():
    647  virtual ~AsyncPanZoomController();
    648 
    649  /**
    650   * Helper method for touches beginning. Sets everything up for panning and any
    651   * multitouch gestures.
    652   */
    653  nsEventStatus OnTouchStart(const MultiTouchInput& aEvent);
    654 
    655  /**
    656   * Helper method for touches moving. Does any transforms needed when panning.
    657   */
    658  nsEventStatus OnTouchMove(const MultiTouchInput& aEvent);
    659 
    660  /**
    661   * Helper method for touches ending. Redraws the screen if necessary and does
    662   * any cleanup after a touch has ended.
    663   */
    664  nsEventStatus OnTouchEnd(const MultiTouchInput& aEvent);
    665 
    666  /**
    667   * Helper method for touches being cancelled. Treated roughly the same as a
    668   * touch ending (OnTouchEnd()).
    669   */
    670  nsEventStatus OnTouchCancel(const MultiTouchInput& aEvent);
    671 
    672  /**
    673   * Helper method for scales beginning. Distinct from the OnTouch* handlers in
    674   * that this implies some outside implementation has determined that the user
    675   * is pinching.
    676   */
    677  nsEventStatus OnScaleBegin(const PinchGestureInput& aEvent);
    678 
    679  /**
    680   * Helper method for scaling. As the user moves their fingers when pinching,
    681   * this changes the scale of the page.
    682   */
    683  nsEventStatus OnScale(const PinchGestureInput& aEvent);
    684 
    685  /**
    686   * Helper method for scales ending. Redraws the screen if necessary and does
    687   * any cleanup after a scale has ended.
    688   */
    689  nsEventStatus OnScaleEnd(const PinchGestureInput& aEvent);
    690 
    691  /**
    692   * Helper methods for handling pan events.
    693   */
    694  nsEventStatus OnPanMayBegin(const PanGestureInput& aEvent);
    695  nsEventStatus OnPanCancelled(const PanGestureInput& aEvent);
    696  nsEventStatus OnPanBegin(const PanGestureInput& aEvent);
    697  enum class FingersOnTouchpad {
    698    Yes,
    699    No,
    700  };
    701  nsEventStatus OnPan(const PanGestureInput& aEvent,
    702                      FingersOnTouchpad aFingersOnTouchpad);
    703  nsEventStatus OnPanEnd(const PanGestureInput& aEvent);
    704  nsEventStatus OnPanMomentumStart(const PanGestureInput& aEvent);
    705  nsEventStatus OnPanMomentumEnd(const PanGestureInput& aEvent);
    706  nsEventStatus HandleEndOfPan();
    707  nsEventStatus OnPanInterrupted(const PanGestureInput& aEvent);
    708 
    709  /**
    710   * Helper methods for handling scroll wheel events.
    711   */
    712  nsEventStatus OnScrollWheel(const ScrollWheelInput& aEvent);
    713 
    714  /**
    715   * Gets the scroll wheel delta's values in parent-layer pixels from the
    716   * original delta's values of a wheel input.
    717   */
    718  ParentLayerPoint GetScrollWheelDelta(const ScrollWheelInput& aEvent) const;
    719 
    720  /**
    721   * This function is like GetScrollWheelDelta(aEvent).
    722   * The difference is the four added parameters provide values as alternatives
    723   * to the original wheel input's delta values, so |aEvent|'s delta values are
    724   * ignored in this function, we only use some other member variables and
    725   * functions of |aEvent|.
    726   */
    727  ParentLayerPoint GetScrollWheelDelta(const ScrollWheelInput& aEvent,
    728                                       double aDeltaX, double aDeltaY,
    729                                       double aMultiplierX,
    730                                       double aMultiplierY) const;
    731 
    732  /**
    733   * This deleted function is used for:
    734   * 1. avoiding accidental implicit value type conversions of input delta
    735   *    values when callers intend to call the above function;
    736   * 2. decoupling the manual relationship between the delta value type and the
    737   *    above function. If by any chance the defined delta value type in
    738   *    ScrollWheelInput has changed, this will automatically result in build
    739   *    time failure, so we can learn of it the first time and accordingly
    740   *    redefine those parameters' value types in the above function.
    741   */
    742  template <typename T>
    743  ParentLayerPoint GetScrollWheelDelta(ScrollWheelInput&, T, T, T, T) = delete;
    744 
    745  /**
    746   * Helper methods for handling keyboard events.
    747   */
    748  nsEventStatus OnKeyboard(const KeyboardInput& aEvent);
    749 
    750  CSSPoint GetKeyboardDestination(const KeyboardScrollAction& aAction) const;
    751 
    752  // Returns the corresponding ScrollSnapFlags for the given |aAction|.
    753  // See https://drafts.csswg.org/css-scroll-snap/#scroll-types
    754  ScrollSnapFlags GetScrollSnapFlagsForKeyboardAction(
    755      const KeyboardScrollAction& aAction) const;
    756 
    757  /**
    758   * Helper methods for long press gestures.
    759   */
    760  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    761  nsEventStatus OnLongPress(const TapGestureInput& aEvent);
    762  nsEventStatus OnLongPressUp(const TapGestureInput& aEvent);
    763 
    764  /**
    765   * Helper method for single tap gestures.
    766   */
    767  nsEventStatus OnSingleTapUp(const TapGestureInput& aEvent);
    768 
    769  /**
    770   * Helper method for a single tap confirmed.
    771   */
    772  nsEventStatus OnSingleTapConfirmed(const TapGestureInput& aEvent);
    773 
    774  /**
    775   * Helper method for double taps.
    776   */
    777  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    778  nsEventStatus OnDoubleTap(const TapGestureInput& aEvent);
    779 
    780  /**
    781   * Helper method for double taps where the double-tap gesture is disabled.
    782   */
    783  nsEventStatus OnSecondTap(const TapGestureInput& aEvent);
    784 
    785  /**
    786   * Helper method to cancel any gesture currently going to Gecko. Used
    787   * primarily when a user taps the screen over some clickable content but then
    788   * pans down instead of letting go (i.e. to cancel a previous touch so that a
    789   * new one can properly take effect.
    790   */
    791  nsEventStatus OnCancelTap(const TapGestureInput& aEvent);
    792 
    793  /**
    794   * The following five methods modify the scroll offset. For the APZC
    795   * representing the RCD-RSF, they also recalculate the offset of the layout
    796   * viewport.
    797   */
    798 
    799  /**
    800   * Scroll the scroll frame to an X,Y offset.
    801   */
    802  void SetVisualScrollOffset(const CSSPoint& aOffset);
    803 
    804  /**
    805   * Scroll the scroll frame to an X,Y offset, clamping the resulting scroll
    806   * offset to the scroll range.
    807   */
    808  void ClampAndSetVisualScrollOffset(const CSSPoint& aOffset);
    809 
    810  /**
    811   * Scroll the scroll frame by an X,Y offset.
    812   * The resulting scroll offset is not clamped to the scrollable rect;
    813   * the caller must ensure it stays within range.
    814   */
    815  void ScrollBy(const CSSPoint& aOffset);
    816 
    817  /**
    818   * Scroll the scroll frame by an X,Y offset, clamping the resulting
    819   * scroll offset to the scroll range.
    820   */
    821  void ScrollByAndClamp(const CSSPoint& aOffset);
    822 
    823  /**
    824   * A variant of ScrollByAndClamp() that can scroll either the visual
    825   * or the layout viewport.
    826   */
    827  void ScrollByAndClamp(ViewportType aViewportToScroll,
    828                        const CSSPoint& aOffset);
    829 
    830  /**
    831   * Similar to ScrollByAndClamp() but scrolls to a specified destination.
    832   * Can also be thought of as a variant of ClampAndSetVisualScrollOffset()
    833   * which can set either the layout or viewport viewport offse.
    834   */
    835  void ScrollToAndClamp(ViewportType aViewportToScroll,
    836                        const CSSPoint& aDestination);
    837 
    838  /**
    839   * Scales the viewport by an amount (note that it multiplies this scale in to
    840   * the current scale, it doesn't set it to |aScale|). Also considers a focus
    841   * point so that the page zooms inward/outward from that point.
    842   */
    843  void ScaleWithFocus(float aScale, const CSSPoint& aFocus);
    844 
    845  /**
    846   * Schedules a composite on the compositor thread.
    847   */
    848  void ScheduleComposite();
    849 
    850  /**
    851   * Schedules a composite, and if enough time has elapsed since the last
    852   * paint, a paint.
    853   */
    854  void ScheduleCompositeAndMaybeRepaint();
    855 
    856  /**
    857   * Gets the start point of the current touch.
    858   * This only makes sense if a touch is currently happening and OnTouchMove()
    859   * or the equivalent for pan gestures is being invoked.
    860   */
    861  ParentLayerPoint PanStart() const;
    862 
    863  /**
    864   * Gets a vector of the velocities of each axis.
    865   */
    866  const ParentLayerPoint GetVelocityVector() const;
    867 
    868  /**
    869   * Sets the velocities of each axis.
    870   */
    871  void SetVelocityVector(const ParentLayerPoint& aVelocityVector);
    872 
    873  /**
    874   * Gets the first touch point from a MultiTouchInput.  This gets only
    875   * the first one and assumes the rest are either missing or not relevant.
    876   */
    877  ParentLayerPoint GetFirstTouchPoint(const MultiTouchInput& aEvent);
    878 
    879  /**
    880   * Gets the relevant point in the event
    881   * (eg. first touch, or pinch focus point) of the given InputData.
    882   */
    883  ExternalPoint GetExternalPoint(const InputData& aEvent);
    884 
    885  /**
    886   * Gets the relevant point in the event, in external screen coordinates.
    887   */
    888  static ExternalPoint GetFirstExternalTouchPoint(
    889      const MultiTouchInput& aEvent);
    890 
    891  /**
    892   * Gets the amount by which this APZC is overscrolled along both axes.
    893   */
    894  ParentLayerPoint GetOverscrollAmount() const;
    895 
    896 private:
    897  // Internal version of GetOverscrollAmount() which does not set
    898  // the test async properties.
    899  ParentLayerPoint GetOverscrollAmountInternal() const;
    900 
    901  // Return whether this APZC blocks pull-to-refresh.
    902  bool BlocksPullToRefreshForOverflowHidden() const;
    903 
    904 protected:
    905  /**
    906   * Returns SideBits where this APZC is overscrolled.
    907   */
    908  SideBits GetOverscrollSideBits() const;
    909 
    910  /**
    911   * Restore the amount by which this APZC is overscrolled along both axes
    912   * to the specified amount. This is for test-related use; overscrolling
    913   * as a result of user input should happen via OverscrollBy().
    914   */
    915  void RestoreOverscrollAmount(const ParentLayerPoint& aOverscroll);
    916 
    917  /**
    918   * Sets the panning state basing on the pan direction angle and current
    919   * touch-action value.
    920   */
    921  void HandlePanningWithTouchAction(double angle);
    922 
    923  /**
    924   * Sets the panning state ignoring the touch action value.
    925   */
    926  void HandlePanning(double angle);
    927 
    928  /**
    929   * Update the panning state and axis locks.
    930   */
    931  void HandlePanningUpdate(const ScreenPoint& aDelta);
    932 
    933  /**
    934   * Set and update the pinch lock
    935   */
    936  void HandlePinchLocking(const PinchGestureInput& aEvent);
    937 
    938  /**
    939   * Sets up anything needed for panning. This takes us out of the "TOUCHING"
    940   * state and starts actually panning us. We provide the physical pixel
    941   * position of the start point so that the pan gesture is calculated
    942   * regardless of if the window/GeckoView moved during the pan.
    943   */
    944  nsEventStatus StartPanning(const ExternalPoint& aStartPoint,
    945                             const TimeStamp& aEventTime);
    946 
    947  /**
    948   * Wrapper for Axis::UpdateWithTouchAtDevicePoint(). Calls this function for
    949   * both axes and factors in the time delta from the last update.
    950   */
    951  void UpdateWithTouchAtDevicePoint(const MultiTouchInput& aEvent);
    952 
    953  /**
    954   * Does any panning required due to a new touch event.
    955   */
    956  void TrackTouch(const MultiTouchInput& aEvent);
    957 
    958  /**
    959   * Register the start of a touch or pan gesture at the given position and
    960   * time.
    961   */
    962  void StartTouch(const ParentLayerPoint& aPoint, TimeStamp aTimestamp);
    963 
    964  /**
    965   * Register the end of a touch or pan gesture at the given time.
    966   */
    967  void EndTouch(TimeStamp aTimestamp, Axis::ClearAxisLock aClearAxisLock);
    968 
    969  /**
    970   * Utility function to send updated FrameMetrics to Gecko so that it can paint
    971   * the displayport area. Calls into GeckoContentController to do the actual
    972   * work. This call will use the current metrics. If this function is called
    973   * from a non-main thread, it will redispatch itself to the main thread, and
    974   * use the latest metrics during the redispatch.
    975   */
    976  void RequestContentRepaint(
    977      RepaintUpdateType aUpdateType = RepaintUpdateType::eUserAction);
    978 
    979  /**
    980   * Send Metrics() to Gecko to trigger a repaint. This function may filter
    981   * duplicate calls with the same metrics. This function must be called on the
    982   * main thread.
    983   */
    984  void RequestContentRepaint(const ParentLayerPoint& aVelocity,
    985                             const ScreenMargin& aDisplayportMargins,
    986                             RepaintUpdateType aUpdateType);
    987 
    988  /**
    989   * Gets the current frame metrics. This is *not* the Gecko copy stored in the
    990   * layers code.
    991   */
    992  const FrameMetrics& GetFrameMetrics() const;
    993 
    994  /**
    995   * Gets the current scroll metadata. This is *not* the Gecko copy stored in
    996   * the layers code/
    997   */
    998  const ScrollMetadata& GetScrollMetadata() const;
    999 
   1000  /**
   1001   * Gets the pointer to the apzc tree manager. All the access to tree manager
   1002   * should be made via this method and not via private variable since this
   1003   * method ensures that no lock is set.
   1004   */
   1005  APZCTreeManager* GetApzcTreeManager() const;
   1006 
   1007  void AssertOnSamplerThread() const;
   1008  void AssertOnUpdaterThread() const;
   1009 
   1010  /**
   1011   * Convert ScreenPoint relative to the screen to LayoutDevicePoint relative
   1012   * to the parent document. This excludes the transient compositor transform.
   1013   * NOTE: This must be converted to LayoutDevicePoint relative to the child
   1014   * document before sending over IPC to a child process.
   1015   */
   1016  Maybe<LayoutDevicePoint> ConvertToGecko(const ScreenIntPoint& aPoint);
   1017 
   1018  enum class AxisLockMode {
   1019    FREE,     /* No locking at all */
   1020    STANDARD, /* Default axis locking mode that remains locked until pan ends */
   1021    STICKY,   /* Allow lock to be broken, with hysteresis */
   1022    DOMINANT_AXIS, /* Only allow movement on one axis */
   1023    BREAKABLE,     /* Allow lock to be broken until the pan ends */
   1024  };
   1025 
   1026  static AxisLockMode GetAxisLockMode();
   1027 
   1028  bool UsingStatefulAxisLock() const;
   1029 
   1030  enum PinchLockMode {
   1031    PINCH_FREE,     /* No locking at all */
   1032    PINCH_STANDARD, /* Default pinch locking mode that remains locked until
   1033                       pinch gesture ends*/
   1034    PINCH_STICKY,   /* Allow lock to be broken, with hysteresis */
   1035  };
   1036 
   1037  static PinchLockMode GetPinchLockMode();
   1038 
   1039  // Helper function for OnSingleTapUp(), OnSingleTapConfirmed(), and
   1040  // OnLongPressUp().
   1041  nsEventStatus GenerateSingleTap(GeckoContentController::TapType aType,
   1042                                  const ScreenIntPoint& aPoint,
   1043                                  mozilla::Modifiers aModifiers);
   1044 
   1045  // Common processing at the end of a touch block.
   1046  void OnTouchEndOrCancel();
   1047 
   1048  LayersId mLayersId;
   1049  RefPtr<CompositorController> mCompositorController;
   1050 
   1051  /* Access to the following two fields is protected by the mRefPtrMonitor,
   1052     since they are accessed on the UI thread but can be cleared on the
   1053     updater thread. */
   1054  RefPtr<GeckoContentController> mGeckoContentController
   1055      MOZ_GUARDED_BY(mRefPtrMonitor);
   1056  RefPtr<GestureEventListener> mGestureEventListener
   1057      MOZ_GUARDED_BY(mRefPtrMonitor);
   1058  mutable Monitor mRefPtrMonitor;
   1059 
   1060  // This is a raw pointer to avoid introducing a reference cycle between
   1061  // AsyncPanZoomController and APZCTreeManager. Since these objects don't
   1062  // live on the main thread, we can't use the cycle collector with them.
   1063  // The APZCTreeManager owns the lifetime of the APZCs, so nulling this
   1064  // pointer out in Destroy() will prevent accessing deleted memory.
   1065  Atomic<APZCTreeManager*> mTreeManager;
   1066 
   1067  /* Utility functions that return a addrefed pointer to the corresponding
   1068   * fields. */
   1069  already_AddRefed<GeckoContentController> GetGeckoContentController() const;
   1070  already_AddRefed<GestureEventListener> GetGestureEventListener() const;
   1071 
   1072  PlatformSpecificStateBase* GetPlatformSpecificState();
   1073 
   1074  /**
   1075   * Convenience functions to get the corresponding fields of mZoomContraints
   1076   * while holding mRecursiveMutex.
   1077   */
   1078  bool ZoomConstraintsAllowZoom() const;
   1079  bool ZoomConstraintsAllowDoubleTapZoom() const;
   1080 
   1081 protected:
   1082  // Both |mScrollMetadata| and |mLastContentPaintMetrics| are protected by the
   1083  // monitor. Do not read from or modify them without locking.
   1084  ScrollMetadata mScrollMetadata;
   1085 
   1086  // Protects |mScrollMetadata|, |mLastContentPaintMetrics|, |mState| and
   1087  // |mLastSnapTargetIds|.  Before manipulating |mScrollMetadata|,
   1088  // |mLastContentPaintMetrics| or |mLastSnapTargetIds| the monitor should be
   1089  // held. When setting |mState|, either the SetState() function can be used, or
   1090  // the monitor can be held and then |mState| updated.
   1091  // IMPORTANT: See the note about lock ordering at the top of
   1092  // APZCTreeManager.h. This is mutable to allow entering it from 'const'
   1093  // methods; doing otherwise would significantly limit what methods could be
   1094  // 'const'.
   1095  // FIXME: Please keep in mind that due to some existing coupled relationships
   1096  // among the class members, we should be aware of indirect usage of the
   1097  // monitor-protected members. That is, although this monitor isn't required to
   1098  // be held before manipulating non-protected class members, some functions on
   1099  // those members might indirectly manipulate the protected members; in such
   1100  // cases, the monitor should still be held. Let's take mX.CanScroll for
   1101  // example:
   1102  // Axis::CanScroll(ParentLayerCoord) calls Axis::CanScroll() which calls
   1103  // Axis::GetPageLength() which calls Axis::GetFrameMetrics() which calls
   1104  // AsyncPanZoomController::GetFrameMetrics(), therefore, this monitor should
   1105  // be held before calling the CanScroll function of |mX| and |mY|. These
   1106  // coupled relationships bring us the burden of taking care of when the
   1107  // monitor should be held, so they should be decoupled in the future.
   1108  mutable RecursiveMutex mRecursiveMutex;
   1109 
   1110 private:
   1111  // Metadata of the container layer corresponding to this APZC. This is
   1112  // stored here so that it is accessible from the UI/controller thread.
   1113  // These are the metrics at last content paint, the most recent
   1114  // values we were notified of in NotifyLayersUpdate(). Since it represents
   1115  // the Gecko state, it should be used as a basis for untransformation when
   1116  // sending messages back to Gecko.
   1117  ScrollMetadata mLastContentPaintMetadata;
   1118  FrameMetrics& mLastContentPaintMetrics;  // for convenience, refers to
   1119                                           // mLastContentPaintMetadata.mMetrics
   1120  // The last content repaint request.
   1121  RepaintRequest mLastPaintRequestMetrics;
   1122  // The metrics that we expect content to have. This is updated when we
   1123  // request a content repaint, and when we receive a shadow layers update.
   1124  // This allows us to transform events into Gecko's coordinate space.
   1125  ExpectedGeckoMetrics mExpectedGeckoMetrics;
   1126 
   1127  // This holds important state from the Metrics() at previous times
   1128  // SampleCompositedAsyncTransform() was called. This will always have at least
   1129  // one item. mRecursiveMutex must be held when using or modifying this member.
   1130  // Samples should be inserted to the "back" of the deque and extracted from
   1131  // the "front".
   1132  std::deque<SampledAPZCState> mSampledState;
   1133 
   1134  // Groups state variables that are specific to a platform.
   1135  // Initialized on first use.
   1136  UniquePtr<PlatformSpecificStateBase> mPlatformSpecificState;
   1137 
   1138  // This flag is set to true when we are in a axis-locked pan as a result of
   1139  // the touch-action CSS property.
   1140  bool mPanDirRestricted;
   1141 
   1142  // This flag is set to true when we are in a pinch-locked state. ie: user
   1143  // is performing a two-finger pan rather than a pinch gesture
   1144  bool mPinchLocked;
   1145 
   1146  // Stores the pinch events that occured within a given timeframe. Used to
   1147  // calculate the focusChange and spanDistance within a fixed timeframe.
   1148  // RecentEventsBuffer is not threadsafe. Should only be accessed on the
   1149  // controller thread.
   1150  RecentEventsBuffer<PinchGestureInput> mPinchEventBuffer;
   1151 
   1152  // Stores the touch events that occured within a given timeframe. Ussed to
   1153  // determine the direction of a touch scroll, which determines which axis
   1154  // should be locked if STICKY axis locking is used. Should only by accessed
   1155  // on the controller thread.
   1156  RecentEventsBuffer<MultiTouchInput> mTouchScrollEventBuffer;
   1157 
   1158  // Most up-to-date constraints on zooming. These should always be reasonable
   1159  // values; for example, allowing a min zoom of 0.0 can cause very bad things
   1160  // to happen. Hold mRecursiveMutex when accessing this.
   1161  ZoomConstraints mZoomConstraints;
   1162 
   1163  // The last time the compositor has sampled the content transform for this
   1164  // frame.
   1165  SampleTime mLastSampleTime;
   1166 
   1167  // The last sample time at which we submitted a checkerboarding report.
   1168  SampleTime mLastCheckerboardReport;
   1169 
   1170  // Stores the previous focus point if there is a pinch gesture happening. Used
   1171  // to allow panning by moving multiple fingers (thus moving the focus point).
   1172  ParentLayerPoint mLastZoomFocus;
   1173 
   1174  // Stores the previous zoom level at which we last sent a ScaleGestureComplete
   1175  // notification.
   1176  CSSToParentLayerScale mLastNotifiedZoom;
   1177 
   1178  // Accessing mAnimation needs to be protected by mRecursiveMutex
   1179  RefPtr<AsyncPanZoomAnimation> mAnimation;
   1180 
   1181  UniquePtr<OverscrollEffectBase> mOverscrollEffect;
   1182 
   1183  // Zoom animation id, used for zooming. This should only be set on the APZC
   1184  // instance for the root content document (i.e. the one we support zooming
   1185  // on). The animation id itself refers to the transform animation id that was
   1186  // set on the stacking context in the WR display list. By changing the
   1187  // transform associated with this id, we can adjust the scaling that WebRender
   1188  // applies, thereby controlling the zoom.
   1189  Maybe<uint64_t> mZoomAnimationId;
   1190 
   1191  // Position on screen where user first put their finger down.
   1192  ExternalPoint mStartTouch;
   1193 
   1194  // Accessing mScrollPayload needs to be protected by mRecursiveMutex
   1195  Maybe<CompositionPayload> mScrollPayload;
   1196 
   1197  // Representing sampled scroll offset generation, this value is bumped up
   1198  // every time this APZC sampled new scroll offset.
   1199  APZScrollGeneration mScrollGeneration;
   1200 
   1201  friend class Axis;
   1202 
   1203 public:
   1204  Maybe<CompositionPayload> NotifyScrollSampling();
   1205 
   1206  /**
   1207   * Invoke |callable|, passing |mLastContentPaintMetrics| as argument,
   1208   * while holding the APZC lock required to access |mLastContentPaintMetrics|.
   1209   * This allows code outside of an AsyncPanZoomController method implementation
   1210   * to access |mLastContentPaintMetrics| without having to make a copy of it.
   1211   * Passes through the return value of |callable|.
   1212   */
   1213  template <typename Callable>
   1214  auto CallWithLastContentPaintMetrics(const Callable& callable) const
   1215      -> decltype(callable(mLastContentPaintMetrics)) {
   1216    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1217    return callable(mLastContentPaintMetrics);
   1218  }
   1219 
   1220  void SetZoomAnimationId(const Maybe<uint64_t>& aZoomAnimationId);
   1221  Maybe<uint64_t> GetZoomAnimationId() const;
   1222 
   1223  /* ===================================================================
   1224   * The functions and members in this section are used to expose
   1225   * the current async transform state to callers.
   1226   */
   1227 public:
   1228  static const AsyncTransformConsumer eForEventHandling =
   1229      AsyncTransformConsumer::eForEventHandling;
   1230  static const AsyncTransformConsumer eForCompositing =
   1231      AsyncTransformConsumer::eForCompositing;
   1232 
   1233  /**
   1234   * Get the current scroll offset of the scrollable frame corresponding
   1235   * to this APZC, including the effects of any asynchronous panning and
   1236   * zooming, in ParentLayer pixels.
   1237   */
   1238  ParentLayerPoint GetCurrentAsyncScrollOffset(
   1239      AsyncTransformConsumer aMode) const;
   1240 
   1241  /**
   1242   * Get the current visual viewport of the scrollable frame corresponding
   1243   * to this APZC, including the effects of any asynchronous panning and
   1244   * zooming, in CSS pixels.
   1245   */
   1246  CSSRect GetCurrentAsyncVisualViewport(AsyncTransformConsumer aMode) const;
   1247 
   1248  /**
   1249   * Return a visual effect that reflects this apzc's
   1250   * overscrolled state, if any.
   1251   */
   1252  AsyncTransformComponentMatrix GetOverscrollTransform(
   1253      AsyncTransformConsumer aMode) const;
   1254 
   1255  /**
   1256   * Returns the incremental transformation corresponding to the async pan/zoom
   1257   * in progress. That is, when this transform is multiplied with the layer's
   1258   * existing transform, it will make the layer appear with the desired pan/zoom
   1259   * amount.
   1260   * The transform can have both scroll and zoom components; the caller can
   1261   * request just one or the other, or both, via the |aComponents| parameter.
   1262   * When only the eLayout component is requested, the returned translation
   1263   * should really be a LayerPoint, rather than a ParentLayerPoint, as it will
   1264   * not be scaled by the asynchronous zoom.
   1265   * |aMode| specifies whether the async transform is queried for the purpose of
   1266   * hit testing (eHitTesting) in which case the latest values from |Metrics()|
   1267   * are used, or for compositing (eCompositing) in which case a sampled value
   1268   * from |mSampledState| is used.
   1269   * |aSampleIndex| specifies which sample in |mSampledState| to use.
   1270   */
   1271  AsyncTransform GetCurrentAsyncTransform(
   1272      AsyncTransformConsumer aMode,
   1273      AsyncTransformComponents aComponents = LayoutAndVisual,
   1274      std::size_t aSampleIndex = 0) const;
   1275 
   1276  /**
   1277   * A variant of GetCurrentAsyncTransform() intended for use when computing
   1278   * the screen-to-apzc and apzc-to-gecko transforms. This includes the
   1279   * overscroll transform, and additionally requires the caller to pass in
   1280   * the LayersId of the APZC whose screen-to-apzc or apzc-to-gecko transform
   1281   * is being computed in |aForLayersId|; if that APZC is in an out-of-process
   1282   * subdocument, and we are the zoomable (root-content) APZC, the returned
   1283   * transform includes the resolution at painting time, not just the async
   1284   * change to the resolution since painting. This is done because
   1285   * out-of-process content expects the screen-to-apzc and apzc-to-gecko
   1286   * transforms to include the painted resolution (see bug 1827330 for details).
   1287   *
   1288   * Should only be called from
   1289   * APZCTreeManager::{GetScreenToApzcTransform(),GetApzcToGeckoTransform()}.
   1290   */
   1291  AsyncTransformComponentMatrix GetAsyncTransformForInputTransformation(
   1292      AsyncTransformComponents aComponents, LayersId aForLayersId) const;
   1293 
   1294  /**
   1295   * Returns a transform that scales by the resolution that was in place
   1296   * at "painting" (display list building) time. This is used as a
   1297   * component of some transforms related to APZCs in out-of-process
   1298   * subdocuments.
   1299   *
   1300   * Can only be called for the root content APZC.
   1301   */
   1302  Matrix4x4 GetPaintedResolutionTransform() const;
   1303 
   1304  AutoTArray<wr::SampledScrollOffset, 2> GetSampledScrollOffsets() const;
   1305 
   1306  /**
   1307   * Returns the "zoom" bits of the transform. This includes both the rasterized
   1308   * (layout device to layer scale) and async (layer scale to parent layer
   1309   * scale) components of the zoom.
   1310   */
   1311  LayoutDeviceToParentLayerScale GetCurrentPinchZoomScale(
   1312      AsyncTransformConsumer aMode) const;
   1313 
   1314  ParentLayerRect GetCompositionBounds() const {
   1315    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1316    return mScrollMetadata.GetMetrics().GetCompositionBounds();
   1317  }
   1318 
   1319  LayoutDeviceToLayerScale GetCumulativeResolution() const {
   1320    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1321    return mScrollMetadata.GetMetrics().GetCumulativeResolution();
   1322  }
   1323 
   1324  CSSRect GetScrollableRect() const {
   1325    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1326    return mScrollMetadata.GetMetrics().GetScrollableRect();
   1327  }
   1328 
   1329  CSSToParentLayerScale GetZoom() const {
   1330    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1331    return Metrics().GetZoom();
   1332  }
   1333 
   1334  CSSRect GetVisualViewport() const {
   1335    MOZ_ASSERT(IsRootContent());
   1336    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1337    return Metrics().GetVisualViewport();
   1338  }
   1339 
   1340  CSSPoint GetLayoutScrollOffset() const {
   1341    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1342    return Metrics().GetLayoutScrollOffset();
   1343  }
   1344 
   1345  // Returns the delta for the given InputData.
   1346  ParentLayerPoint GetDeltaForEvent(const InputData& aEvent) const;
   1347 
   1348  /**
   1349   * Get the current scroll range of the scrollable frame coreesponding to this
   1350   * APZC.
   1351   */
   1352  CSSRect GetCurrentScrollRangeInCssPixels() const;
   1353 
   1354  bool AllowOneTouchPinch() const;
   1355 
   1356 private:
   1357  /**
   1358   * Advances to the next sample, if there is one, the list of sampled states
   1359   * stored in mSampledState. This will make the result of
   1360   * |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect
   1361   * the async scroll offset and zoom of the next sample. See also
   1362   * SampleCompositedAsyncTransform which creates the samples.
   1363   */
   1364  void AdvanceToNextSample();
   1365 
   1366  /**
   1367   * Returns whether we have changes to the scroll offsets which need to be
   1368   * sampled in the next couple of frames (it depends on how many offsets we
   1369   * have, currently it's two).
   1370   */
   1371  bool HavePendingFrameDelayedOffset() const;
   1372 
   1373  /**
   1374   * Samples the composited async transform, storing the result into
   1375   * mSampledState. This will make the result of
   1376   * |GetCurrentAsyncTransform(eForCompositing)| and similar functions reflect
   1377   * the async scroll offset and zoom stored in |Metrics()| when the sample
   1378   * is activated via some future call to |AdvanceToNextSample|.
   1379   *
   1380   * Returns true if the newly sampled value is different from the last
   1381   * sampled value.
   1382   */
   1383  bool SampleCompositedAsyncTransform(
   1384      const RecursiveMutexAutoLock& aProofOfLock);
   1385 
   1386  /**
   1387   * Updates the sample at the front of mSampledState with the latest
   1388   * metrics. This makes the result of
   1389   * |GetCurrentAsyncTransform(eForCompositing)| reflect the current Metrics().
   1390   */
   1391  void ResampleCompositedAsyncTransform(
   1392      const RecursiveMutexAutoLock& aProofOfLock);
   1393 
   1394  /*
   1395   * Helper functions to query the async layout viewport, scroll offset, and
   1396   * zoom either directly from |Metrics()|, or from cached variables that
   1397   * store the required value from the last time it was sampled by calling
   1398   * SampleCompositedAsyncTransform(), depending on who is asking.
   1399   */
   1400  CSSRect GetEffectiveLayoutViewport(AsyncTransformConsumer aMode,
   1401                                     const RecursiveMutexAutoLock& aProofOfLock,
   1402                                     std::size_t aSampleIndex = 0) const;
   1403  CSSPoint GetEffectiveScrollOffset(AsyncTransformConsumer aMode,
   1404                                    const RecursiveMutexAutoLock& aProofOfLock,
   1405                                    std::size_t aSampleIndex = 0) const;
   1406  CSSToParentLayerScale GetEffectiveZoom(
   1407      AsyncTransformConsumer aMode, const RecursiveMutexAutoLock& aProofOfLock,
   1408      std::size_t aSampleIndex = 0) const;
   1409 
   1410  /**
   1411   * Returns the visible portion of the content scrolled by this APZC, in
   1412   * CSS pixels. The caller must have acquired the mRecursiveMutex lock.
   1413   */
   1414  CSSRect GetVisibleRect(const RecursiveMutexAutoLock& aProofOfLock) const;
   1415 
   1416  /**
   1417   * Returns a pair of displacements both in logical/physical units for
   1418   * |aEvent|.
   1419   */
   1420  std::tuple<ParentLayerPoint, ScreenPoint> GetDisplacementsForPanGesture(
   1421      const PanGestureInput& aEvent);
   1422 
   1423  CSSPoint ToCSSPixels(ParentLayerPoint value) const;
   1424  CSSCoord ToCSSPixels(ParentLayerCoord value) const;
   1425 
   1426 private:
   1427  friend class AutoApplyAsyncTestAttributes;
   1428  friend class AutoDynamicToolbarHider;
   1429 
   1430  bool SuppressAsyncScrollOffset() const;
   1431 
   1432  /**
   1433   * Applies |mTestAsyncScrollOffset| and |mTestAsyncZoom| to this
   1434   * AsyncPanZoomController. Calls |SampleCompositedAsyncTransform| to ensure
   1435   * that the GetCurrentAsync* functions consider the test offset and zoom in
   1436   * their computations.
   1437   */
   1438  void ApplyAsyncTestAttributes(const RecursiveMutexAutoLock& aProofOfLock);
   1439 
   1440  /**
   1441   * Sets this AsyncPanZoomController's FrameMetrics to |aPrevFrameMetrics| and
   1442   * calls |SampleCompositedAsyncTransform| to unapply any test values applied
   1443   * by |ApplyAsyncTestAttributes|.
   1444   */
   1445  void UnapplyAsyncTestAttributes(const RecursiveMutexAutoLock& aProofOfLock,
   1446                                  const FrameMetrics& aPrevFrameMetrics,
   1447                                  const ParentLayerPoint& aPrevOverscroll);
   1448 
   1449  /* ===================================================================
   1450   * The functions and members in this section are used to manage
   1451   * the state that tracks what this APZC is doing with the input events.
   1452   */
   1453 protected:
   1454  enum PanZoomState {
   1455    NOTHING,  /* no touch-start events received */
   1456    FLING,    /* all touches removed, but we're still scrolling page */
   1457    TOUCHING, /* one touch-start event received */
   1458 
   1459    PANNING,          /* panning the frame */
   1460    PANNING_LOCKED_X, /* touch-start followed by move (i.e. panning with axis
   1461                         lock) X axis */
   1462    PANNING_LOCKED_Y, /* as above for Y axis */
   1463 
   1464    PAN_MOMENTUM, /* like PANNING, but controlled by momentum PanGestureInput
   1465                     events */
   1466 
   1467    PINCHING, /* nth touch-start, where n > 1. this mode allows pan and zoom */
   1468    ANIMATING_ZOOM,       /* animated zoom to a new rect */
   1469    OVERSCROLL_ANIMATION, /* Spring-based animation used to relieve overscroll
   1470                             once the finger is lifted. */
   1471    SMOOTH_SCROLL,        /* Smooth scrolling to destination. May be for a wheel
   1472                             event, keyboard event, scroll-behavior or scroll
   1473                             snapping. */
   1474    AUTOSCROLL,           /* Autoscroll animation. */
   1475    SCROLLBAR_DRAG        /* Async scrollbar drag. */
   1476  };
   1477  // This is in theory protected by |mRecursiveMutex|; that is, it should be
   1478  // held whenever this is updated. In practice though... see bug 897017.
   1479  PanZoomState mState;
   1480 
   1481  AxisX mX;
   1482  AxisY mY;
   1483 
   1484  /**
   1485   * Returns wheter the given input state is a user pan-gesture.
   1486   *
   1487   * Note: momentum pan gesture states are not considered a panning state.
   1488   */
   1489  static bool IsPanningState(PanZoomState aState);
   1490 
   1491  /**
   1492   * Returns wheter a delayed transform end is queued.
   1493   */
   1494  bool IsDelayedTransformEndSet();
   1495 
   1496  /**
   1497   * Returns wheter a delayed transform end is queued.
   1498   */
   1499  void SetDelayedTransformEnd(bool aDelayedTransformEnd);
   1500 
   1501  /**
   1502   * Check whether there is an ongoing smooth scroll animation of
   1503   * the specified kind.
   1504   */
   1505  bool InScrollAnimation(ScrollAnimationKind aKind) const;
   1506 
   1507  /**
   1508   * Check whether there is an ongoing smooth scroll animation triggered by
   1509   * script.
   1510   */
   1511  bool InScrollAnimationTriggeredByScript() const;
   1512 
   1513  /**
   1514   * Returns whether the specified PanZoomState does not need to be reset when
   1515   * a scroll offset update is processed.
   1516   */
   1517  static bool CanHandleScrollOffsetUpdate(PanZoomState aState);
   1518 
   1519  /**
   1520   * Determine whether a main-thread scroll offset update should result in
   1521   * a call to CancelAnimation() (which interrupts in-progress animations and
   1522   * gestures).
   1523   *
   1524   * If the update is a relative update, |aRelativeDelta| contains its amount.
   1525   * If the update is not a relative update, GetMetrics() should already reflect
   1526   * the new offset at the time of the call.
   1527   */
   1528  bool ShouldCancelAnimationForScrollUpdate(
   1529      const Maybe<CSSPoint>& aRelativeDelta);
   1530 
   1531 private:
   1532  friend class StateChangeNotificationBlocker;
   1533  friend class ThreadSafeStateChangeNotificationBlocker;
   1534  /**
   1535   * A counter of how many StateChangeNotificationBlockers are active.
   1536   * A non-zero count will prevent state change notifications from
   1537   * being dispatched. Only code that holds mRecursiveMutex should touch this.
   1538   */
   1539  int mNotificationBlockers;
   1540 
   1541  /**
   1542   * Helper to set the current state, without content controller events
   1543   * for the state change. This is useful in cases where the content
   1544   * controller events may need to be delayed.
   1545   */
   1546  PanZoomState SetStateNoContentControllerDispatch(PanZoomState aNewState);
   1547 
   1548  /**
   1549   * Helper to set the current state. Holds mRecursiveMutex before actually
   1550   * setting it and fires content controller events based on state changes.
   1551   * Always set the state using this call, do not set it directly.
   1552   */
   1553  void SetState(PanZoomState aNewState);
   1554  /**
   1555   * Helper for getting the current state which acquires mRecursiveMutex
   1556   * before accessing the field.
   1557   */
   1558  PanZoomState GetState() const;
   1559  /**
   1560   * Fire content controller notifications about state changes, assuming no
   1561   * StateChangeNotificationBlocker has been activated.
   1562   */
   1563  void DispatchStateChangeNotification(PanZoomState aOldState,
   1564                                       PanZoomState aNewState);
   1565 
   1566  /**
   1567   * Send a TransformBegin notification followed by a TransformEnd
   1568   * notification.
   1569   */
   1570  void SendTransformBeginAndEnd();
   1571 
   1572  /**
   1573   * Internal helpers for checking general state of this apzc.
   1574   */
   1575  bool IsInTransformingState() const;
   1576  static bool IsTransformingState(PanZoomState aState);
   1577 
   1578  /* ===================================================================
   1579   * The functions and members in this section are used to manage
   1580   * blocks of touch events and the state needed to deal with content
   1581   * listeners.
   1582   */
   1583 public:
   1584  /**
   1585   * Flush a repaint request if one is needed, without throttling it with the
   1586   * paint throttler.
   1587   */
   1588  void FlushRepaintForNewInputBlock();
   1589 
   1590  /**
   1591   * Given an input event and the touch block it belongs to, check if the
   1592   * event can lead to a panning/zooming behavior.
   1593   * This is used for logic related to the pointer events spec (figuring out
   1594   * when to dispatch the pointercancel event), as well as an input to the
   1595   * computation of the APZHandledResult for the event (used on Android to
   1596   * govern dynamic toolbar and pull-to-refresh behaviour).
   1597   */
   1598  PointerEventsConsumableFlags ArePointerEventsConsumable(
   1599      const TouchBlockState* aBlock, const MultiTouchInput& aInput) const;
   1600 
   1601  /**
   1602   * Clear internal state relating to touch input handling.
   1603   */
   1604  void ResetTouchInputState();
   1605 
   1606  /**
   1607     Clear internal state relating to pan gesture input handling.
   1608   */
   1609  void ResetPanGestureInputState();
   1610 
   1611  /**
   1612   * Gets a ref to the input queue that is shared across the entire tree
   1613   * manager.
   1614   */
   1615  const RefPtr<InputQueue>& GetInputQueue() const;
   1616 
   1617 private:
   1618  void CancelAnimationAndGestureState();
   1619 
   1620  RefPtr<InputQueue> mInputQueue;
   1621  InputBlockState* GetCurrentInputBlock() const;
   1622  TouchBlockState* GetCurrentTouchBlock() const;
   1623  bool HasReadyTouchBlock() const;
   1624 
   1625  PanGestureBlockState* GetCurrentPanGestureBlock() const;
   1626  PinchGestureBlockState* GetCurrentPinchGestureBlock() const;
   1627 
   1628 private:
   1629  /* ===================================================================
   1630   * The functions and members in this section are used to manage
   1631   * fling animations, smooth scroll animations, and overscroll
   1632   * during a fling or smooth scroll.
   1633   */
   1634 public:
   1635  /**
   1636   * Attempt a fling with the velocity specified in |aHandoffState|.
   1637   * |aHandoffState.mIsHandoff| should be true iff. the fling was handed off
   1638   * from a previous APZC, and determines whether acceleration is applied
   1639   * to the fling.
   1640   * We only accept the fling in the direction(s) in which we are pannable.
   1641   * Returns the "residual velocity", i.e. the portion of
   1642   * |aHandoffState.mVelocity| that this APZC did not consume.
   1643   */
   1644  ParentLayerPoint AttemptFling(const FlingHandoffState& aHandoffState);
   1645 
   1646  ParentLayerPoint AdjustHandoffVelocityForOverscrollBehavior(
   1647      ParentLayerPoint& aHandoffVelocity) const;
   1648 
   1649 private:
   1650  friend class StackScrollerFlingAnimation;
   1651  friend class AutoscrollAnimation;
   1652  template <typename FlingPhysics>
   1653  friend class GenericFlingAnimation;
   1654  friend class AndroidFlingPhysics;
   1655  friend class DesktopFlingPhysics;
   1656  friend class OverscrollAnimation;
   1657  friend class GenericScrollAnimation;
   1658  friend class SmoothScrollAnimation;
   1659  friend class ZoomAnimation;
   1660 
   1661  friend class GenericOverscrollEffect;
   1662  friend class WidgetOverscrollEffect;
   1663  friend struct apz::AsyncScrollThumbTransformer;
   1664 
   1665  FlingAccelerator mFlingAccelerator;
   1666 
   1667  // Indicates if the repaint-during-pinch timer is currently set
   1668  bool mPinchPaintTimerSet;
   1669 
   1670  // Indicates a delayed transform end notification is queued, and the
   1671  // transform-end timer is currently set. mRecursiveMutex must be held
   1672  // when using or modifying this member.
   1673  bool mDelayedTransformEnd;
   1674 
   1675  // Deal with overscroll resulting from a fling animation. This is only ever
   1676  // called on APZC instances that were actually performing a fling.
   1677  // The overscroll is handled by trying to hand the fling off to an APZC
   1678  // later in the handoff chain, or if there are no takers, continuing the
   1679  // fling and entering an overscrolled state.
   1680  void HandleFlingOverscroll(
   1681      const ParentLayerPoint& aVelocity, SideBits aOverscrollSideBits,
   1682      const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
   1683      const RefPtr<const AsyncPanZoomController>& aScrolledApzc);
   1684 
   1685  // Start an overscroll animation with the given initial velocity.
   1686  void StartOverscrollAnimation(const ParentLayerPoint& aVelocity,
   1687                                SideBits aOverscrollSideBits);
   1688 
   1689  // Start a smooth-scrolling animation to the given destination.
   1690  // |aAnimationKind| must be |Smooth| or |SmoothMsd|
   1691  // |aOrigin| is only used with |Smooth| (for |SmoothMsd|,
   1692  // |ScrollOrigin::NotSpecified| may be passed).
   1693  void SmoothScrollTo(CSSSnapDestination&& aDestination,
   1694                      ScrollTriggeredByScript aTriggeredByScript,
   1695                      ScrollAnimationKind aAnimationKind,
   1696                      ViewportType aViewportToScroll, ScrollOrigin aOrigin,
   1697                      TimeStamp aStartTime);
   1698 
   1699  ParentLayerPoint ConvertDestinationToDelta(CSSPoint& aDestination) const;
   1700 
   1701  // Returns whether overscroll is allowed during an event.
   1702  bool AllowScrollHandoffInCurrentBlock() const;
   1703 
   1704  // Invoked by the pinch repaint timer.
   1705  void DoDelayedRequestContentRepaint();
   1706 
   1707  // Invoked by the on pan-end handler to ensure that scrollend is only
   1708  // fired once when a momentum pan or scroll snap is triggered as a
   1709  // result of the pan gesture.
   1710  void DoDelayedTransformEndNotification(PanZoomState aOldState);
   1711 
   1712  // Compute the number of ParentLayer pixels per (Screen) inch at the given
   1713  // point and in the given direction.
   1714  float ComputePLPPI(ParentLayerPoint aPoint,
   1715                     ParentLayerPoint aDirection) const;
   1716 
   1717  Maybe<CSSPoint> GetCurrentAnimationDestination(
   1718      const RecursiveMutexAutoLock& aProofOfLock) const;
   1719 
   1720  /* ===================================================================
   1721   * The functions and members in this section are used to make ancestor chains
   1722   * out of APZC instances. These chains can only be walked or manipulated
   1723   * while holding the lock in the associated APZCTreeManager instance.
   1724   */
   1725 public:
   1726  void SetParent(AsyncPanZoomController* aParent) { mParent = aParent; }
   1727 
   1728  AsyncPanZoomController* GetParent() const { return mParent; }
   1729 
   1730  /* Returns true if there is no APZC higher in the tree with the same
   1731   * layers id.
   1732   */
   1733  bool HasNoParentWithSameLayersId() const {
   1734    return !mParent || (mParent->mLayersId != mLayersId);
   1735  }
   1736 
   1737  bool IsRootForLayersId() const {
   1738    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1739    return mScrollMetadata.IsLayersIdRoot();
   1740  }
   1741 
   1742  bool IsRootContent() const {
   1743    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1744    return Metrics().IsRootContent();
   1745  }
   1746 
   1747 private:
   1748  // |mTreeManager| belongs in this section but it's declaration is a bit
   1749  // further above due to initialization-order constraints.
   1750 
   1751  RefPtr<AsyncPanZoomController> mParent;
   1752 
   1753  /* ===================================================================
   1754   * The functions and members in this section are used for scrolling,
   1755   * including handing off scroll to another APZC, and overscrolling.
   1756   */
   1757 
   1758  ScrollableLayerGuid::ViewID GetScrollId() const {
   1759    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1760    return Metrics().GetScrollId();
   1761  }
   1762 
   1763 public:
   1764  ScrollableLayerGuid::ViewID GetScrollHandoffParentId() const {
   1765    return mScrollMetadata.GetScrollParentId();
   1766  }
   1767 
   1768  /**
   1769   * Attempt to scroll in response to a touch-move from |aStartPoint| to
   1770   * |aEndPoint|, which are in our (transformed) screen coordinates.
   1771   * Due to overscroll handling, there may not actually have been a touch-move
   1772   * at these points, but this function will scroll as if there had been.
   1773   * If this attempt causes overscroll (i.e. the layer cannot be scrolled
   1774   * by the entire amount requested), the overscroll is passed back to the
   1775   * tree manager via APZCTreeManager::DispatchScroll(). If the tree manager
   1776   * does not find an APZC further in the handoff chain to accept the
   1777   * overscroll, and this APZC is pannable, this APZC enters an overscrolled
   1778   * state.
   1779   * |aOverscrollHandoffChain| and |aOverscrollHandoffChainIndex| are used by
   1780   * the tree manager to keep track of which APZC to hand off the overscroll
   1781   * to; this function increments the chain and the index and passes it on to
   1782   * APZCTreeManager::DispatchScroll() in the event of overscroll.
   1783   * Returns true iff. this APZC, or an APZC further down the
   1784   * handoff chain, accepted the scroll (possibly entering an overscrolled
   1785   * state). If this returns false, the caller APZC knows that it should enter
   1786   * an overscrolled state itself if it can.
   1787   * aStartPoint and aEndPoint are modified depending on how much of the
   1788   * scroll gesture was consumed by APZCs in the handoff chain.
   1789   */
   1790  bool AttemptScroll(ParentLayerPoint& aStartPoint, ParentLayerPoint& aEndPoint,
   1791                     OverscrollHandoffState& aOverscrollHandoffState);
   1792 
   1793  void FlushRepaintForOverscrollHandoff();
   1794 
   1795  /**
   1796   * If overscrolled, start a snap-back animation and return true. Even if not
   1797   * overscrolled, this function tries to snap back to if there's an applicable
   1798   * scroll snap point.
   1799   * Otherwise return false.
   1800   */
   1801  bool SnapBackIfOverscrolled();
   1802 
   1803  /**
   1804   * NOTE: Similar to above but this function doesn't snap back to the scroll
   1805   * snap point.
   1806   */
   1807  bool SnapBackIfOverscrolledForMomentum(const ParentLayerPoint& aVelocity);
   1808 
   1809  /**
   1810   * Build the chain of APZCs along which scroll will be handed off when
   1811   * this APZC receives input events.
   1812   *
   1813   * Notes on lifetime and const-correctness:
   1814   *   - The returned handoff chain is |const|, to indicate that it cannot be
   1815   *     changed after being built.
   1816   *   - When passing the chain to a function that uses it without storing it,
   1817   *     pass it by reference-to-const (as in |const OverscrollHandoffChain&|).
   1818   *   - When storing the chain, store it by RefPtr-to-const (as in
   1819   *     |RefPtr<const OverscrollHandoffChain>|). This ensures the chain is
   1820   *     kept alive. Note that queueing a task that uses the chain as an
   1821   *     argument constitutes storing, as the task may outlive its queuer.
   1822   *   - When passing the chain to a function that will store it, pass it as
   1823   *     |const RefPtr<const OverscrollHandoffChain>&|. This allows the
   1824   *     function to copy it into the |RefPtr<const OverscrollHandoffChain>|
   1825   *     that will store it, while avoiding an unnecessary copy (and thus
   1826   *     AddRef() and Release()) when passing it.
   1827   */
   1828  RefPtr<const OverscrollHandoffChain> BuildOverscrollHandoffChain();
   1829 
   1830 private:
   1831  /**
   1832   * A helper function for calling APZCTreeManager::DispatchScroll().
   1833   * Guards against the case where the APZC is being concurrently destroyed
   1834   * (and thus mTreeManager is being nulled out).
   1835   */
   1836  bool CallDispatchScroll(ParentLayerPoint& aStartPoint,
   1837                          ParentLayerPoint& aEndPoint,
   1838                          OverscrollHandoffState& aOverscrollHandoffState);
   1839 
   1840  void RecordScrollPayload(const TimeStamp& aTimeStamp);
   1841 
   1842  /**
   1843   * A helper function for overscrolling during panning. This is a wrapper
   1844   * around OverscrollBy() that also implements restrictions on entering
   1845   * overscroll based on the pan angle.
   1846   */
   1847  void OverscrollForPanning(ParentLayerPoint& aOverscroll,
   1848                            const ScreenPoint& aPanDistance);
   1849 
   1850  /**
   1851   * Try to overscroll by 'aOverscroll'.
   1852   * If we are pannable on a particular axis, that component of 'aOverscroll'
   1853   * is transferred to any existing overscroll.
   1854   */
   1855  void OverscrollBy(ParentLayerPoint& aOverscroll);
   1856 
   1857  /* ===================================================================
   1858   * The functions and members in this section are used to maintain the
   1859   * area that this APZC instance is responsible for. This is used when
   1860   * hit-testing to see which APZC instance should handle touch events.
   1861   */
   1862 public:
   1863  void SetAncestorTransform(const AncestorTransform& aAncestorTransform) {
   1864    mAncestorTransform = aAncestorTransform;
   1865  }
   1866 
   1867  Matrix4x4 GetAncestorTransform() const {
   1868    return mAncestorTransform.CombinedTransform();
   1869  }
   1870 
   1871  bool AncestorTransformContainsPerspective() const {
   1872    return mAncestorTransform.ContainsPerspectiveTransform();
   1873  }
   1874 
   1875  // Return the perspective transform component of the ancestor transform.
   1876  Matrix4x4 GetAncestorTransformPerspective() const {
   1877    return mAncestorTransform.GetPerspectiveTransform();
   1878  }
   1879 
   1880  // Returns whether or not this apzc contains the given screen point within
   1881  // its composition bounds.
   1882  bool Contains(const ScreenIntPoint& aPoint) const;
   1883 
   1884  bool IsInOverscrollGutter(const ScreenPoint& aHitTestPoint) const;
   1885  bool IsInOverscrollGutter(const ParentLayerPoint& aHitTestPoint) const;
   1886 
   1887  bool IsOverscrolled() const;
   1888 
   1889  bool IsOverscrollAnimationRunning() const {
   1890    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1891    return mState == OVERSCROLL_ANIMATION;
   1892  }
   1893 
   1894  // IsPhysicallyOverscrolled() checks whether the APZC is overscrolled
   1895  // by an overscroll effect which applies a transform to the APZC's contents.
   1896  bool IsPhysicallyOverscrolled() const;
   1897 
   1898 private:
   1899  bool IsInInvalidOverscroll() const;
   1900 
   1901 public:
   1902  bool IsInPanningState() const;
   1903 
   1904  // Returns whether being in the middle of a gesture. E.g., this APZC has
   1905  // started handling a pan gesture but hasn't yet received pan-end, etc.
   1906  bool IsInScrollingGesture() const;
   1907 
   1908 private:
   1909  /* This is the cumulative CSS transform for all the layers from (and
   1910   * including) the parent APZC down to (but excluding) this one, and excluding
   1911   * any perspective transforms. */
   1912  AncestorTransform mAncestorTransform;
   1913 
   1914  /* ===================================================================
   1915   * The functions and members in this section are used for testing
   1916   * and assertion purposes only.
   1917   */
   1918 public:
   1919  /**
   1920   * Gets whether this APZC has performed async key scrolling.
   1921   */
   1922  bool TestHasAsyncKeyScrolled() const { return mTestHasAsyncKeyScrolled; }
   1923 
   1924  /**
   1925   * Set an extra offset for testing async scrolling.
   1926   */
   1927  void SetTestAsyncScrollOffset(const CSSPoint& aPoint);
   1928  /**
   1929   * Set an extra offset for testing async scrolling.
   1930   */
   1931  void SetTestAsyncZoom(const LayerToParentLayerScale& aZoom);
   1932 
   1933  LayersId GetLayersId() const { return mLayersId; }
   1934 
   1935  bool IsAsyncZooming() const {
   1936    RecursiveMutexAutoLock lock(mRecursiveMutex);
   1937    return mState == PINCHING || mState == ANIMATING_ZOOM;
   1938  }
   1939 
   1940  void SetFixedLayerMargins(const ScreenMargin& aMargins);
   1941 
   1942 private:
   1943  // The timestamp of the latest touch start event.
   1944  TimeStamp mTouchStartTime;
   1945  // Used for interpolating touch events that cross the touch-start
   1946  // tolerance threshold.
   1947  struct TouchSample {
   1948    ExternalPoint mPosition;
   1949    TimeStamp mTimeStamp;
   1950  };
   1951  // Information about the latest touch event.
   1952  // This is only populated when we're in the TOUCHING state
   1953  // (and thus the last touch event has only one touch point).
   1954  TouchSample mLastTouch;
   1955  // The time duration between mTouchStartTime and the touchmove event that
   1956  // started the pan (the touchmove event that transitioned this APZC from the
   1957  // TOUCHING state to one of the PANNING* states). Only valid while this APZC
   1958  // is in a panning state.
   1959  TimeDuration mTouchStartRestingTimeBeforePan;
   1960  Maybe<ParentLayerCoord> mMinimumVelocityDuringPan;
   1961  // This variable needs to be protected by |mRecursiveMutex|.
   1962  ScrollSnapTargetIds mLastSnapTargetIds;
   1963  // This variable needs to be protected by |mRecursiveMutex|.
   1964  ScreenMargin mCompositorFixedLayerMargins;
   1965  // Extra offset to add to the async scroll position for testing
   1966  CSSPoint mTestAsyncScrollOffset;
   1967  // Extra zoom to include in the aync zoom for testing
   1968  LayerToParentLayerScale mTestAsyncZoom;
   1969  uint8_t mTestAttributeAppliers;
   1970  // Flag to track whether or not this APZC has ever async key scrolled.
   1971  bool mTestHasAsyncKeyScrolled;
   1972 
   1973  /* ===================================================================
   1974   * The functions and members in this section are used for checkerboard
   1975   * recording.
   1976   */
   1977 private:
   1978  // Helper function to update the in-progress checkerboard event, if any.
   1979  void UpdateCheckerboardEvent(const MutexAutoLock& aProofOfLock,
   1980                               uint32_t aMagnitude);
   1981 
   1982  // Mutex protecting mCheckerboardEvent
   1983  Mutex mCheckerboardEventLock;
   1984  // This is created when this APZC instance is first included as part of a
   1985  // composite. If a checkerboard event takes place, this is destroyed at the
   1986  // end of the event, and a new one is created on the next composite.
   1987  UniquePtr<CheckerboardEvent> mCheckerboardEvent;
   1988  // This is used to track the total amount of time that we could reasonably
   1989  // be checkerboarding. Combined with other info, this allows us to
   1990  // meaningfully say how frequently users actually encounter checkerboarding.
   1991  PotentialCheckerboardDurationTracker mPotentialCheckerboardTracker;
   1992 
   1993  /* ===================================================================
   1994   * The functions in this section are used for CSS scroll snapping.
   1995   */
   1996 
   1997  // If moving |aStartPosition| by |aDelta| should trigger scroll snapping,
   1998  // adjust |aDelta| to reflect the snapping (that is, make it a delta that will
   1999  // take us to the desired snap point). The delta is interpreted as being
   2000  // relative to |aStartPosition|, and if a target snap point is found,
   2001  // |aStartPosition| is also updated, to the value of the snap point.
   2002  // |aUnit| affects the snapping behaviour (see ScrollSnapUtils::
   2003  // GetSnapPointForDestination).
   2004  // Returns true iff. a target snap point was found.
   2005  Maybe<CSSSnapDestination> MaybeAdjustDeltaForScrollSnapping(
   2006      ScrollUnit aUnit, ScrollSnapFlags aSnapFlags, ParentLayerPoint& aDelta,
   2007      CSSPoint& aStartPosition);
   2008 
   2009  // A wrapper function of MaybeAdjustDeltaForScrollSnapping for
   2010  // ScrollWheelInput.
   2011  Maybe<CSSSnapDestination> MaybeAdjustDeltaForScrollSnappingOnWheelInput(
   2012      const ScrollWheelInput& aEvent, ParentLayerPoint& aDelta,
   2013      CSSPoint& aStartPosition);
   2014 
   2015  Maybe<CSSSnapDestination> MaybeAdjustDestinationForScrollSnapping(
   2016      const KeyboardInput& aEvent, CSSPoint& aDestination,
   2017      ScrollSnapFlags aSnapFlags);
   2018 
   2019  // Snap to a snap position nearby the current scroll position, if appropriate.
   2020  void ScrollSnap(ScrollSnapFlags aSnapFlags);
   2021 
   2022  // Snap to a snap position nearby the destination predicted based on the
   2023  // current velocity, if appropriate.
   2024  void ScrollSnapToDestination();
   2025 
   2026  // Snap to a snap position nearby the provided destination, if appropriate.
   2027  void ScrollSnapNear(const CSSPoint& aDestination, ScrollSnapFlags aSnapFlags);
   2028 
   2029  // Find a snap point near |aDestination| that we should snap to.
   2030  // Returns the snap point if one was found, or an empty Maybe otherwise.
   2031  // |aUnit| affects the snapping behaviour (see ScrollSnapUtils::
   2032  // GetSnapPointForDestination). It should generally be determined by the
   2033  // type of event that's triggering the scroll.
   2034  Maybe<CSSSnapDestination> FindSnapPointNear(const CSSPoint& aDestination,
   2035                                              ScrollUnit aUnit,
   2036                                              ScrollSnapFlags aSnapFlags);
   2037 
   2038  // If |aOriginalEvent| crosses the touch-start tolerance threshold, split it
   2039  // into two events: one that just reaches the threshold, and the remainder.
   2040  //
   2041  // |aPanThreshold| is the touch-start tolerance, and |aVectorLength| is
   2042  // the length of the vector from the touch-start position to |aOriginalEvent|.
   2043  // These values could be computed from |aOriginalEvent| but they are
   2044  // passed in for convenience since the caller also needs to compute them.
   2045  //
   2046  // |aExtPoint| is the position of |aOriginalEvent| in External coordinates,
   2047  // and in case of a split is modified by the function to reflect the position
   2048  // of of the first event. This is a workaround for the fact that recomputing
   2049  // the External position from the returned event would require a round-trip
   2050  // through |mScreenPoint| which is an integer.
   2051  Maybe<std::pair<MultiTouchInput, MultiTouchInput>> MaybeSplitTouchMoveEvent(
   2052      const MultiTouchInput& aOriginalEvent, ScreenCoord aPanThreshold,
   2053      float aVectorLength, ExternalPoint& aExtPoint);
   2054 
   2055  // Fill out the overscroll gutter with the new expanded contents the
   2056  // overscroll amount is inside the new scroll range. Returns the scroll
   2057  // position change delta if filling out happened, CSSPoint() otherwise.
   2058  CSSPoint MaybeFillOutOverscrollGutter(
   2059      const RecursiveMutexAutoLock& aProofOfLock);
   2060 
   2061  ScreenMargin GetFixedLayerMargins(
   2062      const RecursiveMutexAutoLock& aProofOfLock) const;
   2063 
   2064  friend std::ostream& operator<<(
   2065      std::ostream& aOut, const AsyncPanZoomController::PanZoomState& aState);
   2066 };
   2067 
   2068 }  // namespace layers
   2069 }  // namespace mozilla
   2070 
   2071 #endif  // mozilla_layers_PanZoomController_h