summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNader Jawad <njawad@google.com>2021-03-17 15:12:58 -0700
committerNader Jawad <njawad@google.com>2021-03-18 22:41:42 -0700
commita225d21f7d586d1484af38a55f8d949d076a4d5c (patch)
treef5dc60ec0ec35c4d8adb69a3a476020d2874ced6
parent78af4257ecebcf73c113ef927942a062aefef3e6 (diff)
Updated EdgeEffect parameters for overscroll stretch
Added dampening logic to caluclate the distance to overscroll. Updated StretchEffect to support independent maximum stretch amounts for the x/y axis Removed debugging parameters to configure stretch distance since they are no longer used. Removed hidden API calls to configure stretch distance in ScrollView/HorizontalScrollView Bug: 179047472 Test: re-ran EdgeEffectTests Change-Id: I4698669273d364695a21c2cce00ec2cfec41b2cc
-rw-r--r--core/java/android/widget/EdgeEffect.java50
-rw-r--r--core/java/android/widget/HorizontalScrollView.java20
-rw-r--r--core/java/android/widget/ScrollView.java20
-rw-r--r--graphics/java/android/graphics/RenderNode.java17
-rw-r--r--libs/hwui/effects/StretchEffect.cpp24
-rw-r--r--libs/hwui/effects/StretchEffect.h17
-rw-r--r--libs/hwui/jni/android_graphics_RenderNode.cpp11
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/EdgeEffectStretchActivity.java7
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java4
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/StretchShaderActivity.java1
-rw-r--r--tests/HwAccelerationTest/src/com/android/test/hwui/StretchySurfaceViewActivity.java3
11 files changed, 67 insertions, 107 deletions
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 3c411126627f..5f55887d6019 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -130,7 +130,11 @@ public class EdgeEffect {
public @interface EdgeEffectType {
}
- private static final float DEFAULT_MAX_STRETCH_INTENSITY = 0.08f;
+ private static final float LINEAR_STRETCH_INTENSITY = 0.03f;
+
+ private static final float EXP_STRETCH_INTENSITY = 0.02f;
+
+ private static final float SCROLL_DIST_AFFECTED_BY_EXP_STRETCH = 0.4f;
@SuppressWarnings("UnusedDeclaration")
private static final String TAG = "EdgeEffect";
@@ -176,9 +180,6 @@ public class EdgeEffect {
private long mStartTime;
private float mDuration;
- private float mStretchIntensity = DEFAULT_MAX_STRETCH_INTENSITY;
- private float mStretchDistanceFraction = 1f;
- private float mStretchDistance = -1f;
private final Interpolator mInterpolator = new DecelerateInterpolator();
@@ -269,16 +270,6 @@ public class EdgeEffect {
}
/**
- * Configure the distance in pixels to stretch the content. This is only consumed as part
- * if {@link #setType(int)} is set to {@link #TYPE_STRETCH}
- * @param stretchDistance Stretch distance in pixels when the target View is overscrolled
- * @hide
- */
- public void setStretchDistance(float stretchDistance) {
- mStretchDistance = stretchDistance;
- }
-
- /**
* Reports if this EdgeEffect's animation is finished. If this method returns false
* after a call to {@link #draw(Canvas)} the host widget should schedule another
* drawing pass to continue the animation.
@@ -520,13 +511,6 @@ public class EdgeEffect {
}
/**
- * @hide
- */
- public void setMaxStretchIntensity(float stretchIntensity) {
- mStretchIntensity = stretchIntensity;
- }
-
- /**
* Set or clear the blend mode. A blend mode defines how source pixels
* (generated by a drawing command) are composited with the destination pixels
* (content of the render target).
@@ -642,22 +626,19 @@ public class EdgeEffect {
// assume rotations of increments of 90 degrees
float x = mTmpPoints[10] - mTmpPoints[8];
float width = right - left;
- float vecX = Math.max(-1f, Math.min(1f, x / width));
+ float vecX = dampStretchVector(Math.max(-1f, Math.min(1f, x / width)));
float y = mTmpPoints[11] - mTmpPoints[9];
float height = bottom - top;
- float vecY = Math.max(-1f, Math.min(1f, y / height));
+ float vecY = dampStretchVector(Math.max(-1f, Math.min(1f, y / height)));
renderNode.stretch(
left,
top,
right,
bottom,
- vecX * mStretchIntensity,
- vecY * mStretchIntensity,
- // TODO (njawad/mount) figure out proper stretch distance from UX
- // for now leverage placeholder logic if no stretch distance is provided to
- // consume the displacement ratio times the minimum of the width or height
- mStretchDistance > 0 ? mStretchDistance :
- (mStretchDistanceFraction * Math.max(mWidth, mHeight))
+ vecX,
+ vecY,
+ mWidth,
+ mHeight
);
}
@@ -794,4 +775,13 @@ public class EdgeEffect {
return Math.abs(mVelocity) < VELOCITY_THRESHOLD
&& Math.abs(displacement) < VALUE_THRESHOLD;
}
+
+ private float dampStretchVector(float normalizedVec) {
+ float sign = normalizedVec > 0 ? 1f : -1f;
+ float overscroll = Math.abs(normalizedVec);
+ float linearIntensity = LINEAR_STRETCH_INTENSITY * overscroll;
+ double scalar = Math.E / SCROLL_DIST_AFFECTED_BY_EXP_STRETCH;
+ double expIntensity = EXP_STRETCH_INTENSITY * (1 - Math.exp(-overscroll * scalar));
+ return sign * (float) (linearIntensity + expIntensity);
+ }
}
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index bf552e2a501c..23915e06335a 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -249,26 +249,6 @@ public class HorizontalScrollView extends FrameLayout {
}
/**
- * API used for prototyping stretch effect parameters in framework sample apps
- * @hide
- */
- public void setEdgeEffectIntensity(float intensity) {
- mEdgeGlowLeft.setMaxStretchIntensity(intensity);
- mEdgeGlowRight.setMaxStretchIntensity(intensity);
- invalidate();
- }
-
- /**
- * API used for prototyping stretch effect parameters in the framework sample apps
- * @hide
- */
- public void setStretchDistance(float distance) {
- mEdgeGlowLeft.setStretchDistance(distance);
- mEdgeGlowRight.setStretchDistance(distance);
- invalidate();
- }
-
- /**
* Sets the right edge effect color.
*
* @param color The color for the right edge effect.
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 30067296f967..65f3da79afe0 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -281,26 +281,6 @@ public class ScrollView extends FrameLayout {
}
/**
- * API used for prototyping stretch effect parameters in framework sample apps
- * @hide
- */
- public void setEdgeEffectIntensity(float intensity) {
- mEdgeGlowTop.setMaxStretchIntensity(intensity);
- mEdgeGlowBottom.setMaxStretchIntensity(intensity);
- invalidate();
- }
-
- /**
- * API used for prototyping stretch effect parameters in the framework sample apps
- * @hide
- */
- public void setStretchDistance(float distance) {
- mEdgeGlowTop.setStretchDistance(distance);
- mEdgeGlowBottom.setStretchDistance(distance);
- invalidate();
- }
-
- /**
* Sets the bottom edge effect color.
*
* @param color The color for the bottom edge effect.
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index da5162b9e15e..6fcd8d09a770 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -275,6 +275,8 @@ public final class RenderNode {
* Call to apply a stretch effect to any child SurfaceControl layers
*
* TODO: Fold this into positionChanged & have HWUI do the ASurfaceControl calls?
+ * (njawad) update to consume different stretch parameters for horizontal/vertical stretch
+ * to ensure SkiaGLRenderEngine can also apply the same stretch to a surface
*
* @hide
*/
@@ -718,7 +720,7 @@ public final class RenderNode {
/** @hide */
public boolean stretch(float left, float top, float right, float bottom,
- float vecX, float vecY, float maxStretchAmount) {
+ float vecX, float vecY, float maxStretchAmountX, float maxStretchAmountY) {
if (Float.isInfinite(vecX) || Float.isNaN(vecX)) {
throw new IllegalArgumentException("vecX must be a finite, non-NaN value " + vecX);
}
@@ -730,9 +732,13 @@ public final class RenderNode {
"Stretch region must not be empty, got "
+ new RectF(left, top, right, bottom).toString());
}
- if (maxStretchAmount <= 0.0f) {
+ if (maxStretchAmountX <= 0.0f) {
throw new IllegalArgumentException(
- "The max stretch amount must be >0, got " + maxStretchAmount);
+ "The max horizontal stretch amount must be >0, got " + maxStretchAmountX);
+ }
+ if (maxStretchAmountY <= 0.0f) {
+ throw new IllegalArgumentException(
+ "The max vertical stretch amount must be >0, got " + maxStretchAmountY);
}
return nStretch(
mNativeRenderNode,
@@ -742,7 +748,8 @@ public final class RenderNode {
bottom,
vecX,
vecY,
- maxStretchAmount
+ maxStretchAmountX,
+ maxStretchAmountY
);
}
@@ -1695,7 +1702,7 @@ public final class RenderNode {
@CriticalNative
private static native boolean nStretch(long renderNode, float left, float top, float right,
- float bottom, float vecX, float vecY, float maxStretch);
+ float bottom, float vecX, float vecY, float maxStretchX, float maxStretchY);
@CriticalNative
private static native boolean nHasShadow(long renderNode);
diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp
index d4fd1053b17f..9e4fb8fc9b35 100644
--- a/libs/hwui/effects/StretchEffect.cpp
+++ b/libs/hwui/effects/StretchEffect.cpp
@@ -33,7 +33,8 @@ static const SkString stretchShader = SkString(R"(
uniform float uMaxStretchIntensity;
// Maximum percentage to stretch beyond bounds of target
- uniform float uStretchAffectedDist;
+ uniform float uStretchAffectedDistX;
+ uniform float uStretchAffectedDistY;
// Distance stretched as a function of the normalized overscroll times
// scale intensity
@@ -138,7 +139,7 @@ static const SkString stretchShader = SkString(R"(
outU,
inU,
uOverscrollX,
- uStretchAffectedDist,
+ uStretchAffectedDistX,
uDistanceStretchedX,
uDistDiffX
);
@@ -146,7 +147,7 @@ static const SkString stretchShader = SkString(R"(
outV,
inV,
uOverscrollY,
- uStretchAffectedDist,
+ uStretchAffectedDistY,
uDistanceStretchedY,
uDistDiffY
);
@@ -166,16 +167,14 @@ sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapsho
return mStretchFilter;
}
- float distanceNotStretchedX = maxStretchAmount / stretchArea.width();
- float distanceNotStretchedY = maxStretchAmount / stretchArea.height();
- float normOverScrollDistX = mStretchDirection.x();
- float normOverScrollDistY = mStretchDirection.y();
- float distanceStretchedX = maxStretchAmount / (1 + abs(normOverScrollDistX));
- float distanceStretchedY = maxStretchAmount / (1 + abs(normOverScrollDistY));
- float diffX = distanceStretchedX - distanceNotStretchedX;
- float diffY = distanceStretchedY - distanceNotStretchedY;
float viewportWidth = stretchArea.width();
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;
if (mBuilder == nullptr) {
mBuilder = std::make_unique<SkRuntimeShaderBuilder>(getStretchEffect());
@@ -183,7 +182,8 @@ sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapsho
mBuilder->child("uContentTexture") = snapshotImage->makeShader(
SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions(SkFilterMode::kLinear));
- mBuilder->uniform("uStretchAffectedDist").set(&maxStretchAmount, 1);
+ mBuilder->uniform("uStretchAffectedDistX").set(&maxStretchAmountX, 1);
+ mBuilder->uniform("uStretchAffectedDistY").set(&maxStretchAmountY, 1);
mBuilder->uniform("uDistanceStretchedX").set(&distanceStretchedX, 1);
mBuilder->uniform("uDistanceStretchedY").set(&distanceStretchedY, 1);
mBuilder->uniform("uDistDiffX").set(&diffX, 1);
diff --git a/libs/hwui/effects/StretchEffect.h b/libs/hwui/effects/StretchEffect.h
index d2da06b31f68..8221b41ff4e5 100644
--- a/libs/hwui/effects/StretchEffect.h
+++ b/libs/hwui/effects/StretchEffect.h
@@ -33,8 +33,12 @@ public:
SmoothStep,
};
- StretchEffect(const SkRect& area, const SkVector& direction, float maxStretchAmount)
- : stretchArea(area), maxStretchAmount(maxStretchAmount), mStretchDirection(direction) {}
+ StretchEffect(const SkRect& area, const SkVector& direction, float maxStretchAmountX,
+ float maxStretchAmountY)
+ : stretchArea(area)
+ , maxStretchAmountX(maxStretchAmountX)
+ , maxStretchAmountY(maxStretchAmountY)
+ , mStretchDirection(direction) {}
StretchEffect() {}
@@ -50,7 +54,8 @@ public:
this->stretchArea = other.stretchArea;
this->mStretchDirection = other.mStretchDirection;
this->mStretchFilter = nullptr;
- this->maxStretchAmount = other.maxStretchAmount;
+ this->maxStretchAmountX = other.maxStretchAmountX;
+ this->maxStretchAmountY = other.maxStretchAmountY;
return *this;
}
@@ -67,13 +72,15 @@ public:
return setEmpty();
}
stretchArea.join(other.stretchArea);
- maxStretchAmount = std::max(maxStretchAmount, other.maxStretchAmount);
+ maxStretchAmountX = std::max(maxStretchAmountX, other.maxStretchAmountX);
+ maxStretchAmountY = std::max(maxStretchAmountY, other.maxStretchAmountY);
}
sk_sp<SkImageFilter> getImageFilter(const sk_sp<SkImage>& snapshotImage) const;
SkRect stretchArea {0, 0, 0, 0};
- float maxStretchAmount = 0;
+ float maxStretchAmountX = 0;
+ float maxStretchAmountY = 0;
void setStretchDirection(const SkVector& direction) {
mStretchFilter = nullptr;
diff --git a/libs/hwui/jni/android_graphics_RenderNode.cpp b/libs/hwui/jni/android_graphics_RenderNode.cpp
index fc7d0d181949..fffa80614370 100644
--- a/libs/hwui/jni/android_graphics_RenderNode.cpp
+++ b/libs/hwui/jni/android_graphics_RenderNode.cpp
@@ -181,9 +181,10 @@ static jboolean android_view_RenderNode_clearStretch(CRITICAL_JNI_PARAMS_COMMA j
static jboolean android_view_RenderNode_stretch(CRITICAL_JNI_PARAMS_COMMA jlong renderNodePtr,
jfloat left, jfloat top, jfloat right,
- jfloat bottom, jfloat vX, jfloat vY, jfloat max) {
- StretchEffect effect =
- StretchEffect(SkRect::MakeLTRB(left, top, right, bottom), {.fX = vX, .fY = vY}, max);
+ jfloat bottom, jfloat vX, jfloat vY, jfloat maxX,
+ jfloat maxY) {
+ StretchEffect effect = StretchEffect(SkRect::MakeLTRB(left, top, right, bottom),
+ {.fX = vX, .fY = vY}, maxX, maxY);
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
renderNode->mutateStagingProperties().mutateLayerProperties().mutableStretchEffect().mergeWith(
effect);
@@ -662,7 +663,7 @@ static void android_view_RenderNode_requestPositionUpdates(JNIEnv* env, jobject,
env->CallVoidMethod(localref, gPositionListener_ApplyStretchMethod,
info.canvasContext.getFrameNumber(), area.left, area.top,
area.right, area.bottom, stretchDirection.fX, stretchDirection.fY,
- effect->maxStretchAmount);
+ effect->maxStretchAmountX, effect->maxStretchAmountY);
#endif
env->DeleteLocalRef(localref);
}
@@ -738,7 +739,7 @@ static const JNINativeMethod gMethods[] = {
{"nSetOutlineEmpty", "(J)Z", (void*)android_view_RenderNode_setOutlineEmpty},
{"nSetOutlineNone", "(J)Z", (void*)android_view_RenderNode_setOutlineNone},
{"nClearStretch", "(J)Z", (void*)android_view_RenderNode_clearStretch},
- {"nStretch", "(JFFFFFFF)Z", (void*)android_view_RenderNode_stretch},
+ {"nStretch", "(JFFFFFFFF)Z", (void*)android_view_RenderNode_stretch},
{"nHasShadow", "(J)Z", (void*)android_view_RenderNode_hasShadow},
{"nSetSpotShadowColor", "(JI)Z", (void*)android_view_RenderNode_setSpotShadowColor},
{"nGetSpotShadowColor", "(J)I", (void*)android_view_RenderNode_getSpotShadowColor},
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/EdgeEffectStretchActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/EdgeEffectStretchActivity.java
index f0e6299f09e9..c4b0072eaff8 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/EdgeEffectStretchActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/EdgeEffectStretchActivity.java
@@ -18,8 +18,6 @@ package com.android.test.hwui;
import android.app.Activity;
import android.os.Bundle;
-import android.widget.HorizontalScrollView;
-import android.widget.ScrollView;
public class EdgeEffectStretchActivity extends Activity {
@@ -27,10 +25,5 @@ public class EdgeEffectStretchActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.stretch_layout);
- HorizontalScrollView hsv = findViewById(R.id.horizontal_scroll_view);
- hsv.setStretchDistance(50f);
-
- ScrollView sv = findViewById(R.id.scroll_view);
- sv.setStretchDistance(50f);
}
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java
index 65d7363ad628..6b6287da2711 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PositionListenerActivity.java
@@ -75,11 +75,11 @@ public class PositionListenerActivity extends Activity {
// Although we could do this in a single call, the real one won't be - so mimic that
if (dir.x != 0f) {
node.stretch(0f, 0f, (float) getWidth(), (float) getHeight(),
- dir.x, 0f, maxStretchAmount);
+ dir.x, 0f, maxStretchAmount, maxStretchAmount);
}
if (dir.y != 0f) {
node.stretch(0f, 0f, (float) getWidth(), (float) getHeight(),
- 0f, dir.y, maxStretchAmount);
+ 0f, dir.y, maxStretchAmount, maxStretchAmount);
}
}
};
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/StretchShaderActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/StretchShaderActivity.java
index 9bd933afa07d..912aee686924 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/StretchShaderActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/StretchShaderActivity.java
@@ -415,6 +415,7 @@ public class StretchShaderActivity extends Activity {
bounds.height(),
mOverScrollX,
mOverScrollY,
+ mStretchDistance,
mStretchDistance
);
}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/StretchySurfaceViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/StretchySurfaceViewActivity.java
index d6042445c2d8..67b9be580ba6 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/StretchySurfaceViewActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/StretchySurfaceViewActivity.java
@@ -99,7 +99,8 @@ public class StretchySurfaceViewActivity extends Activity implements Callback {
super.onDraw(canvas);
RenderNode node = ((RecordingCanvas) canvas).mNode;
- node.stretch(0f, 0f, getWidth(), getHeight() / 2f, 0f, 1f, 400f);
+ node.stretch(0f, 0f, getWidth(), getHeight() / 2f, 0f,
+ 1f, 400f, 400f);
}
};