Updated StretchEffect to use cubic easing

Updated SKSL shader to use cubic easing
instead of smoothstep. Fixed issue where
max stretch distances were not being normalized

Fixes: 184198532
Bug: 183768138
Test: re-ran EdgeEffect tests + manual
Change-Id: I1c4811e71c09b5e807235e3fb30755d8d6430a54
diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp
index 0804e0ae..bd1c154 100644
--- a/libs/hwui/effects/StretchEffect.cpp
+++ b/libs/hwui/effects/StretchEffect.cpp
@@ -40,6 +40,8 @@
     // scale intensity
     uniform float uDistanceStretchedX;
     uniform float uDistanceStretchedY;
+    uniform float uInverseDistanceStretchedX;
+    uniform float uInverseDistanceStretchedY;
     uniform float uDistDiffX;
 
     // Difference between the peak stretch amount and overscroll amount normalized
@@ -58,14 +60,20 @@
     uniform float viewportWidth; // target height in pixels
     uniform float viewportHeight; // target width in pixels
 
+    float easeInCubic(float t, float d) {
+        float tmp = t * d;
+        return tmp * tmp * tmp;
+    }
+
     float computeOverscrollStart(
         float inPos,
         float overscroll,
         float uStretchAffectedDist,
+        float uInverseStretchAffectedDist,
         float distanceStretched
     ) {
         float offsetPos = uStretchAffectedDist - inPos;
-        float posBasedVariation = smoothstep(0., uStretchAffectedDist, offsetPos);
+        float posBasedVariation = easeInCubic(offsetPos, uInverseStretchAffectedDist);
         float stretchIntensity = overscroll * posBasedVariation;
         return distanceStretched - (offsetPos / (1. + stretchIntensity));
     }
@@ -75,10 +83,11 @@
         float overscroll,
         float reverseStretchDist,
         float uStretchAffectedDist,
+        float uInverseStretchAffectedDist,
         float distanceStretched
     ) {
         float offsetPos = inPos - reverseStretchDist;
-        float posBasedVariation = (smoothstep(0., uStretchAffectedDist, offsetPos));
+        float posBasedVariation = easeInCubic(offsetPos, uInverseStretchAffectedDist);
         float stretchIntensity = (-overscroll) * posBasedVariation;
         return 1 - (distanceStretched - (offsetPos / (1. + stretchIntensity)));
     }
@@ -90,6 +99,7 @@
         float inPos,
         float overscroll,
         float uStretchAffectedDist,
+        float uInverseStretchAffectedDist,
         float distanceStretched,
         float distanceDiff
     ) {
@@ -100,6 +110,7 @@
                   inPos,
                   overscroll,
                   uStretchAffectedDist,
+                  uInverseStretchAffectedDist,
                   distanceStretched
                 );
             } else if (inPos >= distanceStretched) {
@@ -114,6 +125,7 @@
                   overscroll,
                   stretchAffectedDist,
                   uStretchAffectedDist,
+                  uInverseStretchAffectedDist,
                   distanceStretched
                 );
             } else if (inPos < stretchAffectedDist) {
@@ -139,6 +151,7 @@
             inU,
             uOverscrollX,
             uStretchAffectedDistX,
+            uInverseDistanceStretchedX,
             uDistanceStretchedX,
             uDistDiffX
         );
@@ -146,6 +159,7 @@
             inV,
             uOverscrollY,
             uStretchAffectedDistY,
+            uInverseDistanceStretchedY,
             uDistanceStretchedY,
             uDistDiffY
         );
@@ -155,6 +169,7 @@
     })");
 
 static const float ZERO = 0.f;
+static const float CONTENT_DISTANCE_STRETCHED = 1.f;
 
 sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapshotImage) const {
     if (isEmpty()) {
@@ -169,10 +184,12 @@
     float viewportHeight = stretchArea.height();
     float normOverScrollDistX = mStretchDirection.x();
     float normOverScrollDistY = mStretchDirection.y();
-    float distanceStretchedX = maxStretchAmountX / (1 + abs(normOverScrollDistX));
-    float distanceStretchedY = maxStretchAmountY / (1 + abs(normOverScrollDistY));
-    float diffX = distanceStretchedX;
-    float diffY = distanceStretchedY;
+    float distanceStretchedX = CONTENT_DISTANCE_STRETCHED / (1 + abs(normOverScrollDistX));
+    float distanceStretchedY = CONTENT_DISTANCE_STRETCHED / (1 + abs(normOverScrollDistY));
+    float inverseDistanceStretchedX = 1.f / distanceStretchedX;
+    float inverseDistanceStretchedY = 1.f / distanceStretchedY;
+    float diffX = distanceStretchedX - CONTENT_DISTANCE_STRETCHED;
+    float diffY = distanceStretchedY - CONTENT_DISTANCE_STRETCHED;
 
     if (mBuilder == nullptr) {
         mBuilder = std::make_unique<SkRuntimeShaderBuilder>(getStretchEffect());
@@ -180,10 +197,12 @@
 
     mBuilder->child("uContentTexture") = snapshotImage->makeShader(
             SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions(SkFilterMode::kLinear));
-    mBuilder->uniform("uStretchAffectedDistX").set(&maxStretchAmountX, 1);
-    mBuilder->uniform("uStretchAffectedDistY").set(&maxStretchAmountY, 1);
+    mBuilder->uniform("uStretchAffectedDistX").set(&CONTENT_DISTANCE_STRETCHED, 1);
+    mBuilder->uniform("uStretchAffectedDistY").set(&CONTENT_DISTANCE_STRETCHED, 1);
     mBuilder->uniform("uDistanceStretchedX").set(&distanceStretchedX, 1);
     mBuilder->uniform("uDistanceStretchedY").set(&distanceStretchedY, 1);
+    mBuilder->uniform("uInverseDistanceStretchedX").set(&inverseDistanceStretchedX, 1);
+    mBuilder->uniform("uInverseDistanceStretchedY").set(&inverseDistanceStretchedY, 1);
     mBuilder->uniform("uDistDiffX").set(&diffX, 1);
     mBuilder->uniform("uDistDiffY").set(&diffY, 1);
     mBuilder->uniform("uOverscrollX").set(&normOverScrollDistX, 1);