Bug 1448439 - Allow the concrete type of fling animations to be determined dynamically. r=kats draft
authorBotond Ballo <botond@mozilla.com>
Tue, 17 Apr 2018 19:53:26 -0400
changeset 788678 19de9aa3c6d1482ace56ce6a4314fe2538a760a7
parent 788677 ef68f50b01af2ba5a00f76fd2f5e3fd01bfead6a
child 788679 b7361efece81ffc7b9185c2f6d827ca8c75e3eba
push id108063
push userbballo@mozilla.com
push dateThu, 26 Apr 2018 20:42:29 +0000
reviewerskats
bugs1448439
milestone61.0a1
Bug 1448439 - Allow the concrete type of fling animations to be determined dynamically. r=kats MozReview-Commit-ID: EBscYyxdlwr
gfx/layers/apz/src/AndroidAPZ.cpp
gfx/layers/apz/src/AndroidAPZ.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
gfx/layers/apz/src/GenericFlingAnimation.h
--- a/gfx/layers/apz/src/AndroidAPZ.cpp
+++ b/gfx/layers/apz/src/AndroidAPZ.cpp
@@ -38,16 +38,27 @@ AndroidSpecificState::AndroidSpecificSta
   StackScroller::LocalRef scroller;
   if (StackScroller::New(GeckoAppShell::GetApplicationContext(), &scroller) != NS_OK) {
     ANDROID_APZ_LOG("%p Failed to create Android StackScroller\n", this);
     return;
   }
   mOverScroller = scroller;
 }
 
+AsyncPanZoomAnimation*
+AndroidSpecificState::CreateFlingAnimation(AsyncPanZoomController& aApzc,
+                                           const FlingHandoffState& aHandoffState) {
+  return new AndroidFlingAnimation(aApzc,
+      this,
+      aHandoffState.mChain,
+      aHandoffState.mIsHandoff,
+      aHandoffState.mScrolledApzc);
+}
+
+
 const float BOUNDS_EPSILON = 1.0f;
 
 // This function is used to convert the scroll offset from a float to an integer
 // suitable for using with the Android OverScroller Class.
 // The Android OverScroller class (unfortunately) operates in integers instead of floats.
 // When casting a float value such as 1.5 to an integer, the value is converted to 1.
 // If this value represents the max scroll offset, the OverScroller class will never scroll
 // to the end of the page as it will always be 0.5 pixels short. To work around this issue,
--- a/gfx/layers/apz/src/AndroidAPZ.h
+++ b/gfx/layers/apz/src/AndroidAPZ.h
@@ -17,16 +17,19 @@ namespace layers {
 class AndroidSpecificState : public PlatformSpecificStateBase {
 public:
   AndroidSpecificState();
 
   virtual AndroidSpecificState* AsAndroidSpecificState() override {
     return this;
   }
 
+  virtual AsyncPanZoomAnimation* CreateFlingAnimation(AsyncPanZoomController& aApzc,
+                                                      const FlingHandoffState& aHandoffState) override;
+
   java::StackScroller::GlobalRef mOverScroller;
   TimeStamp mLastFling;
 };
 
 class AndroidFlingAnimation: public AsyncPanZoomAnimation {
 public:
   AndroidFlingAnimation(AsyncPanZoomController& aApzc,
                         PlatformSpecificStateBase* aPlatformSpecificState,
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -113,21 +113,19 @@ typedef GeckoContentController::TapType 
 typedef mozilla::gfx::Point Point;
 typedef mozilla::gfx::Matrix4x4 Matrix4x4;
 using mozilla::gfx::PointTyped;
 
 // Choose between platform-specific implementations.
 #ifdef MOZ_WIDGET_ANDROID
 typedef WidgetOverscrollEffect OverscrollEffect;
 typedef AndroidSpecificState PlatformSpecificState;
-typedef AndroidFlingAnimation FlingAnimation;
 #else
 typedef GenericOverscrollEffect OverscrollEffect;
 typedef PlatformSpecificStateBase PlatformSpecificState;  // no extra state, just use the base class
-typedef GenericFlingAnimation FlingAnimation;
 #endif
 
 /**
  * \page APZCPrefs APZ preferences
  *
  * The following prefs are used to control the behaviour of the APZC.
  * The default values are provided in gfxPrefs.h.
  *
@@ -511,16 +509,26 @@ static bool IsCloseToHorizontal(float aA
 static bool IsCloseToVertical(float aAngle, float aThreshold)
 {
   return (fabs(aAngle - (M_PI / 2)) < aThreshold);
 }
 
 // Counter used to give each APZC a unique id
 static uint32_t sAsyncPanZoomControllerCount = 0;
 
+AsyncPanZoomAnimation*
+PlatformSpecificStateBase::CreateFlingAnimation(AsyncPanZoomController& aApzc,
+                                                const FlingHandoffState& aHandoffState)
+{
+  return new GenericFlingAnimation(aApzc,
+      aHandoffState.mChain,
+      aHandoffState.mIsHandoff,
+      aHandoffState.mScrolledApzc);
+}
+
 TimeStamp
 AsyncPanZoomController::GetFrameTime() const
 {
   APZCTreeManager* treeManagerLocal = GetApzcTreeManager();
   return treeManagerLocal ? treeManagerLocal->GetFrameTime() : TimeStamp::Now();
 }
 
 class MOZ_STACK_CLASS StateChangeNotificationBlocker {
@@ -3006,21 +3014,17 @@ ParentLayerPoint AsyncPanZoomController:
   }
 
   // If there's a scroll snap point near the predicted fling destination,
   // scroll there using a smooth scroll animation. Otherwise, start a
   // fling animation.
   ScrollSnapToDestination();
   if (mState != SMOOTH_SCROLL) {
     SetState(FLING);
-    FlingAnimation *fling = new FlingAnimation(*this,
-        GetPlatformSpecificState(),
-        aHandoffState.mChain,
-        aHandoffState.mIsHandoff,
-        aHandoffState.mScrolledApzc);
+    AsyncPanZoomAnimation* fling = GetPlatformSpecificState()->CreateFlingAnimation(*this, aHandoffState);
     StartAnimation(fling);
   }
 
   return residualVelocity;
 }
 
 ParentLayerPoint AsyncPanZoomController::AdjustHandoffVelocityForOverscrollBehavior(ParentLayerPoint& aHandoffVelocity) const
 {
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -64,16 +64,18 @@ class GenericOverscrollEffect;
 class AndroidSpecificState;
 struct KeyboardScrollAction;
 
 // Base class for grouping platform-specific APZC state variables.
 class PlatformSpecificStateBase {
 public:
   virtual ~PlatformSpecificStateBase() = default;
   virtual AndroidSpecificState* AsAndroidSpecificState() { return nullptr; }
+  virtual AsyncPanZoomAnimation* CreateFlingAnimation(AsyncPanZoomController& aApzc,
+                                                      const FlingHandoffState& aHandoffState);
 };
 
 /*
  * Represents a transform from the ParentLayer coordinate space of an APZC
  * to the ParentLayer coordinate space of its parent APZC.
  * Each layer along the way contributes to the transform. We track
  * contributions that are perspective transforms separately, as sometimes
  * these require special handling.
--- a/gfx/layers/apz/src/GenericFlingAnimation.h
+++ b/gfx/layers/apz/src/GenericFlingAnimation.h
@@ -25,17 +25,16 @@
 // #define FLING_LOG(...) printf_stderr("FLING: " __VA_ARGS__)
 
 namespace mozilla {
 namespace layers {
 
 class GenericFlingAnimation: public AsyncPanZoomAnimation {
 public:
   GenericFlingAnimation(AsyncPanZoomController& aApzc,
-                        PlatformSpecificStateBase* aPlatformSpecificState,
                         const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
                         bool aFlingIsHandedOff,
                         const RefPtr<const AsyncPanZoomController>& aScrolledApzc)
     : mApzc(aApzc)
     , mOverscrollHandoffChain(aOverscrollHandoffChain)
     , mScrolledApzc(aScrolledApzc)
   {
     MOZ_ASSERT(mOverscrollHandoffChain);