Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7575ba83 authored by George Mount's avatar George Mount Committed by Automerger Merge Worker
Browse files

Merge "Linearly complete overscroll stretch when close" into sc-dev am: 5a1f9df8

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15081295

Change-Id: Id136442430f10e324d95a04ec1a88da1194a95df
parents edd6a72e 5a1f9df8
Loading
Loading
Loading
Loading
+79 −43
Original line number Diff line number Diff line
@@ -97,12 +97,28 @@ public class EdgeEffect {
     */
    private static final double VELOCITY_THRESHOLD = 0.01;

    /**
     * The speed at which we should start linearly interpolating to the destination.
     * When using a spring, as it gets closer to the destination, the speed drops off exponentially.
     * Instead of landing very slowly, a better experience is achieved if the final
     * destination is arrived at quicker.
     */
    private static final float LINEAR_VELOCITY_TAKE_OVER = 200f;

    /**
     * The value threshold before the spring animation is considered close enough to
     * the destination to be settled. This should be around 0.01 pixel.
     */
    private static final double VALUE_THRESHOLD = 0.001;

    /**
     * The maximum distance at which we should start linearly interpolating to the destination.
     * When using a spring, as it gets closer to the destination, the speed drops off exponentially.
     * Instead of landing very slowly, a better experience is achieved if the final
     * destination is arrived at quicker.
     */
    private static final double LINEAR_DISTANCE_TAKE_OVER = 8.0;

    /**
     * The natural frequency of the stretch spring.
     */
@@ -587,6 +603,7 @@ public class EdgeEffect {
            if (mState == STATE_RECEDE) {
                updateSpring();
            }
            if (mDistance != 0f) {
                RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
                if (mTmpMatrix == null) {
                    mTmpMatrix = new Matrix();
@@ -637,6 +654,7 @@ public class EdgeEffect {
                        mHeight // max vertical stretch in pixels
                    );
                }
            }
        } else {
            // Animations have been disabled or this is TYPE_STRETCH and drawing into a Canvas
            // that isn't a Recording Canvas, so no effect can be shown. Just end the effect.
@@ -730,6 +748,26 @@ public class EdgeEffect {
        if (deltaT < 0.001f) {
            return; // Must have at least 1 ms difference
        }
        mStartTime = time;

        if (Math.abs(mVelocity) <= LINEAR_VELOCITY_TAKE_OVER
                && Math.abs(mDistance * mHeight) < LINEAR_DISTANCE_TAKE_OVER
                && Math.signum(mVelocity) == -Math.signum(mDistance)
        ) {
            // This is close. The spring will slowly reach the destination. Instead, we
            // will interpolate linearly so that it arrives at its destination quicker.
            mVelocity = Math.signum(mVelocity) * LINEAR_VELOCITY_TAKE_OVER;

            float targetDistance = mDistance + (mVelocity * deltaT / mHeight);
            if (Math.signum(targetDistance) != Math.signum(mDistance)) {
                // We have arrived
                mDistance = 0;
                mVelocity = 0;
            } else {
                mDistance = targetDistance;
            }
            return;
        }
        final double mDampedFreq = NATURAL_FREQUENCY * Math.sqrt(1 - DAMPING_RATIO * DAMPING_RATIO);

        // We're always underdamped, so we can use only those equations:
@@ -745,9 +783,7 @@ public class EdgeEffect {
                + mDampedFreq * sinCoeff * Math.cos(mDampedFreq * deltaT));
        mDistance = (float) distance / mHeight;
        mVelocity = (float) velocity;
        mStartTime = time;
        if (isAtEquilibrium()) {
            mState = STATE_IDLE;
            mDistance = 0;
            mVelocity = 0;
        }
+13 −3
Original line number Diff line number Diff line
@@ -40,9 +40,7 @@ public:

    StretchEffect() {}

    bool isEmpty() const {
        return MathUtils::isZero(mStretchDirection.x()) && MathUtils::isZero(mStretchDirection.y());
    }
    bool isEmpty() const { return isZero(mStretchDirection.x()) && isZero(mStretchDirection.y()); }

    void setEmpty() {
        *this = StretchEffect{};
@@ -118,6 +116,18 @@ public:
    }

private:
    // The epsilon for StretchEffect is less than in MathUtils because
    // the range is 0-1 for an entire screen and should be significantly
    // less than 1 pixel for a smooth stretch animation.
    inline static bool isZero(float value) {
        // Using fabsf is more performant as ARM computes
        // fabsf in a single instruction.
        return fabsf(value) <= NON_ZERO_EPSILON;
    }
    // This should be good for 1/25,000 of a screen and should be good for
    // screens with less than ~8000 pixels in one dimension with only 1/4 pixel
    // cut-off.
    static constexpr float NON_ZERO_EPSILON = 0.00004f;
    static sk_sp<SkRuntimeEffect> getStretchEffect();
    mutable SkVector mStretchDirection{0, 0};
    mutable std::unique_ptr<SkRuntimeShaderBuilder> mBuilder;