Bug 1448439 - Add a pref to get APZ to use the Chrome fling physics on Android. r=kats draft
authorBotond Ballo <botond@mozilla.com>
Fri, 20 Apr 2018 18:44:18 -0400
changeset 788683 c454a6769ccd0ca9951c41ef2ea9990c24208373
parent 788682 11a3ebd03430e0981be156638762987c7c07a458
child 788684 9acdec2fff2f95057cf2fc4da9fc8e86de4912f0
push id108063
push userbballo@mozilla.com
push dateThu, 26 Apr 2018 20:42:29 +0000
reviewerskats
bugs1448439
milestone61.0a1
Bug 1448439 - Add a pref to get APZ to use the Chrome fling physics on Android. r=kats MozReview-Commit-ID: HDLDlwjov82
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/thebes/gfxPrefs.h
modules/libpref/init/all.js
--- 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)