Bug 1448439 - Add a pref to get APZ to use the Chrome fling physics on Android. r=kats
MozReview-Commit-ID: HDLDlwjov82
--- a/gfx/layers/apz/src/AndroidAPZ.cpp
+++ b/gfx/layers/apz/src/AndroidAPZ.cpp
@@ -1,18 +1,20 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AndroidAPZ.h"
+#include "AndroidFlingPhysics.h"
#include "AsyncPanZoomController.h"
#include "GeneratedJNIWrappers.h"
+#include "GenericFlingAnimation.h"
#include "gfxPrefs.h"
#include "OverscrollHandoffState.h"
#include "ViewConfiguration.h"
#define ANDROID_APZ_LOG(...)
// #define ANDROID_APZ_LOG(...) printf_stderr("ANDROID_APZ: " __VA_ARGS__)
static float sMaxFlingSpeed = 0.0f;
@@ -41,21 +43,35 @@ AndroidSpecificState::AndroidSpecificSta
return;
}
mOverScroller = scroller;
}
AsyncPanZoomAnimation*
AndroidSpecificState::CreateFlingAnimation(AsyncPanZoomController& aApzc,
const FlingHandoffState& aHandoffState) {
- return new StackScrollerFlingAnimation(aApzc,
- this,
- aHandoffState.mChain,
- aHandoffState.mIsHandoff,
- aHandoffState.mScrolledApzc);
+ if (gfxPrefs::APZUseChromeFlingPhysics()) {
+ return new GenericFlingAnimation<AndroidFlingPhysics>(aApzc,
+ aHandoffState.mChain,
+ aHandoffState.mIsHandoff,
+ aHandoffState.mScrolledApzc);
+ } else {
+ return new StackScrollerFlingAnimation(aApzc,
+ this,
+ aHandoffState.mChain,
+ aHandoffState.mIsHandoff,
+ aHandoffState.mScrolledApzc);
+ }
+}
+
+/* static */ void
+AndroidSpecificState::InitializeGlobalState() {
+ // Not conditioned on gfxPrefs::APZUseChromeFlingPhysics() because
+ // the pref is live.
+ AndroidFlingPhysics::InitializeGlobalState();
}
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.
--- a/gfx/layers/apz/src/AndroidAPZ.h
+++ b/gfx/layers/apz/src/AndroidAPZ.h
@@ -20,16 +20,18 @@ public:
virtual AndroidSpecificState* AsAndroidSpecificState() override {
return this;
}
virtual AsyncPanZoomAnimation* CreateFlingAnimation(AsyncPanZoomController& aApzc,
const FlingHandoffState& aHandoffState) override;
+ static void InitializeGlobalState();
+
java::StackScroller::GlobalRef mOverScroller;
TimeStamp mLastFling;
};
class StackScrollerFlingAnimation: public AsyncPanZoomAnimation {
public:
StackScrollerFlingAnimation(AsyncPanZoomController& aApzc,
PlatformSpecificStateBase* aPlatformSpecificState,
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -133,16 +133,20 @@ typedef PlatformSpecificStateBase Platfo
* \li\b apz.allow_checkerboarding
* Pref that allows or disallows checkerboarding
*
* \li\b apz.allow_immediate_handoff
* If set to true, scroll can be handed off from one APZC to another within
* a single input block. If set to false, a single input block can only
* scroll one APZC.
*
+ * \li\b apz.android.chrome_fling_physics.enabled
+ * If set to true, APZ uses a fling physical model similar to Chrome's
+ * on Android, rather than Android's StackScroller.
+ *
* \li\b apz.autoscroll.enabled
* If set to true, autoscrolling is driven by APZ rather than the content
* process main thread.
*
* \li\b apz.axis_lock.mode
* The preferred axis locking style. See AxisLockMode for possible values.
*
* \li\b apz.axis_lock.lock_angle
@@ -777,16 +781,18 @@ AsyncPanZoomController::InitializeGlobal
gfxPrefs::APZCurveFunctionY1(),
gfxPrefs::APZCurveFunctionX2(),
gfxPrefs::APZCurveFunctionY2()));
ClearOnShutdown(&gVelocityCurveFunction);
uint64_t sysmem = PR_GetPhysicalMemorySize();
uint64_t threshold = 1LL << 32; // 4 GB in bytes
gIsHighMemSystem = sysmem >= threshold;
+
+ PlatformSpecificState::InitializeGlobalState();
}
AsyncPanZoomController::AsyncPanZoomController(LayersId aLayersId,
APZCTreeManager* aTreeManager,
const RefPtr<InputQueue>& aInputQueue,
GeckoContentController* aGeckoContentController,
GestureBehavior aGestures)
: mLayersId(aLayersId),
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -68,16 +68,18 @@ 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);
+
+ static void InitializeGlobalState() {}
};
/*
* 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/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -285,16 +285,17 @@ private:
// a method accessing a pref already exists. Just add yours in the list.
DECL_GFX_PREF(Live, "accessibility.browsewithcaret", AccessibilityBrowseWithCaret, bool, false);
// The apz prefs are explained in AsyncPanZoomController.cpp
DECL_GFX_PREF(Live, "apz.allow_checkerboarding", APZAllowCheckerboarding, bool, true);
DECL_GFX_PREF(Live, "apz.allow_immediate_handoff", APZAllowImmediateHandoff, bool, true);
DECL_GFX_PREF(Live, "apz.allow_zooming", APZAllowZooming, bool, false);
+ DECL_GFX_PREF(Live, "apz.android.chrome_fling_physics.enabled", APZUseChromeFlingPhysics, bool, false);
DECL_GFX_PREF(Live, "apz.autoscroll.enabled", APZAutoscrollEnabled, bool, false);
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_angle", APZAxisBreakoutAngle, float, float(M_PI / 8.0) /* 22.5 degrees */);
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_threshold", APZAxisBreakoutThreshold, float, 1.0f / 32.0f);
DECL_GFX_PREF(Live, "apz.axis_lock.direct_pan_angle", APZAllowedDirectPanAngle, float, float(M_PI / 3.0) /* 60 degrees */);
DECL_GFX_PREF(Live, "apz.axis_lock.lock_angle", APZAxisLockAngle, float, float(M_PI / 6.0) /* 30 degrees */);
DECL_GFX_PREF(Live, "apz.axis_lock.mode", APZAxisLockMode, int32_t, 0);
DECL_GFX_PREF(Live, "apz.content_response_timeout", APZContentResponseTimeout, int32_t, 400);
DECL_GFX_PREF(Live, "apz.danger_zone_x", APZDangerZoneX, int32_t, 50);
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -621,16 +621,17 @@ pref("layers.geometry.basic.enabled", tr
// Whether to enable arbitrary layer geometry for DirectX compositor
pref("layers.geometry.d3d11.enabled", true);
// APZ preferences. For documentation/details on what these prefs do, check
// gfx/layers/apz/src/AsyncPanZoomController.cpp.
pref("apz.allow_checkerboarding", true);
pref("apz.allow_immediate_handoff", true);
pref("apz.allow_zooming", false);
+pref("apz.android.chrome_fling_physics.enabled", false);
pref("apz.autoscroll.enabled", true);
// Whether to lock touch scrolling to one axis at a time
// 0 = FREE (No locking at all)
// 1 = STANDARD (Once locked, remain locked until scrolling ends)
// 2 = STICKY (Allow lock to be broken, with hysteresis)
pref("apz.axis_lock.mode", 0);
pref("apz.axis_lock.lock_angle", "0.5235987"); // PI / 6 (30 degrees)