setFrameRate: Make shouldBeSeamless an enum
Change the shouldBeSeamless parameter to an enum
in order to make the API easier to understand.
This changes
- SurfaceControl.setFrameRate
- Surface.setFrameRate
- ANativeWindow_setFrameRateWithChangeStrategy
- ASurfaceTransaction_setFrameRateWithChangeStrategy
Bug: 179116474
Test: atest SetFrameRateTest
Change-Id: I55265399238e2c95fbb90fd33a4c2513d1fc5cec
diff --git a/core/api/current.txt b/core/api/current.txt
index 4aa38d6..5d05f4f 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -47801,11 +47801,13 @@
method public android.graphics.Canvas lockHardwareCanvas();
method public void readFromParcel(android.os.Parcel);
method public void release();
- method public void setFrameRate(@FloatRange(from=0.0) float, int, boolean);
+ method public void setFrameRate(@FloatRange(from=0.0) float, int, int);
method public void setFrameRate(@FloatRange(from=0.0) float, int);
method @Deprecated public void unlockCanvas(android.graphics.Canvas);
method public void unlockCanvasAndPost(android.graphics.Canvas);
method public void writeToParcel(android.os.Parcel, int);
+ field public static final int CHANGE_FRAME_RATE_ALWAYS = 1; // 0x1
+ field public static final int CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0; // 0x0
field @NonNull public static final android.os.Parcelable.Creator<android.view.Surface> CREATOR;
field public static final int FRAME_RATE_COMPATIBILITY_DEFAULT = 0; // 0x0
field public static final int FRAME_RATE_COMPATIBILITY_FIXED_SOURCE = 1; // 0x1
@@ -47849,7 +47851,7 @@
method @NonNull public android.view.SurfaceControl.Transaction setAlpha(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0, to=1.0) float);
method @NonNull public android.view.SurfaceControl.Transaction setBufferSize(@NonNull android.view.SurfaceControl, @IntRange(from=0) int, @IntRange(from=0) int);
method @NonNull public android.view.SurfaceControl.Transaction setFrameRate(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0) float, int);
- method @NonNull public android.view.SurfaceControl.Transaction setFrameRate(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0) float, int, boolean);
+ method @NonNull public android.view.SurfaceControl.Transaction setFrameRate(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0) float, int, int);
method @NonNull public android.view.SurfaceControl.Transaction setGeometry(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, int);
method @NonNull public android.view.SurfaceControl.Transaction setLayer(@NonNull android.view.SurfaceControl, @IntRange(from=java.lang.Integer.MIN_VALUE, to=java.lang.Integer.MAX_VALUE) int);
method @NonNull public android.view.SurfaceControl.Transaction setVisibility(@NonNull android.view.SurfaceControl, boolean);
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index f8c4d15..aa3c9d6 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -97,7 +97,7 @@
private static native int nativeSetAutoRefreshEnabled(long nativeObject, boolean enabled);
private static native int nativeSetFrameRate(
- long nativeObject, float frameRate, int compatibility, boolean shouldBeSeamless);
+ long nativeObject, float frameRate, int compatibility, int changeFrameRateStrategy);
public static final @android.annotation.NonNull Parcelable.Creator<Surface> CREATOR =
new Parcelable.Creator<Surface>() {
@@ -226,6 +226,26 @@
*/
public static final int FRAME_RATE_COMPATIBILITY_EXACT = 100;
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"CHANGE_FRAME_RATE_"},
+ value = {CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS, CHANGE_FRAME_RATE_ALWAYS})
+ public @interface ChangeFrameRateStrategy {}
+
+ /**
+ * Change the frame rate only if the transition is going to be seamless.
+ */
+ public static final int CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS = 0;
+
+ /**
+ * Change the frame rate even if the transition is going to be non-seamless, i.e. with visual
+ * interruptions for the user. Non-seamless switches might be used when the benefit of matching
+ * the content's frame rate outweighs the cost of the transition, for example when
+ * displaying long-running video content.
+ */
+ public static final int CHANGE_FRAME_RATE_ALWAYS = 1;
+
/**
* Create an empty surface, which will later be filled in by readFromParcel().
* @hide
@@ -921,25 +941,21 @@
* the display at 60fps.
*
* @param compatibility The frame rate compatibility of this surface. The
- * compatibility value may influence the system's choice of display frame rate. See
- * the FRAME_RATE_COMPATIBILITY_* values for more info.
+ * compatibility value may influence the system's choice of display frame rate.
*
- * @param shouldBeSeamless Whether display refresh rate transitions should be seamless. A
+ * @param changeFrameRateStrategy Whether display refresh rate transitions should be seamless. A
* seamless transition is one that doesn't have any visual interruptions, such as a black
- * screen for a second or two. True indicates that any frame rate changes caused by this
- * request should be seamless. False indicates that non-seamless refresh rates are also
- * acceptable. Non-seamless switches might be used when the benefit of matching the content's
- * frame rate outweighs the cost of the transition, for example when displaying
- * long-running video content.
+ * screen for a second or two.
*
* @throws IllegalArgumentException If frameRate or compatibility are invalid.
*/
public void setFrameRate(@FloatRange(from = 0.0) float frameRate,
- @FrameRateCompatibility int compatibility, boolean shouldBeSeamless) {
+ @FrameRateCompatibility int compatibility,
+ @ChangeFrameRateStrategy int changeFrameRateStrategy) {
synchronized (mLock) {
checkNotReleasedLocked();
int error = nativeSetFrameRate(mNativeObject, frameRate, compatibility,
- shouldBeSeamless);
+ changeFrameRateStrategy);
if (error == -EINVAL) {
throw new IllegalArgumentException("Invalid argument to Surface.setFrameRate()");
} else if (error != 0) {
@@ -952,11 +968,11 @@
* Sets the intended frame rate for this surface. Any switching of refresh rates is
* most probably going to be seamless.
*
- * @see #setFrameRate(float, int, boolean)
+ * @see #setFrameRate(float, int, int)
*/
public void setFrameRate(
@FloatRange(from = 0.0) float frameRate, @FrameRateCompatibility int compatibility) {
- setFrameRate(frameRate, compatibility, /* shouldBeSeamless = */ true);
+ setFrameRate(frameRate, compatibility, CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
}
/**
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 03dd100..dd470e5 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -209,7 +209,7 @@
@Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius);
private static native void nativeSetFrameRate(long transactionObj, long nativeObject,
- float frameRate, int compatibility, boolean shouldBeSeamless);
+ float frameRate, int compatibility, int changeFrameRateStrategy);
private static native long nativeGetHandle(long nativeObject);
private static native long nativeAcquireFrameRateFlexibilityToken();
@@ -3229,13 +3229,14 @@
* Sets the intended frame rate for this surface. Any switching of refresh rates is
* most probably going to be seamless.
*
- * @see #setFrameRate(SurfaceControl, float, int, boolean)
+ * @see #setFrameRate(SurfaceControl, float, int, int)
*/
@NonNull
public Transaction setFrameRate(@NonNull SurfaceControl sc,
@FloatRange(from = 0.0) float frameRate,
@Surface.FrameRateCompatibility int compatibility) {
- return setFrameRate(sc, frameRate, compatibility, /*shouldBeSeamless*/ true);
+ return setFrameRate(sc, frameRate, compatibility,
+ Surface.CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
}
/**
@@ -3256,27 +3257,21 @@
* refresh rate for this device's display - e.g., it's fine to pass 30fps
* to a device that can only run the display at 60fps.
* @param compatibility The frame rate compatibility of this surface. The compatibility
- * value may influence the system's choice of display frame rate. See
- * the Surface.FRAME_RATE_COMPATIBILITY_* values for more info.
- * @param shouldBeSeamless Whether display refresh rate transitions should be seamless. A
- * seamless transition is one that doesn't have any visual
- * interruptions, such as a black screen for a second or two. True
- * indicates that any frame rate changes caused by this request
- * should be seamless. False indicates that non-seamless refresh
- * rates are also acceptable. Non-seamless switches might be
- * used when the benefit of matching the content's frame rate
- * outweighs the cost of the transition, for example when
- * displaying long-running video content.
+ * value may influence the system's choice of display frame rate.
+ * @param changeFrameRateStrategy Whether display refresh rate transitions should be
+ * seamless. A seamless transition is one that doesn't have
+ * any visual interruptions, such as a black screen for a
+ * second or two.
* @return This transaction object.
*/
@NonNull
public Transaction setFrameRate(@NonNull SurfaceControl sc,
@FloatRange(from = 0.0) float frameRate,
@Surface.FrameRateCompatibility int compatibility,
- boolean shouldBeSeamless) {
+ @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) {
checkPreconditions(sc);
nativeSetFrameRate(mNativeObject, sc.mNativeObject, frameRate, compatibility,
- shouldBeSeamless);
+ changeFrameRateStrategy);
return this;
}
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 5b29f0b..0957067 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -438,7 +438,7 @@
}
static jint nativeSetFrameRate(JNIEnv* env, jclass clazz, jlong nativeObject, jfloat frameRate,
- jint compatibility, jboolean shouldBeSeamless) {
+ jint compatibility, jint changeFrameRateStrategy) {
Surface* surface = reinterpret_cast<Surface*>(nativeObject);
ANativeWindow* anw = static_cast<ANativeWindow*>(surface);
// Our compatibility is a Surface.FRAME_RATE_COMPATIBILITY_* value, and
@@ -446,7 +446,7 @@
// ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* value. The values are identical
// though, so no need to explicitly convert.
return anw->perform(surface, NATIVE_WINDOW_SET_FRAME_RATE, double(frameRate), compatibility,
- int(shouldBeSeamless));
+ int(changeFrameRateStrategy));
}
// ----------------------------------------------------------------------------
@@ -475,7 +475,7 @@
(void*)nativeAttachAndQueueBufferWithColorSpace},
{"nativeSetSharedBufferModeEnabled", "(JZ)I", (void*)nativeSetSharedBufferModeEnabled},
{"nativeSetAutoRefreshEnabled", "(JZ)I", (void*)nativeSetAutoRefreshEnabled},
- {"nativeSetFrameRate", "(JFIZ)I", (void*)nativeSetFrameRate},
+ {"nativeSetFrameRate", "(JFII)I", (void*)nativeSetFrameRate},
{"nativeGetFromBlastBufferQueue", "(JJ)J", (void*)nativeGetFromBlastBufferQueue},
};
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 31cc77f..b10c80a 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -782,7 +782,7 @@
}
static void nativeSetFrameRate(JNIEnv* env, jclass clazz, jlong transactionObj, jlong nativeObject,
- jfloat frameRate, jint compatibility, jboolean shouldBeSeamless) {
+ jfloat frameRate, jint compatibility, jint changeFrameRateStrategy) {
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
const auto ctrl = reinterpret_cast<SurfaceControl*>(nativeObject);
@@ -790,7 +790,7 @@
// Transaction::setFrameRate() takes an ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_* value. The
// values are identical though, so no need to convert anything.
transaction->setFrameRate(ctrl, frameRate, static_cast<int8_t>(compatibility),
- bool(shouldBeSeamless));
+ static_cast<int8_t>(changeFrameRateStrategy));
}
static jlong nativeAcquireFrameRateFlexibilityToken(JNIEnv* env, jclass clazz) {
@@ -1775,7 +1775,7 @@
(void*) nativeSetStretchEffect },
{"nativeSetShadowRadius", "(JJF)V",
(void*)nativeSetShadowRadius },
- {"nativeSetFrameRate", "(JJFIZ)V",
+ {"nativeSetFrameRate", "(JJFII)V",
(void*)nativeSetFrameRate },
{"nativeAcquireFrameRateFlexibilityToken", "()J",
(void*)nativeAcquireFrameRateFlexibilityToken },
diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt
index b01878b..1de6221 100644
--- a/native/android/libandroid.map.txt
+++ b/native/android/libandroid.map.txt
@@ -253,7 +253,7 @@
ASurfaceTransaction_setDamageRegion; # introduced=29
ASurfaceTransaction_setDesiredPresentTime; # introduced=29
ASurfaceTransaction_setFrameRate; # introduced=30
- ASurfaceTransaction_setFrameRateWithSeamlessness; # introduced=31
+ ASurfaceTransaction_setFrameRateWithChangeStrategy; # introduced=31
ASurfaceTransaction_setGeometry; # introduced=29
ASurfaceTransaction_setHdrMetadata_cta861_3; # introduced=29
ASurfaceTransaction_setHdrMetadata_smpte2086; # introduced=29
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index e8cf63f..6c12c43 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -596,24 +596,25 @@
color.g = g;
color.b = b;
- transaction->setBackgroundColor(surfaceControl, color, alpha, static_cast<ui::Dataspace>(dataspace));
+ transaction->setBackgroundColor(surfaceControl, color, alpha,
+ static_cast<ui::Dataspace>(dataspace));
}
void ASurfaceTransaction_setFrameRate(ASurfaceTransaction* aSurfaceTransaction,
ASurfaceControl* aSurfaceControl, float frameRate,
int8_t compatibility) {
- ASurfaceTransaction_setFrameRateWithSeamlessness(aSurfaceTransaction, aSurfaceControl,
- frameRate, compatibility,
- /*shouldBeSeamless*/ true);
+ ASurfaceTransaction_setFrameRateWithChangeStrategy(
+ aSurfaceTransaction, aSurfaceControl, frameRate, compatibility,
+ ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS);
}
-void ASurfaceTransaction_setFrameRateWithSeamlessness(ASurfaceTransaction* aSurfaceTransaction,
- ASurfaceControl* aSurfaceControl,
- float frameRate, int8_t compatibility,
- bool shouldBeSeamless) {
+void ASurfaceTransaction_setFrameRateWithChangeStrategy(ASurfaceTransaction* aSurfaceTransaction,
+ ASurfaceControl* aSurfaceControl,
+ float frameRate, int8_t compatibility,
+ int8_t changeFrameRateStrategy) {
CHECK_NOT_NULL(aSurfaceTransaction);
CHECK_NOT_NULL(aSurfaceControl);
Transaction* transaction = ASurfaceTransaction_to_Transaction(aSurfaceTransaction);
sp<SurfaceControl> surfaceControl = ASurfaceControl_to_SurfaceControl(aSurfaceControl);
- transaction->setFrameRate(surfaceControl, frameRate, compatibility, shouldBeSeamless);
+ transaction->setFrameRate(surfaceControl, frameRate, compatibility, changeFrameRateStrategy);
}