diff options
| -rw-r--r-- | core/java/android/view/View.java | 19 | ||||
| -rw-r--r-- | core/tests/coretests/src/android/view/ViewFrameRateTest.java | 31 |
2 files changed, 41 insertions, 9 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 64c77661d9f4..5f8bea1cdc47 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -34071,14 +34071,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } private float convertVelocityToFrameRate(float velocityPps) { - // From UXR study, premium experience is: - // 1500+ dp/s: 120fps - // 0 - 1500 dp/s: 80fps - // OEMs are likely to modify this to balance battery and user experience for their - // specific device. + // Internal testing has shown that this gives a premium experience: + // above 300dp/s => 120fps + // between 300dp/s and 125fps => 80fps + // below 125dp/s => 60fps float density = mAttachInfo.mDensity; float velocityDps = velocityPps / density; - return (velocityDps >= 1500f) ? MAX_FRAME_RATE : 80f; + float frameRate; + if (velocityDps > 300f) { + frameRate = MAX_FRAME_RATE; // Use maximum at fast motion + } else if (velocityDps > 125f) { + frameRate = 80f; // Use medium frame rate when motion is slower + } else { + frameRate = 60f; // Use minimum frame rate when motion is very slow + } + return frameRate; } /** diff --git a/core/tests/coretests/src/android/view/ViewFrameRateTest.java b/core/tests/coretests/src/android/view/ViewFrameRateTest.java index 18364ad5e2b6..b8ff59528b24 100644 --- a/core/tests/coretests/src/android/view/ViewFrameRateTest.java +++ b/core/tests/coretests/src/android/view/ViewFrameRateTest.java @@ -278,7 +278,7 @@ public class ViewFrameRateTest { @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API, FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY, FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY}) - public void lowVelocity80() throws Throwable { + public void lowVelocity60() throws Throwable { if (!ViewProperties.vrr_enabled().orElse(true)) { return; } @@ -292,6 +292,31 @@ public class ViewFrameRateTest { mActivityRule.runOnUiThread(() -> { mMovingView.setFrameContentVelocity(1f); mMovingView.invalidate(); + runAfterDraw(() -> assertEquals(60f, mViewRoot.getLastPreferredFrameRate(), 0f)); + }); + waitForAfterDraw(); + } + + @Test + @RequiresFlagsEnabled({FLAG_VIEW_VELOCITY_API, + FLAG_TOOLKIT_FRAME_RATE_VELOCITY_MAPPING_READ_ONLY, + FLAG_TOOLKIT_FRAME_RATE_VIEW_ENABLING_READ_ONLY}) + public void midVelocity80() throws Throwable { + if (!ViewProperties.vrr_enabled().orElse(true)) { + return; + } + mActivityRule.runOnUiThread(() -> { + ViewGroup.LayoutParams layoutParams = mMovingView.getLayoutParams(); + layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT; + layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT; + mMovingView.setLayoutParams(layoutParams); + }); + waitForFrameRateCategoryToSettle(); + mActivityRule.runOnUiThread(() -> { + float midSpeed = + 200f * mMovingView.getContext().getResources().getDisplayMetrics().density; + mMovingView.setFrameContentVelocity(midSpeed); + mMovingView.invalidate(); runAfterDraw(() -> assertEquals(80f, mViewRoot.getLastPreferredFrameRate(), 0f)); }); waitForAfterDraw(); @@ -321,7 +346,7 @@ public class ViewFrameRateTest { frameLayout.setFrameContentVelocity(1f); mMovingView.offsetTopAndBottom(100); frameLayout.invalidate(); - runAfterDraw(() -> assertEquals(80f, mViewRoot.getLastPreferredFrameRate(), 0f)); + runAfterDraw(() -> assertEquals(60f, mViewRoot.getLastPreferredFrameRate(), 0f)); }); waitForAfterDraw(); } @@ -590,7 +615,7 @@ public class ViewFrameRateTest { runAfterDraw(() -> { assertEquals(FRAME_RATE_CATEGORY_LOW, mViewRoot.getLastPreferredFrameRateCategory()); - assertEquals(80f, mViewRoot.getLastPreferredFrameRate()); + assertEquals(60f, mViewRoot.getLastPreferredFrameRate()); }); }); waitForAfterDraw(); |