Loading core/java/android/hardware/display/DisplayManagerInternal.java +1 −68 Original line number Diff line number Diff line Loading @@ -24,11 +24,11 @@ import android.hardware.SensorManager; import android.os.Handler; import android.os.PowerManager; import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; import android.view.SurfaceControl; import android.view.SurfaceControl.RefreshRateRange; import android.view.SurfaceControl.Transaction; import android.window.DisplayWindowPolicyController; import android.window.ScreenCapture; Loading @@ -36,7 +36,6 @@ import android.window.ScreenCapture; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.Objects; import java.util.Set; /** Loading Loading @@ -650,72 +649,6 @@ public abstract class DisplayManagerInternal { void onDisplayGroupChanged(int groupId); } /** * Information about the min and max refresh rate DM would like to set the display to. */ public static final class RefreshRateRange { public static final String TAG = "RefreshRateRange"; // The tolerance within which we consider something approximately equals. public static final float FLOAT_TOLERANCE = 0.01f; /** * The lowest desired refresh rate. */ public float min; /** * The highest desired refresh rate. */ public float max; public RefreshRateRange() {} public RefreshRateRange(float min, float max) { if (min < 0 || max < 0 || min > max + FLOAT_TOLERANCE) { Slog.e(TAG, "Wrong values for min and max when initializing RefreshRateRange : " + min + " " + max); this.min = this.max = 0; return; } if (min > max) { // Min and max are within epsilon of each other, but in the wrong order. float t = min; min = max; max = t; } this.min = min; this.max = max; } /** * Checks whether the two objects have the same values. */ @Override public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof RefreshRateRange)) { return false; } RefreshRateRange refreshRateRange = (RefreshRateRange) other; return (min == refreshRateRange.min && max == refreshRateRange.max); } @Override public int hashCode() { return Objects.hash(min, max); } @Override public String toString() { return "(" + min + " " + max + ")"; } } /** * Describes a limitation on a display's refresh rate. Includes the allowed refresh rate * range as well as information about when it applies, such as high-brightness-mode. Loading core/java/android/view/SurfaceControl.java +179 −35 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import android.util.SparseIntArray; import android.util.proto.ProtoOutputStream; import android.view.Surface.OutOfResourcesException; Loading Loading @@ -1673,6 +1674,146 @@ public final class SurfaceControl implements Parcelable { return nativeGetDisplayedContentSample(displayToken, maxFrames, timestamp); } /** * Information about the min and max refresh rate DM would like to set the display to. * @hide */ public static final class RefreshRateRange { public static final String TAG = "RefreshRateRange"; // The tolerance within which we consider something approximately equals. public static final float FLOAT_TOLERANCE = 0.01f; /** * The lowest desired refresh rate. */ public float min; /** * The highest desired refresh rate. */ public float max; public RefreshRateRange() {} public RefreshRateRange(float min, float max) { if (min < 0 || max < 0 || min > max + FLOAT_TOLERANCE) { Slog.e(TAG, "Wrong values for min and max when initializing RefreshRateRange : " + min + " " + max); this.min = this.max = 0; return; } if (min > max) { // Min and max are within epsilon of each other, but in the wrong order. float t = min; min = max; max = t; } this.min = min; this.max = max; } /** * Checks whether the two objects have the same values. */ @Override public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof RefreshRateRange)) { return false; } RefreshRateRange refreshRateRange = (RefreshRateRange) other; return (min == refreshRateRange.min && max == refreshRateRange.max); } @Override public int hashCode() { return Objects.hash(min, max); } @Override public String toString() { return "(" + min + " " + max + ")"; } /** * Copies the supplied object's values to this object. */ public void copyFrom(RefreshRateRange other) { this.min = other.min; this.max = other.max; } } /** * Information about the ranges of refresh rates for the display physical refresh rates and the * render frame rate DM would like to set the policy to. * @hide */ public static final class RefreshRateRanges { public static final String TAG = "RefreshRateRanges"; /** * The range of refresh rates that the display should run at. */ public final RefreshRateRange physical; /** * The range of refresh rates that apps should render at. */ public final RefreshRateRange render; public RefreshRateRanges() { physical = new RefreshRateRange(); render = new RefreshRateRange(); } public RefreshRateRanges(RefreshRateRange physical, RefreshRateRange render) { this.physical = new RefreshRateRange(physical.min, physical.max); this.render = new RefreshRateRange(render.min, render.max); } /** * Checks whether the two objects have the same values. */ @Override public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof RefreshRateRanges)) { return false; } RefreshRateRanges rates = (RefreshRateRanges) other; return physical.equals(rates.physical) && render.equals( rates.render); } @Override public int hashCode() { return Objects.hash(physical, render); } @Override public String toString() { return "physical: " + physical + " render: " + render; } /** * Copies the supplied object's values to this object. */ public void copyFrom(RefreshRateRanges other) { this.physical.copyFrom(other.physical); this.render.copyFrom(other.render); } } /** * Contains information about desired display configuration. Loading @@ -1682,44 +1823,49 @@ public final class SurfaceControl implements Parcelable { public static final class DesiredDisplayModeSpecs { public int defaultMode; /** * The primary refresh rate range represents display manager's general guidance on the * display configs surface flinger will consider when switching refresh rates. Unless * surface flinger has a specific reason to do otherwise, it will stay within this range. * If true this will allow switching between modes in different display configuration * groups. This way the user may see visual interruptions when the display mode changes. */ public float primaryRefreshRateMin; public float primaryRefreshRateMax; public boolean allowGroupSwitching; /** * The app request refresh rate range allows surface flinger to consider more display * configs when switching refresh rates. Although surface flinger will generally stay within * the primary range, specific considerations, such as layer frame rate settings specified * via the setFrameRate() api, may cause surface flinger to go outside the primary * range. Surface flinger never goes outside the app request range. The app request range * will be greater than or equal to the primary refresh rate range, never smaller. * The primary physical and render refresh rate ranges represent display manager's general * guidance on the display configs surface flinger will consider when switching refresh * rates and scheduling the frame rate. Unless surface flinger has a specific reason to do * otherwise, it will stay within this range. */ public float appRequestRefreshRateMin; public float appRequestRefreshRateMax; public final RefreshRateRanges primaryRanges; /** * If true this will allow switching between modes in different display configuration * groups. This way the user may see visual interruptions when the display mode changes. * The app request physical and render refresh rate ranges allow surface flinger to consider * more display configs when switching refresh rates. Although surface flinger will * generally stay within the primary range, specific considerations, such as layer frame * rate settings specified via the setFrameRate() api, may cause surface flinger to go * outside the primary range. Surface flinger never goes outside the app request range. * The app request range will be greater than or equal to the primary refresh rate range, * never smaller. */ public boolean allowGroupSwitching; public final RefreshRateRanges appRequestRanges; public DesiredDisplayModeSpecs() {} public DesiredDisplayModeSpecs() { this.primaryRanges = new RefreshRateRanges(); this.appRequestRanges = new RefreshRateRanges(); } public DesiredDisplayModeSpecs(DesiredDisplayModeSpecs other) { this.primaryRanges = new RefreshRateRanges(); this.appRequestRanges = new RefreshRateRanges(); copyFrom(other); } public DesiredDisplayModeSpecs(int defaultMode, boolean allowGroupSwitching, float primaryRefreshRateMin, float primaryRefreshRateMax, float appRequestRefreshRateMin, float appRequestRefreshRateMax) { RefreshRateRanges primaryRanges, RefreshRateRanges appRequestRanges) { this.defaultMode = defaultMode; this.allowGroupSwitching = allowGroupSwitching; this.primaryRefreshRateMin = primaryRefreshRateMin; this.primaryRefreshRateMax = primaryRefreshRateMax; this.appRequestRefreshRateMin = appRequestRefreshRateMin; this.appRequestRefreshRateMax = appRequestRefreshRateMax; this.primaryRanges = new RefreshRateRanges(primaryRanges.physical, primaryRanges.render); this.appRequestRanges = new RefreshRateRanges(appRequestRanges.physical, appRequestRanges.render); } @Override Loading @@ -1732,10 +1878,9 @@ public final class SurfaceControl implements Parcelable { */ public boolean equals(DesiredDisplayModeSpecs other) { return other != null && defaultMode == other.defaultMode && primaryRefreshRateMin == other.primaryRefreshRateMin && primaryRefreshRateMax == other.primaryRefreshRateMax && appRequestRefreshRateMin == other.appRequestRefreshRateMin && appRequestRefreshRateMax == other.appRequestRefreshRateMax; && allowGroupSwitching == other.allowGroupSwitching && primaryRanges.equals(other.primaryRanges) && appRequestRanges.equals(other.appRequestRanges); } @Override Loading @@ -1748,18 +1893,17 @@ public final class SurfaceControl implements Parcelable { */ public void copyFrom(DesiredDisplayModeSpecs other) { defaultMode = other.defaultMode; primaryRefreshRateMin = other.primaryRefreshRateMin; primaryRefreshRateMax = other.primaryRefreshRateMax; appRequestRefreshRateMin = other.appRequestRefreshRateMin; appRequestRefreshRateMax = other.appRequestRefreshRateMax; allowGroupSwitching = other.allowGroupSwitching; primaryRanges.copyFrom(other.primaryRanges); appRequestRanges.copyFrom(other.appRequestRanges); } @Override public String toString() { return String.format("defaultConfig=%d primaryRefreshRateRange=[%.0f %.0f]" + " appRequestRefreshRateRange=[%.0f %.0f]", defaultMode, primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin, appRequestRefreshRateMax); return "defaultMode=" + defaultMode + " allowGroupSwitching=" + allowGroupSwitching + " primaryRanges=" + primaryRanges + " appRequestRanges=" + appRequestRanges; } } Loading core/jni/android_view_SurfaceControl.cpp +116 −42 Original line number Diff line number Diff line Loading @@ -187,15 +187,27 @@ static struct { jfieldID white; } gDisplayPrimariesClassInfo; static struct { jclass clazz; jmethodID ctor; jfieldID min; jfieldID max; } gRefreshRateRangeClassInfo; static struct { jclass clazz; jmethodID ctor; jfieldID physical; jfieldID render; } gRefreshRateRangesClassInfo; static struct { jclass clazz; jmethodID ctor; jfieldID defaultMode; jfieldID allowGroupSwitching; jfieldID primaryRefreshRateMin; jfieldID primaryRefreshRateMax; jfieldID appRequestRefreshRateMin; jfieldID appRequestRefreshRateMax; jfieldID primaryRanges; jfieldID appRequestRanges; } gDesiredDisplayModeSpecsClassInfo; static struct { Loading Loading @@ -1190,6 +1202,39 @@ static jobject nativeGetDynamicDisplayInfo(JNIEnv* env, jclass clazz, jobject to return object; } struct RefreshRateRange { const float min; const float max; RefreshRateRange(float min, float max) : min(min), max(max) {} RefreshRateRange(JNIEnv* env, jobject obj) : min(env->GetFloatField(obj, gRefreshRateRangeClassInfo.min)), max(env->GetFloatField(obj, gRefreshRateRangeClassInfo.max)) {} jobject toJava(JNIEnv* env) const { return env->NewObject(gRefreshRateRangeClassInfo.clazz, gRefreshRateRangeClassInfo.ctor, min, max); } }; struct RefreshRateRanges { const RefreshRateRange physical; const RefreshRateRange render; RefreshRateRanges(RefreshRateRange physical, RefreshRateRange render) : physical(physical), render(render) {} RefreshRateRanges(JNIEnv* env, jobject obj) : physical(env, env->GetObjectField(obj, gRefreshRateRangesClassInfo.physical)), render(env, env->GetObjectField(obj, gRefreshRateRangesClassInfo.render)) {} jobject toJava(JNIEnv* env) const { return env->NewObject(gRefreshRateRangesClassInfo.clazz, gRefreshRateRangesClassInfo.ctor, physical.toJava(env), render.toJava(env)); } }; static jboolean nativeSetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobject tokenObj, jobject DesiredDisplayModeSpecs) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); Loading @@ -1200,25 +1245,23 @@ static jboolean nativeSetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobj jboolean allowGroupSwitching = env->GetBooleanField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.allowGroupSwitching); jfloat primaryRefreshRateMin = env->GetFloatField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMin); jfloat primaryRefreshRateMax = env->GetFloatField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMax); jfloat appRequestRefreshRateMin = env->GetFloatField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMin); jfloat appRequestRefreshRateMax = env->GetFloatField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMax); size_t result = SurfaceComposerClient::setDesiredDisplayModeSpecs(token, defaultMode, const jobject primaryRangesObject = env->GetObjectField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.primaryRanges); const jobject appRequestRangesObject = env->GetObjectField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.appRequestRanges); const RefreshRateRanges primaryRanges(env, primaryRangesObject); const RefreshRateRanges appRequestRanges(env, appRequestRangesObject); size_t result = SurfaceComposerClient::setDesiredDisplayModeSpecs(token, defaultMode, allowGroupSwitching, primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin, appRequestRefreshRateMax); primaryRanges.physical.min, primaryRanges.physical.max, appRequestRanges.physical.min, appRequestRanges.physical.max); return result == NO_ERROR ? JNI_TRUE : JNI_FALSE; } Loading @@ -1228,22 +1271,31 @@ static jobject nativeGetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobje ui::DisplayModeId defaultMode; bool allowGroupSwitching; float primaryRefreshRateMin; float primaryRefreshRateMax; float appRequestRefreshRateMin; float appRequestRefreshRateMax; float primaryPhysicalRefreshRateMin; float primaryPhysicalRefreshRateMax; float appRequestPhysicalRefreshRateMin; float appRequestPhysicalRefreshRateMax; if (SurfaceComposerClient::getDesiredDisplayModeSpecs(token, &defaultMode, &allowGroupSwitching, &primaryRefreshRateMin, &primaryRefreshRateMax, &appRequestRefreshRateMin, &appRequestRefreshRateMax) != NO_ERROR) { &primaryPhysicalRefreshRateMin, &primaryPhysicalRefreshRateMax, &appRequestPhysicalRefreshRateMin, &appRequestPhysicalRefreshRateMax) != NO_ERROR) { return nullptr; } const RefreshRateRange primaryPhysicalRange(primaryPhysicalRefreshRateMin, primaryPhysicalRefreshRateMax); const RefreshRateRange appRequestPhysicalRange(appRequestPhysicalRefreshRateMin, appRequestPhysicalRefreshRateMax); // TODO(b/241460058): populate the render ranges const RefreshRateRanges primaryRanges(primaryPhysicalRange, primaryPhysicalRange); const RefreshRateRanges appRequestRanges(appRequestPhysicalRange, appRequestPhysicalRange); return env->NewObject(gDesiredDisplayModeSpecsClassInfo.clazz, gDesiredDisplayModeSpecsClassInfo.ctor, defaultMode, allowGroupSwitching, primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin, appRequestRefreshRateMax); primaryRanges.toJava(env), appRequestRanges.toJava(env)); } static jobject nativeGetDisplayNativePrimaries(JNIEnv* env, jclass, jobject tokenObj) { Loading Loading @@ -2235,23 +2287,45 @@ int register_android_view_SurfaceControl(JNIEnv* env) gDisplayPrimariesClassInfo.white = GetFieldIDOrDie(env, displayPrimariesClazz, "white", "Landroid/view/SurfaceControl$CieXyz;"); jclass RefreshRateRangeClazz = FindClassOrDie(env, "android/view/SurfaceControl$RefreshRateRange"); gRefreshRateRangeClassInfo.clazz = MakeGlobalRefOrDie(env, RefreshRateRangeClazz); gRefreshRateRangeClassInfo.ctor = GetMethodIDOrDie(env, gRefreshRateRangeClassInfo.clazz, "<init>", "(FF)V"); gRefreshRateRangeClassInfo.min = GetFieldIDOrDie(env, RefreshRateRangeClazz, "min", "F"); gRefreshRateRangeClassInfo.max = GetFieldIDOrDie(env, RefreshRateRangeClazz, "max", "F"); jclass RefreshRateRangesClazz = FindClassOrDie(env, "android/view/SurfaceControl$RefreshRateRanges"); gRefreshRateRangesClassInfo.clazz = MakeGlobalRefOrDie(env, RefreshRateRangesClazz); gRefreshRateRangesClassInfo.ctor = GetMethodIDOrDie(env, gRefreshRateRangesClassInfo.clazz, "<init>", "(Landroid/view/SurfaceControl$RefreshRateRange;Landroid/view/" "SurfaceControl$RefreshRateRange;)V"); gRefreshRateRangesClassInfo.physical = GetFieldIDOrDie(env, RefreshRateRangesClazz, "physical", "Landroid/view/SurfaceControl$RefreshRateRange;"); gRefreshRateRangesClassInfo.render = GetFieldIDOrDie(env, RefreshRateRangesClazz, "render", "Landroid/view/SurfaceControl$RefreshRateRange;"); jclass DesiredDisplayModeSpecsClazz = FindClassOrDie(env, "android/view/SurfaceControl$DesiredDisplayModeSpecs"); gDesiredDisplayModeSpecsClassInfo.clazz = MakeGlobalRefOrDie(env, DesiredDisplayModeSpecsClazz); gDesiredDisplayModeSpecsClassInfo.ctor = GetMethodIDOrDie(env, gDesiredDisplayModeSpecsClassInfo.clazz, "<init>", "(IZFFFF)V"); GetMethodIDOrDie(env, gDesiredDisplayModeSpecsClassInfo.clazz, "<init>", "(IZLandroid/view/SurfaceControl$RefreshRateRanges;Landroid/view/" "SurfaceControl$RefreshRateRanges;)V"); gDesiredDisplayModeSpecsClassInfo.defaultMode = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "defaultMode", "I"); gDesiredDisplayModeSpecsClassInfo.allowGroupSwitching = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "allowGroupSwitching", "Z"); gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMin = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "primaryRefreshRateMin", "F"); gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMax = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "primaryRefreshRateMax", "F"); gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMin = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRefreshRateMin", "F"); gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMax = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRefreshRateMax", "F"); gDesiredDisplayModeSpecsClassInfo.primaryRanges = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "primaryRanges", "Landroid/view/SurfaceControl$RefreshRateRanges;"); gDesiredDisplayModeSpecsClassInfo.appRequestRanges = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRanges", "Landroid/view/SurfaceControl$RefreshRateRanges;"); jclass jankDataClazz = FindClassOrDie(env, "android/view/SurfaceControl$JankData"); Loading services/core/java/com/android/server/display/DisplayManagerService.java +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ import android.view.DisplayEventReceiver; import android.view.DisplayInfo; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl.RefreshRateRange; import android.window.DisplayWindowPolicyController; import android.window.ScreenCapture; Loading services/core/java/com/android/server/display/DisplayModeDirector.java +286 −114 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/hardware/display/DisplayManagerInternal.java +1 −68 Original line number Diff line number Diff line Loading @@ -24,11 +24,11 @@ import android.hardware.SensorManager; import android.os.Handler; import android.os.PowerManager; import android.util.IntArray; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.DisplayInfo; import android.view.SurfaceControl; import android.view.SurfaceControl.RefreshRateRange; import android.view.SurfaceControl.Transaction; import android.window.DisplayWindowPolicyController; import android.window.ScreenCapture; Loading @@ -36,7 +36,6 @@ import android.window.ScreenCapture; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.Objects; import java.util.Set; /** Loading Loading @@ -650,72 +649,6 @@ public abstract class DisplayManagerInternal { void onDisplayGroupChanged(int groupId); } /** * Information about the min and max refresh rate DM would like to set the display to. */ public static final class RefreshRateRange { public static final String TAG = "RefreshRateRange"; // The tolerance within which we consider something approximately equals. public static final float FLOAT_TOLERANCE = 0.01f; /** * The lowest desired refresh rate. */ public float min; /** * The highest desired refresh rate. */ public float max; public RefreshRateRange() {} public RefreshRateRange(float min, float max) { if (min < 0 || max < 0 || min > max + FLOAT_TOLERANCE) { Slog.e(TAG, "Wrong values for min and max when initializing RefreshRateRange : " + min + " " + max); this.min = this.max = 0; return; } if (min > max) { // Min and max are within epsilon of each other, but in the wrong order. float t = min; min = max; max = t; } this.min = min; this.max = max; } /** * Checks whether the two objects have the same values. */ @Override public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof RefreshRateRange)) { return false; } RefreshRateRange refreshRateRange = (RefreshRateRange) other; return (min == refreshRateRange.min && max == refreshRateRange.max); } @Override public int hashCode() { return Objects.hash(min, max); } @Override public String toString() { return "(" + min + " " + max + ")"; } } /** * Describes a limitation on a display's refresh rate. Includes the allowed refresh rate * range as well as information about when it applies, such as high-brightness-mode. Loading
core/java/android/view/SurfaceControl.java +179 −35 Original line number Diff line number Diff line Loading @@ -67,6 +67,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import android.util.SparseIntArray; import android.util.proto.ProtoOutputStream; import android.view.Surface.OutOfResourcesException; Loading Loading @@ -1673,6 +1674,146 @@ public final class SurfaceControl implements Parcelable { return nativeGetDisplayedContentSample(displayToken, maxFrames, timestamp); } /** * Information about the min and max refresh rate DM would like to set the display to. * @hide */ public static final class RefreshRateRange { public static final String TAG = "RefreshRateRange"; // The tolerance within which we consider something approximately equals. public static final float FLOAT_TOLERANCE = 0.01f; /** * The lowest desired refresh rate. */ public float min; /** * The highest desired refresh rate. */ public float max; public RefreshRateRange() {} public RefreshRateRange(float min, float max) { if (min < 0 || max < 0 || min > max + FLOAT_TOLERANCE) { Slog.e(TAG, "Wrong values for min and max when initializing RefreshRateRange : " + min + " " + max); this.min = this.max = 0; return; } if (min > max) { // Min and max are within epsilon of each other, but in the wrong order. float t = min; min = max; max = t; } this.min = min; this.max = max; } /** * Checks whether the two objects have the same values. */ @Override public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof RefreshRateRange)) { return false; } RefreshRateRange refreshRateRange = (RefreshRateRange) other; return (min == refreshRateRange.min && max == refreshRateRange.max); } @Override public int hashCode() { return Objects.hash(min, max); } @Override public String toString() { return "(" + min + " " + max + ")"; } /** * Copies the supplied object's values to this object. */ public void copyFrom(RefreshRateRange other) { this.min = other.min; this.max = other.max; } } /** * Information about the ranges of refresh rates for the display physical refresh rates and the * render frame rate DM would like to set the policy to. * @hide */ public static final class RefreshRateRanges { public static final String TAG = "RefreshRateRanges"; /** * The range of refresh rates that the display should run at. */ public final RefreshRateRange physical; /** * The range of refresh rates that apps should render at. */ public final RefreshRateRange render; public RefreshRateRanges() { physical = new RefreshRateRange(); render = new RefreshRateRange(); } public RefreshRateRanges(RefreshRateRange physical, RefreshRateRange render) { this.physical = new RefreshRateRange(physical.min, physical.max); this.render = new RefreshRateRange(render.min, render.max); } /** * Checks whether the two objects have the same values. */ @Override public boolean equals(Object other) { if (other == this) { return true; } if (!(other instanceof RefreshRateRanges)) { return false; } RefreshRateRanges rates = (RefreshRateRanges) other; return physical.equals(rates.physical) && render.equals( rates.render); } @Override public int hashCode() { return Objects.hash(physical, render); } @Override public String toString() { return "physical: " + physical + " render: " + render; } /** * Copies the supplied object's values to this object. */ public void copyFrom(RefreshRateRanges other) { this.physical.copyFrom(other.physical); this.render.copyFrom(other.render); } } /** * Contains information about desired display configuration. Loading @@ -1682,44 +1823,49 @@ public final class SurfaceControl implements Parcelable { public static final class DesiredDisplayModeSpecs { public int defaultMode; /** * The primary refresh rate range represents display manager's general guidance on the * display configs surface flinger will consider when switching refresh rates. Unless * surface flinger has a specific reason to do otherwise, it will stay within this range. * If true this will allow switching between modes in different display configuration * groups. This way the user may see visual interruptions when the display mode changes. */ public float primaryRefreshRateMin; public float primaryRefreshRateMax; public boolean allowGroupSwitching; /** * The app request refresh rate range allows surface flinger to consider more display * configs when switching refresh rates. Although surface flinger will generally stay within * the primary range, specific considerations, such as layer frame rate settings specified * via the setFrameRate() api, may cause surface flinger to go outside the primary * range. Surface flinger never goes outside the app request range. The app request range * will be greater than or equal to the primary refresh rate range, never smaller. * The primary physical and render refresh rate ranges represent display manager's general * guidance on the display configs surface flinger will consider when switching refresh * rates and scheduling the frame rate. Unless surface flinger has a specific reason to do * otherwise, it will stay within this range. */ public float appRequestRefreshRateMin; public float appRequestRefreshRateMax; public final RefreshRateRanges primaryRanges; /** * If true this will allow switching between modes in different display configuration * groups. This way the user may see visual interruptions when the display mode changes. * The app request physical and render refresh rate ranges allow surface flinger to consider * more display configs when switching refresh rates. Although surface flinger will * generally stay within the primary range, specific considerations, such as layer frame * rate settings specified via the setFrameRate() api, may cause surface flinger to go * outside the primary range. Surface flinger never goes outside the app request range. * The app request range will be greater than or equal to the primary refresh rate range, * never smaller. */ public boolean allowGroupSwitching; public final RefreshRateRanges appRequestRanges; public DesiredDisplayModeSpecs() {} public DesiredDisplayModeSpecs() { this.primaryRanges = new RefreshRateRanges(); this.appRequestRanges = new RefreshRateRanges(); } public DesiredDisplayModeSpecs(DesiredDisplayModeSpecs other) { this.primaryRanges = new RefreshRateRanges(); this.appRequestRanges = new RefreshRateRanges(); copyFrom(other); } public DesiredDisplayModeSpecs(int defaultMode, boolean allowGroupSwitching, float primaryRefreshRateMin, float primaryRefreshRateMax, float appRequestRefreshRateMin, float appRequestRefreshRateMax) { RefreshRateRanges primaryRanges, RefreshRateRanges appRequestRanges) { this.defaultMode = defaultMode; this.allowGroupSwitching = allowGroupSwitching; this.primaryRefreshRateMin = primaryRefreshRateMin; this.primaryRefreshRateMax = primaryRefreshRateMax; this.appRequestRefreshRateMin = appRequestRefreshRateMin; this.appRequestRefreshRateMax = appRequestRefreshRateMax; this.primaryRanges = new RefreshRateRanges(primaryRanges.physical, primaryRanges.render); this.appRequestRanges = new RefreshRateRanges(appRequestRanges.physical, appRequestRanges.render); } @Override Loading @@ -1732,10 +1878,9 @@ public final class SurfaceControl implements Parcelable { */ public boolean equals(DesiredDisplayModeSpecs other) { return other != null && defaultMode == other.defaultMode && primaryRefreshRateMin == other.primaryRefreshRateMin && primaryRefreshRateMax == other.primaryRefreshRateMax && appRequestRefreshRateMin == other.appRequestRefreshRateMin && appRequestRefreshRateMax == other.appRequestRefreshRateMax; && allowGroupSwitching == other.allowGroupSwitching && primaryRanges.equals(other.primaryRanges) && appRequestRanges.equals(other.appRequestRanges); } @Override Loading @@ -1748,18 +1893,17 @@ public final class SurfaceControl implements Parcelable { */ public void copyFrom(DesiredDisplayModeSpecs other) { defaultMode = other.defaultMode; primaryRefreshRateMin = other.primaryRefreshRateMin; primaryRefreshRateMax = other.primaryRefreshRateMax; appRequestRefreshRateMin = other.appRequestRefreshRateMin; appRequestRefreshRateMax = other.appRequestRefreshRateMax; allowGroupSwitching = other.allowGroupSwitching; primaryRanges.copyFrom(other.primaryRanges); appRequestRanges.copyFrom(other.appRequestRanges); } @Override public String toString() { return String.format("defaultConfig=%d primaryRefreshRateRange=[%.0f %.0f]" + " appRequestRefreshRateRange=[%.0f %.0f]", defaultMode, primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin, appRequestRefreshRateMax); return "defaultMode=" + defaultMode + " allowGroupSwitching=" + allowGroupSwitching + " primaryRanges=" + primaryRanges + " appRequestRanges=" + appRequestRanges; } } Loading
core/jni/android_view_SurfaceControl.cpp +116 −42 Original line number Diff line number Diff line Loading @@ -187,15 +187,27 @@ static struct { jfieldID white; } gDisplayPrimariesClassInfo; static struct { jclass clazz; jmethodID ctor; jfieldID min; jfieldID max; } gRefreshRateRangeClassInfo; static struct { jclass clazz; jmethodID ctor; jfieldID physical; jfieldID render; } gRefreshRateRangesClassInfo; static struct { jclass clazz; jmethodID ctor; jfieldID defaultMode; jfieldID allowGroupSwitching; jfieldID primaryRefreshRateMin; jfieldID primaryRefreshRateMax; jfieldID appRequestRefreshRateMin; jfieldID appRequestRefreshRateMax; jfieldID primaryRanges; jfieldID appRequestRanges; } gDesiredDisplayModeSpecsClassInfo; static struct { Loading Loading @@ -1190,6 +1202,39 @@ static jobject nativeGetDynamicDisplayInfo(JNIEnv* env, jclass clazz, jobject to return object; } struct RefreshRateRange { const float min; const float max; RefreshRateRange(float min, float max) : min(min), max(max) {} RefreshRateRange(JNIEnv* env, jobject obj) : min(env->GetFloatField(obj, gRefreshRateRangeClassInfo.min)), max(env->GetFloatField(obj, gRefreshRateRangeClassInfo.max)) {} jobject toJava(JNIEnv* env) const { return env->NewObject(gRefreshRateRangeClassInfo.clazz, gRefreshRateRangeClassInfo.ctor, min, max); } }; struct RefreshRateRanges { const RefreshRateRange physical; const RefreshRateRange render; RefreshRateRanges(RefreshRateRange physical, RefreshRateRange render) : physical(physical), render(render) {} RefreshRateRanges(JNIEnv* env, jobject obj) : physical(env, env->GetObjectField(obj, gRefreshRateRangesClassInfo.physical)), render(env, env->GetObjectField(obj, gRefreshRateRangesClassInfo.render)) {} jobject toJava(JNIEnv* env) const { return env->NewObject(gRefreshRateRangesClassInfo.clazz, gRefreshRateRangesClassInfo.ctor, physical.toJava(env), render.toJava(env)); } }; static jboolean nativeSetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobject tokenObj, jobject DesiredDisplayModeSpecs) { sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); Loading @@ -1200,25 +1245,23 @@ static jboolean nativeSetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobj jboolean allowGroupSwitching = env->GetBooleanField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.allowGroupSwitching); jfloat primaryRefreshRateMin = env->GetFloatField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMin); jfloat primaryRefreshRateMax = env->GetFloatField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMax); jfloat appRequestRefreshRateMin = env->GetFloatField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMin); jfloat appRequestRefreshRateMax = env->GetFloatField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMax); size_t result = SurfaceComposerClient::setDesiredDisplayModeSpecs(token, defaultMode, const jobject primaryRangesObject = env->GetObjectField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.primaryRanges); const jobject appRequestRangesObject = env->GetObjectField(DesiredDisplayModeSpecs, gDesiredDisplayModeSpecsClassInfo.appRequestRanges); const RefreshRateRanges primaryRanges(env, primaryRangesObject); const RefreshRateRanges appRequestRanges(env, appRequestRangesObject); size_t result = SurfaceComposerClient::setDesiredDisplayModeSpecs(token, defaultMode, allowGroupSwitching, primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin, appRequestRefreshRateMax); primaryRanges.physical.min, primaryRanges.physical.max, appRequestRanges.physical.min, appRequestRanges.physical.max); return result == NO_ERROR ? JNI_TRUE : JNI_FALSE; } Loading @@ -1228,22 +1271,31 @@ static jobject nativeGetDesiredDisplayModeSpecs(JNIEnv* env, jclass clazz, jobje ui::DisplayModeId defaultMode; bool allowGroupSwitching; float primaryRefreshRateMin; float primaryRefreshRateMax; float appRequestRefreshRateMin; float appRequestRefreshRateMax; float primaryPhysicalRefreshRateMin; float primaryPhysicalRefreshRateMax; float appRequestPhysicalRefreshRateMin; float appRequestPhysicalRefreshRateMax; if (SurfaceComposerClient::getDesiredDisplayModeSpecs(token, &defaultMode, &allowGroupSwitching, &primaryRefreshRateMin, &primaryRefreshRateMax, &appRequestRefreshRateMin, &appRequestRefreshRateMax) != NO_ERROR) { &primaryPhysicalRefreshRateMin, &primaryPhysicalRefreshRateMax, &appRequestPhysicalRefreshRateMin, &appRequestPhysicalRefreshRateMax) != NO_ERROR) { return nullptr; } const RefreshRateRange primaryPhysicalRange(primaryPhysicalRefreshRateMin, primaryPhysicalRefreshRateMax); const RefreshRateRange appRequestPhysicalRange(appRequestPhysicalRefreshRateMin, appRequestPhysicalRefreshRateMax); // TODO(b/241460058): populate the render ranges const RefreshRateRanges primaryRanges(primaryPhysicalRange, primaryPhysicalRange); const RefreshRateRanges appRequestRanges(appRequestPhysicalRange, appRequestPhysicalRange); return env->NewObject(gDesiredDisplayModeSpecsClassInfo.clazz, gDesiredDisplayModeSpecsClassInfo.ctor, defaultMode, allowGroupSwitching, primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin, appRequestRefreshRateMax); primaryRanges.toJava(env), appRequestRanges.toJava(env)); } static jobject nativeGetDisplayNativePrimaries(JNIEnv* env, jclass, jobject tokenObj) { Loading Loading @@ -2235,23 +2287,45 @@ int register_android_view_SurfaceControl(JNIEnv* env) gDisplayPrimariesClassInfo.white = GetFieldIDOrDie(env, displayPrimariesClazz, "white", "Landroid/view/SurfaceControl$CieXyz;"); jclass RefreshRateRangeClazz = FindClassOrDie(env, "android/view/SurfaceControl$RefreshRateRange"); gRefreshRateRangeClassInfo.clazz = MakeGlobalRefOrDie(env, RefreshRateRangeClazz); gRefreshRateRangeClassInfo.ctor = GetMethodIDOrDie(env, gRefreshRateRangeClassInfo.clazz, "<init>", "(FF)V"); gRefreshRateRangeClassInfo.min = GetFieldIDOrDie(env, RefreshRateRangeClazz, "min", "F"); gRefreshRateRangeClassInfo.max = GetFieldIDOrDie(env, RefreshRateRangeClazz, "max", "F"); jclass RefreshRateRangesClazz = FindClassOrDie(env, "android/view/SurfaceControl$RefreshRateRanges"); gRefreshRateRangesClassInfo.clazz = MakeGlobalRefOrDie(env, RefreshRateRangesClazz); gRefreshRateRangesClassInfo.ctor = GetMethodIDOrDie(env, gRefreshRateRangesClassInfo.clazz, "<init>", "(Landroid/view/SurfaceControl$RefreshRateRange;Landroid/view/" "SurfaceControl$RefreshRateRange;)V"); gRefreshRateRangesClassInfo.physical = GetFieldIDOrDie(env, RefreshRateRangesClazz, "physical", "Landroid/view/SurfaceControl$RefreshRateRange;"); gRefreshRateRangesClassInfo.render = GetFieldIDOrDie(env, RefreshRateRangesClazz, "render", "Landroid/view/SurfaceControl$RefreshRateRange;"); jclass DesiredDisplayModeSpecsClazz = FindClassOrDie(env, "android/view/SurfaceControl$DesiredDisplayModeSpecs"); gDesiredDisplayModeSpecsClassInfo.clazz = MakeGlobalRefOrDie(env, DesiredDisplayModeSpecsClazz); gDesiredDisplayModeSpecsClassInfo.ctor = GetMethodIDOrDie(env, gDesiredDisplayModeSpecsClassInfo.clazz, "<init>", "(IZFFFF)V"); GetMethodIDOrDie(env, gDesiredDisplayModeSpecsClassInfo.clazz, "<init>", "(IZLandroid/view/SurfaceControl$RefreshRateRanges;Landroid/view/" "SurfaceControl$RefreshRateRanges;)V"); gDesiredDisplayModeSpecsClassInfo.defaultMode = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "defaultMode", "I"); gDesiredDisplayModeSpecsClassInfo.allowGroupSwitching = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "allowGroupSwitching", "Z"); gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMin = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "primaryRefreshRateMin", "F"); gDesiredDisplayModeSpecsClassInfo.primaryRefreshRateMax = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "primaryRefreshRateMax", "F"); gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMin = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRefreshRateMin", "F"); gDesiredDisplayModeSpecsClassInfo.appRequestRefreshRateMax = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRefreshRateMax", "F"); gDesiredDisplayModeSpecsClassInfo.primaryRanges = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "primaryRanges", "Landroid/view/SurfaceControl$RefreshRateRanges;"); gDesiredDisplayModeSpecsClassInfo.appRequestRanges = GetFieldIDOrDie(env, DesiredDisplayModeSpecsClazz, "appRequestRanges", "Landroid/view/SurfaceControl$RefreshRateRanges;"); jclass jankDataClazz = FindClassOrDie(env, "android/view/SurfaceControl$JankData"); Loading
services/core/java/com/android/server/display/DisplayManagerService.java +1 −0 Original line number Diff line number Diff line Loading @@ -119,6 +119,7 @@ import android.view.DisplayEventReceiver; import android.view.DisplayInfo; import android.view.Surface; import android.view.SurfaceControl; import android.view.SurfaceControl.RefreshRateRange; import android.window.DisplayWindowPolicyController; import android.window.ScreenCapture; Loading
services/core/java/com/android/server/display/DisplayModeDirector.java +286 −114 File changed.Preview size limit exceeded, changes collapsed. Show changes