LCOV - code coverage report
Current view: top level - gfx/layers/apz/src - Axis.h (source / functions) Hit Total Coverage
Test: output.info Lines: 1 5 20.0 %
Date: 2017-07-14 16:53:18 Functions: 1 5 20.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set sw=2 ts=8 et 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_Axis_h
       8             : #define mozilla_layers_Axis_h
       9             : 
      10             : #include <sys/types.h>                  // for int32_t
      11             : #include "APZUtils.h"
      12             : #include "AxisPhysicsMSDModel.h"
      13             : #include "Units.h"
      14             : #include "mozilla/TimeStamp.h"          // for TimeDuration
      15             : #include "nsTArray.h"                   // for nsTArray
      16             : 
      17             : namespace mozilla {
      18             : namespace layers {
      19             : 
      20             : const float EPSILON = 0.0001f;
      21             : 
      22             : /**
      23             :  * Compare two coordinates for equality, accounting for rounding error.
      24             :  * Use both FuzzyEqualsAdditive() with COORDINATE_EPISLON, which accounts for
      25             :  * things like the error introduced by rounding during a round-trip to app
      26             :  * units, and FuzzyEqualsMultiplicative(), which accounts for accumulated error
      27             :  * due to floating-point operations (which can be larger than COORDINATE_EPISLON
      28             :  * for sufficiently large coordinate values).
      29             :  */
      30             : bool FuzzyEqualsCoordinate(float aValue1, float aValue2);
      31             : 
      32             : struct FrameMetrics;
      33             : class AsyncPanZoomController;
      34             : 
      35             : /**
      36             :  * Helper class to maintain each axis of movement (X,Y) for panning and zooming.
      37             :  * Note that everything here is specific to one axis; that is, the X axis knows
      38             :  * nothing about the Y axis and vice versa.
      39             :  */
      40           0 : class Axis {
      41             : public:
      42             :   explicit Axis(AsyncPanZoomController* aAsyncPanZoomController);
      43             : 
      44             :   /**
      45             :    * Notify this Axis that a new touch has been received, including a timestamp
      46             :    * for when the touch was received. This triggers a recalculation of velocity.
      47             :    * This can also used for pan gesture events. For those events, the "touch"
      48             :    * location is stationary and the scroll displacement is passed in as
      49             :    * aAdditionalDelta.
      50             :    */
      51             :   void UpdateWithTouchAtDevicePoint(ParentLayerCoord aPos, ParentLayerCoord aAdditionalDelta, uint32_t aTimestampMs);
      52             : 
      53             : protected:
      54             :   float ApplyFlingCurveToVelocity(float aVelocity) const;
      55             :   void AddVelocityToQueue(uint32_t aTimestampMs, float aVelocity);
      56             : 
      57             : public:
      58             :   void HandleTouchVelocity(uint32_t aTimestampMs, float aSpeed);
      59             : 
      60             :   /**
      61             :    * Notify this Axis that a touch has begun, i.e. the user has put their finger
      62             :    * on the screen but has not yet tried to pan.
      63             :    */
      64             :   void StartTouch(ParentLayerCoord aPos, uint32_t aTimestampMs);
      65             : 
      66             :   /**
      67             :    * Notify this Axis that a touch has ended gracefully. This may perform
      68             :    * recalculations of the axis velocity.
      69             :    */
      70             :   void EndTouch(uint32_t aTimestampMs);
      71             : 
      72             :   /**
      73             :    * Notify this Axis that the gesture has ended forcefully. Useful for stopping
      74             :    * flings when a user puts their finger down in the middle of one (i.e. to
      75             :    * stop a previous touch including its fling so that a new one can take its
      76             :    * place).
      77             :    */
      78             :   void CancelGesture();
      79             : 
      80             :   /**
      81             :    * Takes a requested displacement to the position of this axis, and adjusts it
      82             :    * to account for overscroll (which might decrease the displacement; this is
      83             :    * to prevent the viewport from overscrolling the page rect), and axis locking
      84             :    * (which might prevent any displacement from happening). If overscroll
      85             :    * ocurred, its amount is written to |aOverscrollAmountOut|.
      86             :    * The |aDisplacementOut| parameter is set to the adjusted
      87             :    * displacement, and the function returns true iff internal overscroll amounts
      88             :    * were changed.
      89             :    */
      90             :   bool AdjustDisplacement(ParentLayerCoord aDisplacement,
      91             :                           /* ParentLayerCoord */ float& aDisplacementOut,
      92             :                           /* ParentLayerCoord */ float& aOverscrollAmountOut,
      93             :                           bool aForceOverscroll = false);
      94             : 
      95             :   /**
      96             :    * Overscrolls this axis by the requested amount in the requested direction.
      97             :    * The axis must be at the end of its scroll range in this direction.
      98             :    */
      99             :   void OverscrollBy(ParentLayerCoord aOverscroll);
     100             : 
     101             :   /**
     102             :    * Return the amount of overscroll on this axis, in ParentLayer pixels.
     103             :    *
     104             :    * If this amount is nonzero, the relevant component of
     105             :    * mAsyncPanZoomController->mFrameMetrics.mScrollOffset must be at its
     106             :    * extreme allowed value in the relevant direction (that is, it must be at
     107             :    * its maximum value if we are overscrolled at our composition length, and
     108             :    * at its minimum value if we are overscrolled at the origin).
     109             :    */
     110             :   ParentLayerCoord GetOverscroll() const;
     111             : 
     112             :   /**
     113             :    * Start an overscroll animation with the given initial velocity.
     114             :    */
     115             :   void StartOverscrollAnimation(float aVelocity);
     116             : 
     117             :   /**
     118             :    * Sample the snap-back animation to relieve overscroll.
     119             :    * |aDelta| is the time since the last sample.
     120             :    */
     121             :   bool SampleOverscrollAnimation(const TimeDuration& aDelta);
     122             : 
     123             :   /**
     124             :    * Stop an overscroll animation.
     125             :    */
     126             :   void EndOverscrollAnimation();
     127             : 
     128             :   /**
     129             :    * Return whether this axis is overscrolled in either direction.
     130             :    */
     131             :   bool IsOverscrolled() const;
     132             : 
     133             :   /**
     134             :    * Clear any overscroll amount on this axis.
     135             :    */
     136             :   void ClearOverscroll();
     137             : 
     138             :   /**
     139             :    * Gets the starting position of the touch supplied in StartTouch().
     140             :    */
     141             :   ParentLayerCoord PanStart() const;
     142             : 
     143             :   /**
     144             :    * Gets the distance between the starting position of the touch supplied in
     145             :    * StartTouch() and the current touch from the last
     146             :    * UpdateWithTouchAtDevicePoint().
     147             :    */
     148             :   ParentLayerCoord PanDistance() const;
     149             : 
     150             :   /**
     151             :    * Gets the distance between the starting position of the touch supplied in
     152             :    * StartTouch() and the supplied position.
     153             :    */
     154             :   ParentLayerCoord PanDistance(ParentLayerCoord aPos) const;
     155             : 
     156             :   /**
     157             :    * Applies friction during a fling, or cancels the fling if the velocity is
     158             :    * too low. Returns true if the fling should continue to another frame, or
     159             :    * false if it should end.
     160             :    * |aDelta| is the amount of time that has passed since the last time
     161             :    * friction was applied.
     162             :    * |aFriction| is the amount of friction to apply.
     163             :    * |aThreshold| is the velocity below which the fling is cancelled.
     164             :    */
     165             :   bool FlingApplyFrictionOrCancel(const TimeDuration& aDelta,
     166             :                                   float aFriction,
     167             :                                   float aThreshold);
     168             : 
     169             :   /**
     170             :    * Returns true if the page has room to be scrolled along this axis.
     171             :    */
     172             :   bool CanScroll() const;
     173             : 
     174             :   /**
     175             :    * Returns whether this axis can scroll any more in a particular direction.
     176             :    */
     177             :   bool CanScroll(ParentLayerCoord aDelta) const;
     178             : 
     179             :   /**
     180             :    * Returns true if the page has room to be scrolled along this axis
     181             :    * and this axis is not scroll-locked.
     182             :    */
     183             :   bool CanScrollNow() const;
     184             : 
     185             :   /**
     186             :    * Clamp a point to the page's scrollable bounds. That is, a scroll
     187             :    * destination to the returned point will not contain any overscroll.
     188             :    */
     189             :   CSSCoord ClampOriginToScrollableRect(CSSCoord aOrigin) const;
     190             : 
     191           4 :   void SetAxisLocked(bool aAxisLocked) { mAxisLocked = aAxisLocked; }
     192             : 
     193             :   /**
     194             :    * Gets the raw velocity of this axis at this moment.
     195             :    */
     196             :   float GetVelocity() const;
     197             : 
     198             :   /**
     199             :    * Sets the raw velocity of this axis at this moment.
     200             :    * Intended to be called only when the axis "takes over" a velocity from
     201             :    * another APZC, in which case there are no touch points available to call
     202             :    * UpdateWithTouchAtDevicePoint. In other circumstances,
     203             :    * UpdateWithTouchAtDevicePoint should be used and the velocity calculated
     204             :    * there.
     205             :    */
     206             :   void SetVelocity(float aVelocity);
     207             : 
     208             :   /**
     209             :    * If a displacement will overscroll the axis, this returns the amount and in
     210             :    * what direction.
     211             :    */
     212             :   ParentLayerCoord DisplacementWillOverscrollAmount(ParentLayerCoord aDisplacement) const;
     213             : 
     214             :   /**
     215             :    * If a scale will overscroll the axis, this returns the amount and in what
     216             :    * direction.
     217             :    *
     218             :    * |aFocus| is the point at which the scale is focused at. We will offset the
     219             :    * scroll offset in such a way that it remains in the same place on the page
     220             :    * relative.
     221             :    *
     222             :    * Note: Unlike most other functions in Axis, this functions operates in
     223             :    *       CSS coordinates so there is no confusion as to whether the ParentLayer
     224             :    *       coordinates it operates in are before or after the scale is applied.
     225             :    */
     226             :   CSSCoord ScaleWillOverscrollAmount(float aScale, CSSCoord aFocus) const;
     227             : 
     228             :   /**
     229             :    * Checks if an axis will overscroll in both directions by computing the
     230             :    * content rect and checking that its height/width (depending on the axis)
     231             :    * does not overextend past the viewport.
     232             :    *
     233             :    * This gets called by ScaleWillOverscroll().
     234             :    */
     235             :   bool ScaleWillOverscrollBothSides(float aScale) const;
     236             : 
     237             :   /**
     238             :    * Returns true if movement on this axis is locked.
     239             :    */
     240             :   bool IsAxisLocked() const;
     241             : 
     242             :   ParentLayerCoord GetOrigin() const;
     243             :   ParentLayerCoord GetCompositionLength() const;
     244             :   ParentLayerCoord GetPageStart() const;
     245             :   ParentLayerCoord GetPageLength() const;
     246             :   ParentLayerCoord GetCompositionEnd() const;
     247             :   ParentLayerCoord GetPageEnd() const;
     248             :   ParentLayerCoord GetScrollRangeEnd() const;
     249             : 
     250           0 :   ParentLayerCoord GetPos() const { return mPos; }
     251             : 
     252             :   virtual ParentLayerCoord GetPointOffset(const ParentLayerPoint& aPoint) const = 0;
     253             :   virtual ParentLayerCoord GetRectLength(const ParentLayerRect& aRect) const = 0;
     254             :   virtual ParentLayerCoord GetRectOffset(const ParentLayerRect& aRect) const = 0;
     255             :   virtual CSSToParentLayerScale GetScaleForAxis(const CSSToParentLayerScale2D& aScale) const = 0;
     256             : 
     257             :   virtual ScreenPoint MakePoint(ScreenCoord aCoord) const = 0;
     258             : 
     259             :   virtual const char* Name() const = 0;
     260             : 
     261             : protected:
     262             :   ParentLayerCoord mPos;
     263             : 
     264             :   // mVelocitySampleTimeMs and mVelocitySamplePos are the time and position
     265             :   // used in the last velocity sampling. They get updated when a new sample is
     266             :   // taken (which may not happen on every input event, if the time delta is too
     267             :   // small).
     268             :   uint32_t mVelocitySampleTimeMs;
     269             :   ParentLayerCoord mVelocitySamplePos;
     270             : 
     271             :   ParentLayerCoord mStartPos;
     272             :   float mVelocity;      // Units: ParentLayerCoords per millisecond
     273             :   bool mAxisLocked;     // Whether movement on this axis is locked.
     274             :   AsyncPanZoomController* mAsyncPanZoomController;
     275             : 
     276             :   // The amount by which we are overscrolled; see GetOverscroll().
     277             :   ParentLayerCoord mOverscroll;
     278             : 
     279             :   // The mass-spring-damper model for overscroll physics.
     280             :   AxisPhysicsMSDModel mMSDModel;
     281             : 
     282             :   // A queue of (timestamp, velocity) pairs; these are the historical
     283             :   // velocities at the given timestamps. Timestamps are in milliseconds,
     284             :   // velocities are in screen pixels per ms. This member can only be
     285             :   // accessed on the controller/UI thread.
     286             :   nsTArray<std::pair<uint32_t, float> > mVelocityQueue;
     287             : 
     288             :   const FrameMetrics& GetFrameMetrics() const;
     289             : 
     290             :   // Adjust a requested overscroll amount for resistance, yielding a smaller
     291             :   // actual overscroll amount.
     292             :   ParentLayerCoord ApplyResistance(ParentLayerCoord aOverscroll) const;
     293             : 
     294             :   // Helper function for SampleOverscrollAnimation().
     295             :   void StepOverscrollAnimation(double aStepDurationMilliseconds);
     296             : 
     297             :   // Convert a velocity from global inches/ms into ParentLayerCoords/ms.
     298             :   float ToLocalVelocity(float aVelocityInchesPerMs) const;
     299             : };
     300             : 
     301           0 : class AxisX : public Axis {
     302             : public:
     303             :   explicit AxisX(AsyncPanZoomController* mAsyncPanZoomController);
     304             :   virtual ParentLayerCoord GetPointOffset(const ParentLayerPoint& aPoint) const override;
     305             :   virtual ParentLayerCoord GetRectLength(const ParentLayerRect& aRect) const override;
     306             :   virtual ParentLayerCoord GetRectOffset(const ParentLayerRect& aRect) const override;
     307             :   virtual CSSToParentLayerScale GetScaleForAxis(const CSSToParentLayerScale2D& aScale) const override;
     308             :   virtual ScreenPoint MakePoint(ScreenCoord aCoord) const override;
     309             :   virtual const char* Name() const override;
     310             : };
     311             : 
     312           0 : class AxisY : public Axis {
     313             : public:
     314             :   explicit AxisY(AsyncPanZoomController* mAsyncPanZoomController);
     315             :   virtual ParentLayerCoord GetPointOffset(const ParentLayerPoint& aPoint) const override;
     316             :   virtual ParentLayerCoord GetRectLength(const ParentLayerRect& aRect) const override;
     317             :   virtual ParentLayerCoord GetRectOffset(const ParentLayerRect& aRect) const override;
     318             :   virtual CSSToParentLayerScale GetScaleForAxis(const CSSToParentLayerScale2D& aScale) const override;
     319             :   virtual ScreenPoint MakePoint(ScreenCoord aCoord) const override;
     320             :   virtual const char* Name() const override;
     321             : };
     322             : 
     323             : } // namespace layers
     324             : } // namespace mozilla
     325             : 
     326             : #endif

Generated by: LCOV version 1.13