summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/View.java19
-rw-r--r--core/tests/coretests/src/android/view/ViewFrameRateTest.java31
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();