Merge "Split refresh rate range into two ranges" into rvc-dev am: 5724666853
Change-Id: I3ab1225ff065704a3c560a487ff0a4e9781960d7
This commit is contained in:
@@ -1464,8 +1464,23 @@ public final class SurfaceControl implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public static final class DesiredDisplayConfigSpecs {
|
public static final class DesiredDisplayConfigSpecs {
|
||||||
public int defaultConfig;
|
public int defaultConfig;
|
||||||
public float minRefreshRate;
|
/**
|
||||||
public float maxRefreshRate;
|
* 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.
|
||||||
|
*/
|
||||||
|
public float primaryRefreshRateMin;
|
||||||
|
public float primaryRefreshRateMax;
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
public float appRequestRefreshRateMin;
|
||||||
|
public float appRequestRefreshRateMax;
|
||||||
|
|
||||||
public DesiredDisplayConfigSpecs() {}
|
public DesiredDisplayConfigSpecs() {}
|
||||||
|
|
||||||
@@ -1473,11 +1488,14 @@ public final class SurfaceControl implements Parcelable {
|
|||||||
copyFrom(other);
|
copyFrom(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DesiredDisplayConfigSpecs(
|
public DesiredDisplayConfigSpecs(int defaultConfig, float primaryRefreshRateMin,
|
||||||
int defaultConfig, float minRefreshRate, float maxRefreshRate) {
|
float primaryRefreshRateMax, float appRequestRefreshRateMin,
|
||||||
|
float appRequestRefreshRateMax) {
|
||||||
this.defaultConfig = defaultConfig;
|
this.defaultConfig = defaultConfig;
|
||||||
this.minRefreshRate = minRefreshRate;
|
this.primaryRefreshRateMin = primaryRefreshRateMin;
|
||||||
this.maxRefreshRate = maxRefreshRate;
|
this.primaryRefreshRateMax = primaryRefreshRateMax;
|
||||||
|
this.appRequestRefreshRateMin = appRequestRefreshRateMin;
|
||||||
|
this.appRequestRefreshRateMax = appRequestRefreshRateMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1490,8 +1508,10 @@ public final class SurfaceControl implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public boolean equals(DesiredDisplayConfigSpecs other) {
|
public boolean equals(DesiredDisplayConfigSpecs other) {
|
||||||
return other != null && defaultConfig == other.defaultConfig
|
return other != null && defaultConfig == other.defaultConfig
|
||||||
&& minRefreshRate == other.minRefreshRate
|
&& primaryRefreshRateMin == other.primaryRefreshRateMin
|
||||||
&& maxRefreshRate == other.maxRefreshRate;
|
&& primaryRefreshRateMax == other.primaryRefreshRateMax
|
||||||
|
&& appRequestRefreshRateMin == other.appRequestRefreshRateMin
|
||||||
|
&& appRequestRefreshRateMax == other.appRequestRefreshRateMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1504,14 +1524,18 @@ public final class SurfaceControl implements Parcelable {
|
|||||||
*/
|
*/
|
||||||
public void copyFrom(DesiredDisplayConfigSpecs other) {
|
public void copyFrom(DesiredDisplayConfigSpecs other) {
|
||||||
defaultConfig = other.defaultConfig;
|
defaultConfig = other.defaultConfig;
|
||||||
minRefreshRate = other.minRefreshRate;
|
primaryRefreshRateMin = other.primaryRefreshRateMin;
|
||||||
maxRefreshRate = other.maxRefreshRate;
|
primaryRefreshRateMax = other.primaryRefreshRateMax;
|
||||||
|
appRequestRefreshRateMin = other.appRequestRefreshRateMin;
|
||||||
|
appRequestRefreshRateMax = other.appRequestRefreshRateMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("defaultConfig=%d min=%.0f max=%.0f", defaultConfig,
|
return String.format("defaultConfig=%d primaryRefreshRateRange=[%.0f %.0f]"
|
||||||
minRefreshRate, maxRefreshRate);
|
+ " appRequestRefreshRateRange=[%.0f %.0f]",
|
||||||
|
defaultConfig, primaryRefreshRateMin, primaryRefreshRateMax,
|
||||||
|
appRequestRefreshRateMin, appRequestRefreshRateMax);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,8 +174,10 @@ static struct {
|
|||||||
jclass clazz;
|
jclass clazz;
|
||||||
jmethodID ctor;
|
jmethodID ctor;
|
||||||
jfieldID defaultConfig;
|
jfieldID defaultConfig;
|
||||||
jfieldID minRefreshRate;
|
jfieldID primaryRefreshRateMin;
|
||||||
jfieldID maxRefreshRate;
|
jfieldID primaryRefreshRateMax;
|
||||||
|
jfieldID appRequestRefreshRateMin;
|
||||||
|
jfieldID appRequestRefreshRateMax;
|
||||||
} gDesiredDisplayConfigSpecsClassInfo;
|
} gDesiredDisplayConfigSpecsClassInfo;
|
||||||
|
|
||||||
class JNamedColorSpace {
|
class JNamedColorSpace {
|
||||||
@@ -919,13 +921,24 @@ static jboolean nativeSetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, jo
|
|||||||
|
|
||||||
jint defaultConfig = env->GetIntField(desiredDisplayConfigSpecs,
|
jint defaultConfig = env->GetIntField(desiredDisplayConfigSpecs,
|
||||||
gDesiredDisplayConfigSpecsClassInfo.defaultConfig);
|
gDesiredDisplayConfigSpecsClassInfo.defaultConfig);
|
||||||
jfloat minRefreshRate = env->GetFloatField(desiredDisplayConfigSpecs,
|
jfloat primaryRefreshRateMin =
|
||||||
gDesiredDisplayConfigSpecsClassInfo.minRefreshRate);
|
env->GetFloatField(desiredDisplayConfigSpecs,
|
||||||
jfloat maxRefreshRate = env->GetFloatField(desiredDisplayConfigSpecs,
|
gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMin);
|
||||||
gDesiredDisplayConfigSpecsClassInfo.maxRefreshRate);
|
jfloat primaryRefreshRateMax =
|
||||||
|
env->GetFloatField(desiredDisplayConfigSpecs,
|
||||||
|
gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMax);
|
||||||
|
jfloat appRequestRefreshRateMin =
|
||||||
|
env->GetFloatField(desiredDisplayConfigSpecs,
|
||||||
|
gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMin);
|
||||||
|
jfloat appRequestRefreshRateMax =
|
||||||
|
env->GetFloatField(desiredDisplayConfigSpecs,
|
||||||
|
gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMax);
|
||||||
|
|
||||||
size_t result = SurfaceComposerClient::setDesiredDisplayConfigSpecs(
|
size_t result = SurfaceComposerClient::setDesiredDisplayConfigSpecs(token, defaultConfig,
|
||||||
token, defaultConfig, minRefreshRate, maxRefreshRate);
|
primaryRefreshRateMin,
|
||||||
|
primaryRefreshRateMax,
|
||||||
|
appRequestRefreshRateMin,
|
||||||
|
appRequestRefreshRateMax);
|
||||||
return result == NO_ERROR ? JNI_TRUE : JNI_FALSE;
|
return result == NO_ERROR ? JNI_TRUE : JNI_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -934,16 +947,23 @@ static jobject nativeGetDesiredDisplayConfigSpecs(JNIEnv* env, jclass clazz, job
|
|||||||
if (token == nullptr) return nullptr;
|
if (token == nullptr) return nullptr;
|
||||||
|
|
||||||
int32_t defaultConfig;
|
int32_t defaultConfig;
|
||||||
float minRefreshRate;
|
float primaryRefreshRateMin;
|
||||||
float maxRefreshRate;
|
float primaryRefreshRateMax;
|
||||||
if (SurfaceComposerClient::getDesiredDisplayConfigSpecs(token, &defaultConfig, &minRefreshRate,
|
float appRequestRefreshRateMin;
|
||||||
&maxRefreshRate) != NO_ERROR) {
|
float appRequestRefreshRateMax;
|
||||||
|
if (SurfaceComposerClient::getDesiredDisplayConfigSpecs(token, &defaultConfig,
|
||||||
|
&primaryRefreshRateMin,
|
||||||
|
&primaryRefreshRateMax,
|
||||||
|
&appRequestRefreshRateMin,
|
||||||
|
&appRequestRefreshRateMax) !=
|
||||||
|
NO_ERROR) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return env->NewObject(gDesiredDisplayConfigSpecsClassInfo.clazz,
|
return env->NewObject(gDesiredDisplayConfigSpecsClassInfo.clazz,
|
||||||
gDesiredDisplayConfigSpecsClassInfo.ctor, defaultConfig, minRefreshRate,
|
gDesiredDisplayConfigSpecsClassInfo.ctor, defaultConfig,
|
||||||
maxRefreshRate);
|
primaryRefreshRateMin, primaryRefreshRateMax, appRequestRefreshRateMin,
|
||||||
|
appRequestRefreshRateMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
static jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) {
|
static jint nativeGetActiveConfig(JNIEnv* env, jclass clazz, jobject tokenObj) {
|
||||||
@@ -1757,13 +1777,17 @@ int register_android_view_SurfaceControl(JNIEnv* env)
|
|||||||
gDesiredDisplayConfigSpecsClassInfo.clazz =
|
gDesiredDisplayConfigSpecsClassInfo.clazz =
|
||||||
MakeGlobalRefOrDie(env, desiredDisplayConfigSpecsClazz);
|
MakeGlobalRefOrDie(env, desiredDisplayConfigSpecsClazz);
|
||||||
gDesiredDisplayConfigSpecsClassInfo.ctor =
|
gDesiredDisplayConfigSpecsClassInfo.ctor =
|
||||||
GetMethodIDOrDie(env, gDesiredDisplayConfigSpecsClassInfo.clazz, "<init>", "(IFF)V");
|
GetMethodIDOrDie(env, gDesiredDisplayConfigSpecsClassInfo.clazz, "<init>", "(IFFFF)V");
|
||||||
gDesiredDisplayConfigSpecsClassInfo.defaultConfig =
|
gDesiredDisplayConfigSpecsClassInfo.defaultConfig =
|
||||||
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "defaultConfig", "I");
|
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "defaultConfig", "I");
|
||||||
gDesiredDisplayConfigSpecsClassInfo.minRefreshRate =
|
gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMin =
|
||||||
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "minRefreshRate", "F");
|
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "primaryRefreshRateMin", "F");
|
||||||
gDesiredDisplayConfigSpecsClassInfo.maxRefreshRate =
|
gDesiredDisplayConfigSpecsClassInfo.primaryRefreshRateMax =
|
||||||
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "maxRefreshRate", "F");
|
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "primaryRefreshRateMax", "F");
|
||||||
|
gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMin =
|
||||||
|
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "appRequestRefreshRateMin", "F");
|
||||||
|
gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMax =
|
||||||
|
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "appRequestRefreshRateMax", "F");
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,6 +152,47 @@ public class DisplayModeDirector {
|
|||||||
return votes;
|
return votes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final class VoteSummary {
|
||||||
|
public float minRefreshRate;
|
||||||
|
public float maxRefreshRate;
|
||||||
|
public int width;
|
||||||
|
public int height;
|
||||||
|
|
||||||
|
VoteSummary() {
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
minRefreshRate = 0f;
|
||||||
|
maxRefreshRate = Float.POSITIVE_INFINITY;
|
||||||
|
width = Vote.INVALID_SIZE;
|
||||||
|
height = Vote.INVALID_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// VoteSummary is returned as an output param to cut down a bit on the number of temporary
|
||||||
|
// objects.
|
||||||
|
private void summarizeVotes(
|
||||||
|
SparseArray<Vote> votes, int lowestConsideredPriority, /*out*/ VoteSummary summary) {
|
||||||
|
summary.reset();
|
||||||
|
for (int priority = Vote.MAX_PRIORITY; priority >= lowestConsideredPriority; priority--) {
|
||||||
|
Vote vote = votes.get(priority);
|
||||||
|
if (vote == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// For refresh rates, just use the tightest bounds of all the votes
|
||||||
|
summary.minRefreshRate = Math.max(summary.minRefreshRate, vote.refreshRateRange.min);
|
||||||
|
summary.maxRefreshRate = Math.min(summary.maxRefreshRate, vote.refreshRateRange.max);
|
||||||
|
// For display size, use only the first vote we come across (i.e. the highest
|
||||||
|
// priority vote that includes the width / height).
|
||||||
|
if (summary.height == Vote.INVALID_SIZE && summary.width == Vote.INVALID_SIZE
|
||||||
|
&& vote.height > 0 && vote.width > 0) {
|
||||||
|
summary.width = vote.width;
|
||||||
|
summary.height = vote.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the refresh rate ranges and display modes that the system is allowed to freely
|
* Calculates the refresh rate ranges and display modes that the system is allowed to freely
|
||||||
* switch between based on global and display-specific constraints.
|
* switch between based on global and display-specific constraints.
|
||||||
@@ -174,52 +215,31 @@ public class DisplayModeDirector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int[] availableModes = new int[]{defaultMode.getModeId()};
|
int[] availableModes = new int[]{defaultMode.getModeId()};
|
||||||
float minRefreshRate = 0f;
|
VoteSummary primarySummary = new VoteSummary();
|
||||||
float maxRefreshRate = Float.POSITIVE_INFINITY;
|
|
||||||
int lowestConsideredPriority = Vote.MIN_PRIORITY;
|
int lowestConsideredPriority = Vote.MIN_PRIORITY;
|
||||||
while (lowestConsideredPriority <= Vote.MAX_PRIORITY) {
|
while (lowestConsideredPriority <= Vote.MAX_PRIORITY) {
|
||||||
minRefreshRate = 0f;
|
summarizeVotes(votes, lowestConsideredPriority, primarySummary);
|
||||||
maxRefreshRate = Float.POSITIVE_INFINITY;
|
|
||||||
int height = Vote.INVALID_SIZE;
|
|
||||||
int width = Vote.INVALID_SIZE;
|
|
||||||
|
|
||||||
for (int priority = Vote.MAX_PRIORITY;
|
|
||||||
priority >= lowestConsideredPriority; priority--) {
|
|
||||||
Vote vote = votes.get(priority);
|
|
||||||
if (vote == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// For refresh rates, just use the tightest bounds of all the votes
|
|
||||||
minRefreshRate = Math.max(minRefreshRate, vote.refreshRateRange.min);
|
|
||||||
maxRefreshRate = Math.min(maxRefreshRate, vote.refreshRateRange.max);
|
|
||||||
// For display size, use only the first vote we come across (i.e. the highest
|
|
||||||
// priority vote that includes the width / height).
|
|
||||||
if (height == Vote.INVALID_SIZE && width == Vote.INVALID_SIZE
|
|
||||||
&& vote.height > 0 && vote.width > 0) {
|
|
||||||
width = vote.width;
|
|
||||||
height = vote.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we don't have anything specifying the width / height of the display, just use
|
// If we don't have anything specifying the width / height of the display, just use
|
||||||
// the default width and height. We don't want these switching out from underneath
|
// the default width and height. We don't want these switching out from underneath
|
||||||
// us since it's a pretty disruptive behavior.
|
// us since it's a pretty disruptive behavior.
|
||||||
if (height == Vote.INVALID_SIZE || width == Vote.INVALID_SIZE) {
|
if (primarySummary.height == Vote.INVALID_SIZE
|
||||||
width = defaultMode.getPhysicalWidth();
|
|| primarySummary.width == Vote.INVALID_SIZE) {
|
||||||
height = defaultMode.getPhysicalHeight();
|
primarySummary.width = defaultMode.getPhysicalWidth();
|
||||||
|
primarySummary.height = defaultMode.getPhysicalHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
availableModes = filterModes(modes, width, height, minRefreshRate, maxRefreshRate);
|
availableModes = filterModes(modes, primarySummary);
|
||||||
if (availableModes.length > 0) {
|
if (availableModes.length > 0) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.w(TAG, "Found available modes=" + Arrays.toString(availableModes)
|
Slog.w(TAG, "Found available modes=" + Arrays.toString(availableModes)
|
||||||
+ " with lowest priority considered "
|
+ " with lowest priority considered "
|
||||||
+ Vote.priorityToString(lowestConsideredPriority)
|
+ Vote.priorityToString(lowestConsideredPriority)
|
||||||
+ " and constraints: "
|
+ " and constraints: "
|
||||||
+ "width=" + width
|
+ "width=" + primarySummary.width
|
||||||
+ ", height=" + height
|
+ ", height=" + primarySummary.height
|
||||||
+ ", minRefreshRate=" + minRefreshRate
|
+ ", minRefreshRate=" + primarySummary.minRefreshRate
|
||||||
+ ", maxRefreshRate=" + maxRefreshRate);
|
+ ", maxRefreshRate=" + primarySummary.maxRefreshRate);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -228,10 +248,10 @@ public class DisplayModeDirector {
|
|||||||
Slog.w(TAG, "Couldn't find available modes with lowest priority set to "
|
Slog.w(TAG, "Couldn't find available modes with lowest priority set to "
|
||||||
+ Vote.priorityToString(lowestConsideredPriority)
|
+ Vote.priorityToString(lowestConsideredPriority)
|
||||||
+ " and with the following constraints: "
|
+ " and with the following constraints: "
|
||||||
+ "width=" + width
|
+ "width=" + primarySummary.width
|
||||||
+ ", height=" + height
|
+ ", height=" + primarySummary.height
|
||||||
+ ", minRefreshRate=" + minRefreshRate
|
+ ", minRefreshRate=" + primarySummary.minRefreshRate
|
||||||
+ ", maxRefreshRate=" + maxRefreshRate);
|
+ ", maxRefreshRate=" + primarySummary.maxRefreshRate);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we haven't found anything with the current set of votes, drop the
|
// If we haven't found anything with the current set of votes, drop the
|
||||||
@@ -239,6 +259,20 @@ public class DisplayModeDirector {
|
|||||||
lowestConsideredPriority++;
|
lowestConsideredPriority++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VoteSummary appRequestSummary = new VoteSummary();
|
||||||
|
summarizeVotes(
|
||||||
|
votes, Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, appRequestSummary);
|
||||||
|
appRequestSummary.minRefreshRate =
|
||||||
|
Math.min(appRequestSummary.minRefreshRate, primarySummary.minRefreshRate);
|
||||||
|
appRequestSummary.maxRefreshRate =
|
||||||
|
Math.max(appRequestSummary.maxRefreshRate, primarySummary.maxRefreshRate);
|
||||||
|
if (DEBUG) {
|
||||||
|
Slog.i(TAG,
|
||||||
|
String.format("App request range: [%.0f %.0f]",
|
||||||
|
appRequestSummary.minRefreshRate,
|
||||||
|
appRequestSummary.maxRefreshRate));
|
||||||
|
}
|
||||||
|
|
||||||
int baseModeId = defaultMode.getModeId();
|
int baseModeId = defaultMode.getModeId();
|
||||||
if (availableModes.length > 0) {
|
if (availableModes.length > 0) {
|
||||||
baseModeId = availableModes[0];
|
baseModeId = availableModes[0];
|
||||||
@@ -246,20 +280,23 @@ public class DisplayModeDirector {
|
|||||||
// filterModes function is going to filter the modes based on the voting system. If
|
// filterModes function is going to filter the modes based on the voting system. If
|
||||||
// the application requests a given mode with preferredModeId function, it will be
|
// the application requests a given mode with preferredModeId function, it will be
|
||||||
// stored as baseModeId.
|
// stored as baseModeId.
|
||||||
return new DesiredDisplayModeSpecs(
|
return new DesiredDisplayModeSpecs(baseModeId,
|
||||||
baseModeId, new RefreshRateRange(minRefreshRate, maxRefreshRate));
|
new RefreshRateRange(
|
||||||
|
primarySummary.minRefreshRate, primarySummary.maxRefreshRate),
|
||||||
|
new RefreshRateRange(
|
||||||
|
appRequestSummary.minRefreshRate, appRequestSummary.maxRefreshRate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int[] filterModes(Display.Mode[] supportedModes,
|
private int[] filterModes(Display.Mode[] supportedModes, VoteSummary summary) {
|
||||||
int width, int height, float minRefreshRate, float maxRefreshRate) {
|
|
||||||
ArrayList<Display.Mode> availableModes = new ArrayList<>();
|
ArrayList<Display.Mode> availableModes = new ArrayList<>();
|
||||||
for (Display.Mode mode : supportedModes) {
|
for (Display.Mode mode : supportedModes) {
|
||||||
if (mode.getPhysicalWidth() != width || mode.getPhysicalHeight() != height) {
|
if (mode.getPhysicalWidth() != summary.width
|
||||||
|
|| mode.getPhysicalHeight() != summary.height) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.w(TAG, "Discarding mode " + mode.getModeId() + ", wrong size"
|
Slog.w(TAG, "Discarding mode " + mode.getModeId() + ", wrong size"
|
||||||
+ ": desiredWidth=" + width
|
+ ": desiredWidth=" + summary.width
|
||||||
+ ": desiredHeight=" + height
|
+ ": desiredHeight=" + summary.height
|
||||||
+ ": actualWidth=" + mode.getPhysicalWidth()
|
+ ": actualWidth=" + mode.getPhysicalWidth()
|
||||||
+ ": actualHeight=" + mode.getPhysicalHeight());
|
+ ": actualHeight=" + mode.getPhysicalHeight());
|
||||||
}
|
}
|
||||||
@@ -269,13 +306,13 @@ public class DisplayModeDirector {
|
|||||||
// Some refresh rates are calculated based on frame timings, so they aren't *exactly*
|
// Some refresh rates are calculated based on frame timings, so they aren't *exactly*
|
||||||
// equal to expected refresh rate. Given that, we apply a bit of tolerance to this
|
// equal to expected refresh rate. Given that, we apply a bit of tolerance to this
|
||||||
// comparison.
|
// comparison.
|
||||||
if (refreshRate < (minRefreshRate - FLOAT_TOLERANCE)
|
if (refreshRate < (summary.minRefreshRate - FLOAT_TOLERANCE)
|
||||||
|| refreshRate > (maxRefreshRate + FLOAT_TOLERANCE)) {
|
|| refreshRate > (summary.maxRefreshRate + FLOAT_TOLERANCE)) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Slog.w(TAG, "Discarding mode " + mode.getModeId()
|
Slog.w(TAG, "Discarding mode " + mode.getModeId()
|
||||||
+ ", outside refresh rate bounds"
|
+ ", outside refresh rate bounds"
|
||||||
+ ": minRefreshRate=" + minRefreshRate
|
+ ": minRefreshRate=" + summary.minRefreshRate
|
||||||
+ ", maxRefreshRate=" + maxRefreshRate
|
+ ", maxRefreshRate=" + summary.maxRefreshRate
|
||||||
+ ", modeRefreshRate=" + refreshRate);
|
+ ", modeRefreshRate=" + refreshRate);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -535,7 +572,7 @@ public class DisplayModeDirector {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about the desired display mode to be set by the system. Includes the base
|
* Information about the desired display mode to be set by the system. Includes the base
|
||||||
* mode ID and refresh rate range.
|
* mode ID and the primary and app request refresh rate ranges.
|
||||||
*
|
*
|
||||||
* We have this class in addition to SurfaceControl.DesiredDisplayConfigSpecs to make clear the
|
* We have this class in addition to SurfaceControl.DesiredDisplayConfigSpecs to make clear the
|
||||||
* distinction between the config ID / physical index that
|
* distinction between the config ID / physical index that
|
||||||
@@ -548,17 +585,28 @@ public class DisplayModeDirector {
|
|||||||
*/
|
*/
|
||||||
public int baseModeId;
|
public int baseModeId;
|
||||||
/**
|
/**
|
||||||
* The refresh rate range.
|
* The primary refresh rate range.
|
||||||
*/
|
*/
|
||||||
public final RefreshRateRange refreshRateRange;
|
public final RefreshRateRange primaryRefreshRateRange;
|
||||||
|
/**
|
||||||
|
* The app request refresh rate range. Lower priority considerations won't be included in
|
||||||
|
* this range, allowing surface flinger to consider additional refresh rates for apps that
|
||||||
|
* call setFrameRate(). This range will be greater than or equal to the primary refresh rate
|
||||||
|
* range, never smaller.
|
||||||
|
*/
|
||||||
|
public final RefreshRateRange appRequestRefreshRateRange;
|
||||||
|
|
||||||
public DesiredDisplayModeSpecs() {
|
public DesiredDisplayModeSpecs() {
|
||||||
refreshRateRange = new RefreshRateRange();
|
primaryRefreshRateRange = new RefreshRateRange();
|
||||||
|
appRequestRefreshRateRange = new RefreshRateRange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public DesiredDisplayModeSpecs(int baseModeId, @NonNull RefreshRateRange refreshRateRange) {
|
public DesiredDisplayModeSpecs(int baseModeId,
|
||||||
|
@NonNull RefreshRateRange primaryRefreshRateRange,
|
||||||
|
@NonNull RefreshRateRange appRequestRefreshRateRange) {
|
||||||
this.baseModeId = baseModeId;
|
this.baseModeId = baseModeId;
|
||||||
this.refreshRateRange = refreshRateRange;
|
this.primaryRefreshRateRange = primaryRefreshRateRange;
|
||||||
|
this.appRequestRefreshRateRange = appRequestRefreshRateRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -566,8 +614,10 @@ public class DisplayModeDirector {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("baseModeId=%d min=%.0f max=%.0f", baseModeId,
|
return String.format("baseModeId=%d primaryRefreshRateRange=[%.0f %.0f]"
|
||||||
refreshRateRange.min, refreshRateRange.max);
|
+ " appRequestRefreshRateRange=[%.0f %.0f]",
|
||||||
|
baseModeId, primaryRefreshRateRange.min, primaryRefreshRateRange.max,
|
||||||
|
appRequestRefreshRateRange.min, appRequestRefreshRateRange.max);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Checks whether the two objects have the same values.
|
* Checks whether the two objects have the same values.
|
||||||
@@ -587,7 +637,11 @@ public class DisplayModeDirector {
|
|||||||
if (baseModeId != desiredDisplayModeSpecs.baseModeId) {
|
if (baseModeId != desiredDisplayModeSpecs.baseModeId) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!refreshRateRange.equals(desiredDisplayModeSpecs.refreshRateRange)) {
|
if (!primaryRefreshRateRange.equals(desiredDisplayModeSpecs.primaryRefreshRateRange)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!appRequestRefreshRateRange.equals(
|
||||||
|
desiredDisplayModeSpecs.appRequestRefreshRateRange)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -595,7 +649,7 @@ public class DisplayModeDirector {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(baseModeId, refreshRateRange);
|
return Objects.hash(baseModeId, primaryRefreshRateRange, appRequestRefreshRateRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -603,8 +657,10 @@ public class DisplayModeDirector {
|
|||||||
*/
|
*/
|
||||||
public void copyFrom(DesiredDisplayModeSpecs other) {
|
public void copyFrom(DesiredDisplayModeSpecs other) {
|
||||||
baseModeId = other.baseModeId;
|
baseModeId = other.baseModeId;
|
||||||
refreshRateRange.min = other.refreshRateRange.min;
|
primaryRefreshRateRange.min = other.primaryRefreshRateRange.min;
|
||||||
refreshRateRange.max = other.refreshRateRange.max;
|
primaryRefreshRateRange.max = other.primaryRefreshRateRange.max;
|
||||||
|
appRequestRefreshRateRange.min = other.appRequestRefreshRateRange.min;
|
||||||
|
appRequestRefreshRateRange.max = other.appRequestRefreshRateRange.max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,12 +693,17 @@ public class DisplayModeDirector {
|
|||||||
// LOW_POWER_MODE force display to [0, 60HZ] if Settings.Global.LOW_POWER_MODE is on.
|
// LOW_POWER_MODE force display to [0, 60HZ] if Settings.Global.LOW_POWER_MODE is on.
|
||||||
public static final int PRIORITY_LOW_POWER_MODE = 5;
|
public static final int PRIORITY_LOW_POWER_MODE = 5;
|
||||||
|
|
||||||
// Whenever a new priority is added, remember to update MIN_PRIORITY and/or MAX_PRIORITY as
|
// Whenever a new priority is added, remember to update MIN_PRIORITY, MAX_PRIORITY, and
|
||||||
// appropriate, as well as priorityToString.
|
// APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF, as well as priorityToString.
|
||||||
|
|
||||||
public static final int MIN_PRIORITY = PRIORITY_LOW_BRIGHTNESS;
|
public static final int MIN_PRIORITY = PRIORITY_LOW_BRIGHTNESS;
|
||||||
public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
|
public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
|
||||||
|
|
||||||
|
// The cutoff for the app request refresh rate range. Votes with priorities lower than this
|
||||||
|
// value will not be considered when constructing the app request refresh rate range.
|
||||||
|
public static final int APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF =
|
||||||
|
PRIORITY_APP_REQUEST_REFRESH_RATE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A value signifying an invalid width or height in a vote.
|
* A value signifying an invalid width or height in a vote.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -310,9 +310,14 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
// list of available modes will take care of updating display config specs.
|
// list of available modes will take care of updating display config specs.
|
||||||
if (activeBaseMode != NO_DISPLAY_MODE_ID) {
|
if (activeBaseMode != NO_DISPLAY_MODE_ID) {
|
||||||
if (mDisplayModeSpecs.baseModeId != activeBaseMode
|
if (mDisplayModeSpecs.baseModeId != activeBaseMode
|
||||||
|| mDisplayModeSpecs.refreshRateRange.min != configSpecs.minRefreshRate
|
|| mDisplayModeSpecs.primaryRefreshRateRange.min
|
||||||
|| mDisplayModeSpecs.refreshRateRange.max
|
!= configSpecs.primaryRefreshRateMin
|
||||||
!= configSpecs.maxRefreshRate) {
|
|| mDisplayModeSpecs.primaryRefreshRateRange.max
|
||||||
|
!= configSpecs.primaryRefreshRateMax
|
||||||
|
|| mDisplayModeSpecs.appRequestRefreshRateRange.min
|
||||||
|
!= configSpecs.appRequestRefreshRateMin
|
||||||
|
|| mDisplayModeSpecs.appRequestRefreshRateRange.max
|
||||||
|
!= configSpecs.appRequestRefreshRateMax) {
|
||||||
mDisplayModeSpecsInvalid = true;
|
mDisplayModeSpecsInvalid = true;
|
||||||
sendTraversalRequestLocked();
|
sendTraversalRequestLocked();
|
||||||
}
|
}
|
||||||
@@ -799,8 +804,10 @@ final class LocalDisplayAdapter extends DisplayAdapter {
|
|||||||
LocalDisplayDevice::setDesiredDisplayModeSpecsAsync, this,
|
LocalDisplayDevice::setDesiredDisplayModeSpecsAsync, this,
|
||||||
getDisplayTokenLocked(),
|
getDisplayTokenLocked(),
|
||||||
new SurfaceControl.DesiredDisplayConfigSpecs(baseConfigId,
|
new SurfaceControl.DesiredDisplayConfigSpecs(baseConfigId,
|
||||||
mDisplayModeSpecs.refreshRateRange.min,
|
mDisplayModeSpecs.primaryRefreshRateRange.min,
|
||||||
mDisplayModeSpecs.refreshRateRange.max)));
|
mDisplayModeSpecs.primaryRefreshRateRange.max,
|
||||||
|
mDisplayModeSpecs.appRequestRefreshRateRange.min,
|
||||||
|
mDisplayModeSpecs.appRequestRefreshRateRange.max)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ public class LocalDisplayAdapterTest {
|
|||||||
doReturn(0).when(() -> SurfaceControl.getActiveColorMode(display.token));
|
doReturn(0).when(() -> SurfaceControl.getActiveColorMode(display.token));
|
||||||
doReturn(new int[] { 0 }).when(
|
doReturn(new int[] { 0 }).when(
|
||||||
() -> SurfaceControl.getDisplayColorModes(display.token));
|
() -> SurfaceControl.getDisplayColorModes(display.token));
|
||||||
doReturn(new SurfaceControl.DesiredDisplayConfigSpecs(0, 60.f, 60.f))
|
doReturn(new SurfaceControl.DesiredDisplayConfigSpecs(0, 60.f, 60.f, 60.f, 60.f))
|
||||||
.when(() -> SurfaceControl.getDesiredDisplayConfigSpecs(display.token));
|
.when(() -> SurfaceControl.getDesiredDisplayConfigSpecs(display.token));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.android.server.display;
|
package com.android.server.display;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -30,7 +29,6 @@ import androidx.test.filters.SmallTest;
|
|||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs;
|
import com.android.server.display.DisplayModeDirector.DesiredDisplayModeSpecs;
|
||||||
import com.android.server.display.DisplayModeDirector.RefreshRateRange;
|
|
||||||
import com.android.server.display.DisplayModeDirector.Vote;
|
import com.android.server.display.DisplayModeDirector.Vote;
|
||||||
|
|
||||||
import com.google.common.truth.Truth;
|
import com.google.common.truth.Truth;
|
||||||
@@ -79,10 +77,12 @@ public class DisplayModeDirectorTest {
|
|||||||
int displayId = 0;
|
int displayId = 0;
|
||||||
|
|
||||||
// With no votes present, DisplayModeDirector should allow any refresh rate.
|
// With no votes present, DisplayModeDirector should allow any refresh rate.
|
||||||
assertEquals(new DesiredDisplayModeSpecs(/*baseModeId=*/60,
|
DesiredDisplayModeSpecs modeSpecs =
|
||||||
new RefreshRateRange(0f, Float.POSITIVE_INFINITY)),
|
|
||||||
createDisplayModeDirectorWithDisplayFpsRange(60, 90).getDesiredDisplayModeSpecs(
|
createDisplayModeDirectorWithDisplayFpsRange(60, 90).getDesiredDisplayModeSpecs(
|
||||||
displayId));
|
displayId);
|
||||||
|
Truth.assertThat(modeSpecs.baseModeId).isEqualTo(60);
|
||||||
|
Truth.assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(0f);
|
||||||
|
Truth.assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(Float.POSITIVE_INFINITY);
|
||||||
|
|
||||||
int numPriorities =
|
int numPriorities =
|
||||||
DisplayModeDirector.Vote.MAX_PRIORITY - DisplayModeDirector.Vote.MIN_PRIORITY + 1;
|
DisplayModeDirector.Vote.MAX_PRIORITY - DisplayModeDirector.Vote.MIN_PRIORITY + 1;
|
||||||
@@ -101,10 +101,12 @@ public class DisplayModeDirectorTest {
|
|||||||
int priority = Vote.MIN_PRIORITY + i;
|
int priority = Vote.MIN_PRIORITY + i;
|
||||||
votes.put(priority, Vote.forRefreshRates(minFps + i, maxFps - i));
|
votes.put(priority, Vote.forRefreshRates(minFps + i, maxFps - i));
|
||||||
director.injectVotesByDisplay(votesByDisplay);
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
assertEquals(new DesiredDisplayModeSpecs(
|
modeSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
/*baseModeId=*/minFps + i,
|
Truth.assertThat(modeSpecs.baseModeId).isEqualTo(minFps + i);
|
||||||
new RefreshRateRange(minFps + i, maxFps - i)),
|
Truth.assertThat(modeSpecs.primaryRefreshRateRange.min)
|
||||||
director.getDesiredDisplayModeSpecs(displayId));
|
.isEqualTo((float) (minFps + i));
|
||||||
|
Truth.assertThat(modeSpecs.primaryRefreshRateRange.max)
|
||||||
|
.isEqualTo((float) (maxFps - i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,9 +121,10 @@ public class DisplayModeDirectorTest {
|
|||||||
votes.put(Vote.MAX_PRIORITY, Vote.forRefreshRates(65, 85));
|
votes.put(Vote.MAX_PRIORITY, Vote.forRefreshRates(65, 85));
|
||||||
votes.put(Vote.MIN_PRIORITY, Vote.forRefreshRates(70, 80));
|
votes.put(Vote.MIN_PRIORITY, Vote.forRefreshRates(70, 80));
|
||||||
director.injectVotesByDisplay(votesByDisplay);
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
assertEquals(new DesiredDisplayModeSpecs(/*baseModeId=*/70,
|
modeSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
new RefreshRateRange(70, 80)),
|
Truth.assertThat(modeSpecs.baseModeId).isEqualTo(70);
|
||||||
director.getDesiredDisplayModeSpecs(displayId));
|
Truth.assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(70f);
|
||||||
|
Truth.assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(80f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,8 +143,8 @@ public class DisplayModeDirectorTest {
|
|||||||
director.injectVotesByDisplay(votesByDisplay);
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
|
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
|
||||||
Truth.assertThat(desiredSpecs.baseModeId).isEqualTo(60);
|
Truth.assertThat(desiredSpecs.baseModeId).isEqualTo(60);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,34 +162,77 @@ public class DisplayModeDirectorTest {
|
|||||||
votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60));
|
votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60));
|
||||||
director.injectVotesByDisplay(votesByDisplay);
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
|
||||||
|
|
||||||
votes.clear();
|
votes.clear();
|
||||||
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 90));
|
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 90));
|
||||||
votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(90, 90));
|
votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(90, 90));
|
||||||
director.injectVotesByDisplay(votesByDisplay);
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90);
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90);
|
||||||
|
|
||||||
|
|
||||||
votes.clear();
|
votes.clear();
|
||||||
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(90, 90));
|
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(90, 90));
|
||||||
votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60));
|
votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60));
|
||||||
director.injectVotesByDisplay(votesByDisplay);
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90);
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90);
|
||||||
|
|
||||||
votes.clear();
|
votes.clear();
|
||||||
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 60));
|
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 60));
|
||||||
votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(90, 90));
|
votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(90, 90));
|
||||||
director.injectVotesByDisplay(votesByDisplay);
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
|
||||||
Truth.assertThat(desiredSpecs.refreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAppRequestRefreshRateRange() {
|
||||||
|
// Confirm that the app request range doesn't include low brightness or min refresh rate
|
||||||
|
// settings, but does include everything else.
|
||||||
|
assertTrue(
|
||||||
|
Vote.PRIORITY_LOW_BRIGHTNESS < Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF);
|
||||||
|
assertTrue(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE
|
||||||
|
< Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF);
|
||||||
|
assertTrue(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE
|
||||||
|
>= Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF);
|
||||||
|
|
||||||
|
int displayId = 0;
|
||||||
|
DisplayModeDirector director = createDisplayModeDirectorWithDisplayFpsRange(60, 90);
|
||||||
|
SparseArray<Vote> votes = new SparseArray<>();
|
||||||
|
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
|
||||||
|
votesByDisplay.put(displayId, votes);
|
||||||
|
votes.put(Vote.PRIORITY_LOW_BRIGHTNESS, Vote.forRefreshRates(60, 60));
|
||||||
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
|
DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
|
||||||
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
|
||||||
|
Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f);
|
||||||
|
Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.max).isAtLeast(90f);
|
||||||
|
|
||||||
|
votes.put(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE,
|
||||||
|
Vote.forRefreshRates(90, Float.POSITIVE_INFINITY));
|
||||||
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
|
desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90);
|
||||||
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isAtLeast(90f);
|
||||||
|
Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f);
|
||||||
|
Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.max).isAtLeast(90f);
|
||||||
|
|
||||||
|
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(75, 75));
|
||||||
|
director.injectVotesByDisplay(votesByDisplay);
|
||||||
|
desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
|
||||||
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(75);
|
||||||
|
Truth.assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(75);
|
||||||
|
Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.min)
|
||||||
|
.isWithin(FLOAT_TOLERANCE)
|
||||||
|
.of(75);
|
||||||
|
Truth.assertThat(desiredSpecs.appRequestRefreshRateRange.max)
|
||||||
|
.isWithin(FLOAT_TOLERANCE)
|
||||||
|
.of(75);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user