tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

FlingAccelerator.cpp (4736B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 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 #include "FlingAccelerator.h"
      8 
      9 #include "mozilla/StaticPrefs_apz.h"
     10 
     11 #include "GenericFlingAnimation.h"  // for FLING_LOG and FlingHandoffState
     12 
     13 namespace mozilla {
     14 namespace layers {
     15 
     16 void FlingAccelerator::Reset() {
     17  mPreviousFlingStartingVelocity = ParentLayerPoint{};
     18  mPreviousFlingCancelVelocity = ParentLayerPoint{};
     19  mIsTracking = false;
     20 }
     21 
     22 static bool SameDirection(float aVelocity1, float aVelocity2) {
     23  return (aVelocity1 == 0.0f) || (aVelocity2 == 0.0f) ||
     24         (IsNegative(aVelocity1) == IsNegative(aVelocity2));
     25 }
     26 
     27 static float Accelerate(float aBase, float aSupplemental) {
     28  return (aBase * StaticPrefs::apz_fling_accel_base_mult()) +
     29         (aSupplemental * StaticPrefs::apz_fling_accel_supplemental_mult());
     30 }
     31 
     32 ParentLayerPoint FlingAccelerator::GetFlingStartingVelocity(
     33    const SampleTime& aNow, const ParentLayerPoint& aVelocity,
     34    const FlingHandoffState& aHandoffState) {
     35  // If the fling should be accelerated and is in the same direction as the
     36  // previous fling, boost the velocity to be the sum of the two. Check separate
     37  // axes separately because we could have two vertical flings with small
     38  // horizontal components on the opposite side of zero, and we still want the
     39  // y-fling to get accelerated.
     40  ParentLayerPoint velocity = aVelocity;
     41  if (ShouldAccelerate(aNow, aVelocity, aHandoffState)) {
     42    if (velocity.x != 0 &&
     43        SameDirection(velocity.x, mPreviousFlingStartingVelocity.x)) {
     44      velocity.x = Accelerate(velocity.x, mPreviousFlingStartingVelocity.x);
     45      FLING_LOG("%p Applying fling x-acceleration from %f to %f (delta %f)\n",
     46                this, aVelocity.x.value, velocity.x.value,
     47                mPreviousFlingStartingVelocity.x.value);
     48    }
     49    if (velocity.y != 0 &&
     50        SameDirection(velocity.y, mPreviousFlingStartingVelocity.y)) {
     51      velocity.y = Accelerate(velocity.y, mPreviousFlingStartingVelocity.y);
     52      FLING_LOG("%p Applying fling y-acceleration from %f to %f (delta %f)\n",
     53                this, aVelocity.y.value, velocity.y.value,
     54                mPreviousFlingStartingVelocity.y.value);
     55    }
     56  }
     57 
     58  Reset();
     59 
     60  mPreviousFlingStartingVelocity = velocity;
     61  mIsTracking = true;
     62 
     63  return velocity;
     64 }
     65 
     66 bool FlingAccelerator::ShouldAccelerate(
     67    const SampleTime& aNow, const ParentLayerPoint& aVelocity,
     68    const FlingHandoffState& aHandoffState) const {
     69  if (!IsTracking()) {
     70    FLING_LOG("%p Fling accelerator was reset, not accelerating.\n", this);
     71    return false;
     72  }
     73 
     74  if (!aHandoffState.mTouchStartRestingTime) {
     75    FLING_LOG("%p Don't have a touch start resting time, not accelerating.\n",
     76              this);
     77    return false;
     78  }
     79 
     80  double msBetweenTouchStartAndPanStart =
     81      aHandoffState.mTouchStartRestingTime->ToMilliseconds();
     82  FLING_LOG(
     83      "%p ShouldAccelerate with pan velocity %f pixels/ms, min pan velocity %f "
     84      "pixels/ms, previous fling cancel velocity %f pixels/ms, time elapsed "
     85      "since starting previous time between touch start and pan "
     86      "start %fms.\n",
     87      this, float(aVelocity.Length()), float(aHandoffState.mMinPanVelocity),
     88      float(mPreviousFlingCancelVelocity.Length()),
     89      float(msBetweenTouchStartAndPanStart));
     90 
     91  if (aVelocity.Length() < StaticPrefs::apz_fling_accel_min_fling_velocity()) {
     92    FLING_LOG("%p Fling velocity too low (%f), not accelerating.\n", this,
     93              float(aVelocity.Length()));
     94    return false;
     95  }
     96 
     97  if (aHandoffState.mMinPanVelocity <
     98      StaticPrefs::apz_fling_accel_min_pan_velocity()) {
     99    FLING_LOG(
    100        "%p Panning velocity was too slow at some point during the pan (%f), "
    101        "not accelerating.\n",
    102        this, float(aHandoffState.mMinPanVelocity));
    103    return false;
    104  }
    105 
    106  if (mPreviousFlingCancelVelocity.Length() <
    107      StaticPrefs::apz_fling_accel_min_fling_velocity()) {
    108    FLING_LOG(
    109        "%p The previous fling animation had slowed down too much when it was "
    110        "interrupted (%f), not accelerating.\n",
    111        this, float(mPreviousFlingCancelVelocity.Length()));
    112    return false;
    113  }
    114 
    115  if (msBetweenTouchStartAndPanStart >=
    116      StaticPrefs::apz_fling_accel_max_pause_interval_ms()) {
    117    FLING_LOG(
    118        "%p Too much time (%fms) elapsed between touch start and pan start, "
    119        "not accelerating.\n",
    120        this, msBetweenTouchStartAndPanStart);
    121    return false;
    122  }
    123 
    124  return true;
    125 }
    126 
    127 }  // namespace layers
    128 }  // namespace mozilla