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
This commit is contained in:
Marin Shalamanov
2021-03-16 18:03:30 +01:00
parent 41b3b73ece
commit 511f9145ba
7 changed files with 61 additions and 47 deletions

View File

@@ -47801,11 +47801,13 @@ package android.view {
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 @@ package android.view {
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);

View File

@@ -97,7 +97,7 @@ public class Surface implements Parcelable {
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 class Surface implements Parcelable {
*/
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 @@ public class Surface implements Parcelable {
* 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 @@ public class Surface implements Parcelable {
* 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);
}
/**

View File

@@ -209,7 +209,7 @@ public final class SurfaceControl implements Parcelable {
@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 @@ public final class SurfaceControl implements Parcelable {
* 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 @@ public final class SurfaceControl implements Parcelable {
* 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;
}

View File

@@ -438,7 +438,7 @@ static jint nativeSetAutoRefreshEnabled(JNIEnv* env, jclass clazz, jlong nativeO
}
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 @@ static jint nativeSetFrameRate(JNIEnv* env, jclass clazz, jlong nativeObject, jf
// 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 @@ static const JNINativeMethod gSurfaceMethods[] = {
(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},
};

View File

@@ -782,7 +782,7 @@ static void nativeSetShadowRadius(JNIEnv* env, jclass clazz, jlong transactionOb
}
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 @@ static void nativeSetFrameRate(JNIEnv* env, jclass clazz, jlong transactionObj,
// 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 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*) nativeSetStretchEffect },
{"nativeSetShadowRadius", "(JJF)V",
(void*)nativeSetShadowRadius },
{"nativeSetFrameRate", "(JJFIZ)V",
{"nativeSetFrameRate", "(JJFII)V",
(void*)nativeSetFrameRate },
{"nativeAcquireFrameRateFlexibilityToken", "()J",
(void*)nativeAcquireFrameRateFlexibilityToken },

View File

@@ -253,7 +253,7 @@ LIBANDROID {
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

View File

@@ -596,24 +596,25 @@ void ASurfaceTransaction_setColor(ASurfaceTransaction* aSurfaceTransaction,
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);
}