diff options
author | Scott Lobdell <slobdell@google.com> | 2021-04-08 04:27:11 +0000 |
---|---|---|
committer | Scott Lobdell <slobdell@google.com> | 2021-04-09 17:32:37 +0000 |
commit | 5f1da148b08c14445ce83ca151a84f75e489d274 (patch) | |
tree | df59b2056d1fe2dbe09f6c85463ddf1769daf4e6 /libs/hwui/effects/StretchEffect.cpp | |
parent | 702f04add003ce3e490a2f0bdff083a7e6f5979e (diff) | |
parent | 851218af5f83cdb89c02d680fb22212318150068 (diff) |
Merge SP1A.210407.002
Change-Id: Iaad2b7cc2aeba166f003d0d460bc8ce29d1caab3
Diffstat (limited to 'libs/hwui/effects/StretchEffect.cpp')
-rw-r--r-- | libs/hwui/effects/StretchEffect.cpp | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp index 9e4fb8fc9b35..d7162b9872d5 100644 --- a/libs/hwui/effects/StretchEffect.cpp +++ b/libs/hwui/effects/StretchEffect.cpp @@ -40,6 +40,8 @@ static const SkString stretchShader = SkString(R"( // 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,48 +60,57 @@ static const SkString stretchShader = SkString(R"( uniform float viewportWidth; // target height in pixels uniform float viewportHeight; // target width in pixels - void computeOverscrollStart( - out float outPos, + 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; - outPos = distanceStretched - (offsetPos / (1. + stretchIntensity)); + return distanceStretched - (offsetPos / (1. + stretchIntensity)); } - void computeOverscrollEnd( - out float outPos, + float computeOverscrollEnd( float inPos, 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; - outPos = 1 - (distanceStretched - (offsetPos / (1. + stretchIntensity))); + return 1 - (distanceStretched - (offsetPos / (1. + stretchIntensity))); } - void computeOverscroll( - out float outPos, + // Prefer usage of return values over out parameters as it enables + // SKSL to properly inline method calls and works around potential GPU + // driver issues on Wembly. See b/182566543 for details + float computeOverscroll( float inPos, float overscroll, float uStretchAffectedDist, + float uInverseStretchAffectedDist, float distanceStretched, float distanceDiff ) { - if (overscroll > 0) { + float outPos = inPos; + if (overscroll > 0) { if (inPos <= uStretchAffectedDist) { - computeOverscrollStart( - outPos, + outPos = computeOverscrollStart( inPos, overscroll, uStretchAffectedDist, + uInverseStretchAffectedDist, distanceStretched ); } else if (inPos >= distanceStretched) { @@ -109,18 +120,19 @@ static const SkString stretchShader = SkString(R"( if (overscroll < 0) { float stretchAffectedDist = 1. - uStretchAffectedDist; if (inPos >= stretchAffectedDist) { - computeOverscrollEnd( - outPos, + outPos = computeOverscrollEnd( inPos, overscroll, stretchAffectedDist, uStretchAffectedDist, + uInverseStretchAffectedDist, distanceStretched ); } else if (inPos < stretchAffectedDist) { outPos = -distanceDiff + inPos; } } + return outPos; } vec4 main(vec2 coord) { @@ -135,19 +147,19 @@ static const SkString stretchShader = SkString(R"( inV += uScrollY; outU = inU; outV = inV; - computeOverscroll( - outU, + outU = computeOverscroll( inU, uOverscrollX, uStretchAffectedDistX, + uInverseDistanceStretchedX, uDistanceStretchedX, uDistDiffX ); - computeOverscroll( - outV, + outV = computeOverscroll( inV, uOverscrollY, uStretchAffectedDistY, + uInverseDistanceStretchedY, uDistanceStretchedY, uDistDiffY ); @@ -157,6 +169,7 @@ static const SkString stretchShader = SkString(R"( })"); 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()) { @@ -171,10 +184,12 @@ sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapsho 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 / CONTENT_DISTANCE_STRETCHED; + float inverseDistanceStretchedY = 1.f / CONTENT_DISTANCE_STRETCHED; + float diffX = distanceStretchedX - CONTENT_DISTANCE_STRETCHED; + float diffY = distanceStretchedY - CONTENT_DISTANCE_STRETCHED; if (mBuilder == nullptr) { mBuilder = std::make_unique<SkRuntimeShaderBuilder>(getStretchEffect()); @@ -182,10 +197,12 @@ sk_sp<SkImageFilter> StretchEffect::getImageFilter(const sk_sp<SkImage>& snapsho 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); |