From 91a55b613d572497a660fb3303a6326d1844cd02 Mon Sep 17 00:00:00 2001 From: Nader Jawad Date: Thu, 13 May 2021 19:08:04 -0700 Subject: [PATCH 1/2] Improve Stretch shader performance Refactor stretch shader to return within conditional blocks instead of falling through to main function body. Improves performance on coral by approximately 60% ~600 fps to ~1k fps on non-surfaceview case ~300 fps to 500 fps on surfaceview case Bug: 187718492 Test: manual Change-Id: Ida0d0dee9c94b0ac210a024708100283fecc2a5c --- libs/hwui/effects/StretchEffect.cpp | 60 ++++++++++++++--------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp index 0599bfaf02f54..df480afcbe802 100644 --- a/libs/hwui/effects/StretchEffect.cpp +++ b/libs/hwui/effects/StretchEffect.cpp @@ -115,38 +115,37 @@ static const SkString stretchShader = SkString(R"( float distanceDiff, float interpolationStrength ) { - float outPos = inPos; if (overscroll > 0) { - if (inPos <= uStretchAffectedDist) { - outPos = computeOverscrollStart( - inPos, - overscroll, - uStretchAffectedDist, - uInverseStretchAffectedDist, - distanceStretched, - interpolationStrength - ); - } else if (inPos >= distanceStretched) { - outPos = distanceDiff + inPos; - } + if (inPos <= uStretchAffectedDist) { + return computeOverscrollStart( + inPos, + overscroll, + uStretchAffectedDist, + uInverseStretchAffectedDist, + distanceStretched, + interpolationStrength + ); + } else { + return distanceDiff + inPos; } - if (overscroll < 0) { - float stretchAffectedDist = 1. - uStretchAffectedDist; - if (inPos >= stretchAffectedDist) { - outPos = computeOverscrollEnd( - inPos, - overscroll, - stretchAffectedDist, - uStretchAffectedDist, - uInverseStretchAffectedDist, - distanceStretched, - interpolationStrength - ); - } else if (inPos < stretchAffectedDist) { - outPos = -distanceDiff + inPos; - } + } else if (overscroll < 0) { + float stretchAffectedDist = 1. - uStretchAffectedDist; + if (inPos >= stretchAffectedDist) { + return computeOverscrollEnd( + inPos, + overscroll, + stretchAffectedDist, + uStretchAffectedDist, + uInverseStretchAffectedDist, + distanceStretched, + interpolationStrength + ); + } else { + return -distanceDiff + inPos; } - return outPos; + } else { + return inPos; + } } vec4 main(vec2 coord) { @@ -155,12 +154,9 @@ static const SkString stretchShader = SkString(R"( float inV = coord.y / viewportHeight; float outU; float outV; - float stretchIntensity; // Add the normalized scroll position within scrolling list inU += uScrollX; inV += uScrollY; - outU = inU; - outV = inV; outU = computeOverscroll( inU, uOverscrollX, From 76d84aec28a1d00fe8807803e842bf17282814f3 Mon Sep 17 00:00:00 2001 From: Nader Jawad Date: Thu, 13 May 2021 20:43:18 -0700 Subject: [PATCH 2/2] Improve Stretch shader performance more Refactor stretch shader to always work in skia's coordinate system instead of normalizing the input coordinates. Improves performance on coral by approximately 10-20% across various use cases on top of the branching refactoring perf improvements ~1k fps to ~1.1k fps on non-surfaceview cases ~500 fps to ~600 fps o surfaceview cases Bug: 187718492 Test: manual Change-Id: I0b36f48699739979948bfec160a8aa64fc80b7a7 --- libs/hwui/effects/StretchEffect.cpp | 47 +++++++++++++++-------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/libs/hwui/effects/StretchEffect.cpp b/libs/hwui/effects/StretchEffect.cpp index df480afcbe802..807fb75e097c3 100644 --- a/libs/hwui/effects/StretchEffect.cpp +++ b/libs/hwui/effects/StretchEffect.cpp @@ -94,13 +94,14 @@ static const SkString stretchShader = SkString(R"( float uStretchAffectedDist, float uInverseStretchAffectedDist, float distanceStretched, - float interpolationStrength + float interpolationStrength, + float viewportDimension ) { float offsetPos = inPos - reverseStretchDist; float posBasedVariation = mix( 1. ,easeIn(offsetPos, uInverseStretchAffectedDist), interpolationStrength); float stretchIntensity = (-overscroll) * posBasedVariation; - return 1 - (distanceStretched - (offsetPos / (1. + stretchIntensity))); + return viewportDimension - (distanceStretched - (offsetPos / (1. + stretchIntensity))); } // Prefer usage of return values over out parameters as it enables @@ -113,7 +114,8 @@ static const SkString stretchShader = SkString(R"( float uInverseStretchAffectedDist, float distanceStretched, float distanceDiff, - float interpolationStrength + float interpolationStrength, + float viewportDimension ) { if (overscroll > 0) { if (inPos <= uStretchAffectedDist) { @@ -129,7 +131,7 @@ static const SkString stretchShader = SkString(R"( return distanceDiff + inPos; } } else if (overscroll < 0) { - float stretchAffectedDist = 1. - uStretchAffectedDist; + float stretchAffectedDist = viewportDimension - uStretchAffectedDist; if (inPos >= stretchAffectedDist) { return computeOverscrollEnd( inPos, @@ -138,7 +140,8 @@ static const SkString stretchShader = SkString(R"( uStretchAffectedDist, uInverseStretchAffectedDist, distanceStretched, - interpolationStrength + interpolationStrength, + viewportDimension ); } else { return -distanceDiff + inPos; @@ -149,12 +152,11 @@ static const SkString stretchShader = SkString(R"( } vec4 main(vec2 coord) { - // Normalize SKSL pixel coordinate into a unit vector - float inU = coord.x / viewportWidth; - float inV = coord.y / viewportHeight; + float inU = coord.x; + float inV = coord.y; float outU; float outV; - // Add the normalized scroll position within scrolling list + inU += uScrollX; inV += uScrollY; outU = computeOverscroll( @@ -164,7 +166,8 @@ static const SkString stretchShader = SkString(R"( uInverseDistanceStretchedX, uDistanceStretchedX, uDistDiffX, - uInterpolationStrength + uInterpolationStrength, + viewportWidth ); outV = computeOverscroll( inV, @@ -173,15 +176,15 @@ static const SkString stretchShader = SkString(R"( uInverseDistanceStretchedY, uDistanceStretchedY, uDistDiffY, - uInterpolationStrength + uInterpolationStrength, + viewportHeight ); - coord.x = outU * viewportWidth; - coord.y = outV * viewportHeight; + coord.x = outU; + coord.y = outV; return sample(uContentTexture, coord); })"); static const float ZERO = 0.f; -static const float CONTENT_DISTANCE_STRETCHED = 1.f; static const float INTERPOLATION_STRENGTH_VALUE = 0.7f; sk_sp StretchEffect::getShader(float width, float height, @@ -192,12 +195,12 @@ sk_sp StretchEffect::getShader(float width, float height, float normOverScrollDistX = mStretchDirection.x(); float normOverScrollDistY = mStretchDirection.y(); - 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; + float distanceStretchedX = width / (1 + abs(normOverScrollDistX)); + float distanceStretchedY = height / (1 + abs(normOverScrollDistY)); + float inverseDistanceStretchedX = 1.f / width; + float inverseDistanceStretchedY = 1.f / height; + float diffX = distanceStretchedX - width; + float diffY = distanceStretchedY - height; if (mBuilder == nullptr) { mBuilder = std::make_unique(getStretchEffect()); @@ -206,8 +209,8 @@ sk_sp StretchEffect::getShader(float width, float height, mBuilder->child("uContentTexture") = snapshotImage->makeShader( SkTileMode::kClamp, SkTileMode::kClamp, SkSamplingOptions(SkFilterMode::kLinear)); mBuilder->uniform("uInterpolationStrength").set(&INTERPOLATION_STRENGTH_VALUE, 1); - mBuilder->uniform("uStretchAffectedDistX").set(&CONTENT_DISTANCE_STRETCHED, 1); - mBuilder->uniform("uStretchAffectedDistY").set(&CONTENT_DISTANCE_STRETCHED, 1); + mBuilder->uniform("uStretchAffectedDistX").set(&width, 1); + mBuilder->uniform("uStretchAffectedDistY").set(&height, 1); mBuilder->uniform("uDistanceStretchedX").set(&distanceStretchedX, 1); mBuilder->uniform("uDistanceStretchedY").set(&distanceStretchedY, 1); mBuilder->uniform("uInverseDistanceStretchedX").set(&inverseDistanceStretchedX, 1);