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