Bug 1448439 - Allow the concrete type of fling animations to be determined dynamically. r=kats
MozReview-Commit-ID: EBscYyxdlwr
--- 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);