SF: store the render frame rate in RefreshRateConfigs::Policy
Add plumbing for the render frame rate passed from DM and update the
policy accordingly.
Test: SF unit tests
Bug: 241460058
Change-Id: I86088001d6d6e5302516f42aa5c9ede4a918dae1
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 40af6ee..f22f9e7 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -164,9 +164,10 @@
std::string RefreshRateSelector::Policy::toString() const {
return base::StringPrintf("{defaultModeId=%d, allowGroupSwitching=%s"
- ", primaryRange=%s, appRequestRange=%s}",
+ ", primaryRanges=%s, appRequestRanges=%s}",
defaultMode.value(), allowGroupSwitching ? "true" : "false",
- to_string(primaryRange).c_str(), to_string(appRequestRange).c_str());
+ to_string(primaryRanges).c_str(),
+ to_string(appRequestRanges).c_str());
}
std::pair<nsecs_t, nsecs_t> RefreshRateSelector::getDisplayFrames(nsecs_t layerPeriod,
@@ -381,7 +382,7 @@
// move out the of range if layers explicitly request a different refresh
// rate.
const bool primaryRangeIsSingleRate =
- isApproxEqual(policy->primaryRange.min, policy->primaryRange.max);
+ isApproxEqual(policy->primaryRanges.physical.min, policy->primaryRanges.physical.max);
if (!signals.touch && signals.idle && !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) {
ALOGV("Idle");
@@ -450,7 +451,7 @@
continue;
}
- const bool inPrimaryRange = policy->primaryRange.includes(mode->getFps());
+ const bool inPrimaryRange = policy->primaryRanges.physical.includes(mode->getFps());
if ((primaryRangeIsSingleRate || !inPrimaryRange) &&
!(layer.focused &&
(layer.vote == LayerVoteType::ExplicitDefault ||
@@ -902,7 +903,7 @@
bool RefreshRateSelector::isPolicyValidLocked(const Policy& policy) const {
// defaultMode must be a valid mode, and within the given refresh rate range.
if (const auto mode = mDisplayModes.get(policy.defaultMode)) {
- if (!policy.primaryRange.includes(mode->get()->getFps())) {
+ if (!policy.primaryRanges.physical.includes(mode->get()->getFps())) {
ALOGE("Default mode is not in the primary range.");
return false;
}
@@ -912,8 +913,8 @@
}
using namespace fps_approx_ops;
- return policy.appRequestRange.min <= policy.primaryRange.min &&
- policy.appRequestRange.max >= policy.primaryRange.max;
+ return policy.appRequestRanges.physical.min <= policy.primaryRanges.physical.min &&
+ policy.appRequestRanges.physical.max >= policy.primaryRanges.physical.max;
}
auto RefreshRateSelector::setPolicy(const PolicyVariant& policy) -> SetPolicyResult {
@@ -1026,8 +1027,8 @@
return modes;
};
- mPrimaryRefreshRates = filterRefreshRates(policy->primaryRange, "primary");
- mAppRequestRefreshRates = filterRefreshRates(policy->appRequestRange, "app request");
+ mPrimaryRefreshRates = filterRefreshRates(policy->primaryRanges.physical, "primary");
+ mAppRequestRefreshRates = filterRefreshRates(policy->appRequestRanges.physical, "app request");
}
Fps RefreshRateSelector::findClosestKnownFrameRate(Fps frameRate) const {
@@ -1067,7 +1068,7 @@
if (minByPolicy == maxByPolicy) {
// Turn on the timer when the min of the primary range is below the device min.
if (const Policy* currentPolicy = getCurrentPolicyLocked();
- isApproxLess(currentPolicy->primaryRange.min, deviceMinFps)) {
+ isApproxLess(currentPolicy->primaryRanges.physical.min, deviceMinFps)) {
return KernelIdleTimerAction::TurnOn;
}
return KernelIdleTimerAction::TurnOff;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.h b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
index bff16d3..887d815 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
@@ -67,40 +67,31 @@
DisplayModeId defaultMode;
// Whether or not we switch mode groups to get the best frame rate.
bool allowGroupSwitching = kAllowGroupSwitchingDefault;
- // The primary refresh rate range represents display manager's general guidance on the
- // display modes we'll consider when switching refresh rates. Unless we get an explicit
- // signal from an app, we should stay within this range.
- FpsRange primaryRange;
- // The app request refresh rate range allows us to consider more display modes when
- // switching refresh rates. Although we should generally stay within the primary range,
- // specific considerations, such as layer frame rate settings specified via the
- // setFrameRate() api, may cause us to go outside the primary range. We never go outside the
- // app request range. The app request range will be greater than or equal to the primary
- // refresh rate range, never smaller.
- FpsRange appRequestRange;
+ // The primary refresh rate ranges. @see DisplayModeSpecs.aidl for details.
+ // TODO(b/257072060): use the render range when selecting SF render rate
+ // or the app override frame rate
+ FpsRanges primaryRanges;
+ // The app request refresh rate ranges. @see DisplayModeSpecs.aidl for details.
+ FpsRanges appRequestRanges;
Policy() = default;
- Policy(DisplayModeId defaultMode, FpsRange range)
- : Policy(defaultMode, kAllowGroupSwitchingDefault, range, range) {}
+ Policy(DisplayModeId defaultMode, FpsRange range,
+ bool allowGroupSwitching = kAllowGroupSwitchingDefault)
+ : Policy(defaultMode, FpsRanges{range, range}, FpsRanges{range, range},
+ allowGroupSwitching) {}
- Policy(DisplayModeId defaultMode, bool allowGroupSwitching, FpsRange range)
- : Policy(defaultMode, allowGroupSwitching, range, range) {}
-
- Policy(DisplayModeId defaultMode, FpsRange primaryRange, FpsRange appRequestRange)
- : Policy(defaultMode, kAllowGroupSwitchingDefault, primaryRange, appRequestRange) {}
-
- Policy(DisplayModeId defaultMode, bool allowGroupSwitching, FpsRange primaryRange,
- FpsRange appRequestRange)
+ Policy(DisplayModeId defaultMode, FpsRanges primaryRanges, FpsRanges appRequestRanges,
+ bool allowGroupSwitching = kAllowGroupSwitchingDefault)
: defaultMode(defaultMode),
allowGroupSwitching(allowGroupSwitching),
- primaryRange(primaryRange),
- appRequestRange(appRequestRange) {}
+ primaryRanges(primaryRanges),
+ appRequestRanges(appRequestRanges) {}
bool operator==(const Policy& other) const {
using namespace fps_approx_ops;
- return defaultMode == other.defaultMode && primaryRange == other.primaryRange &&
- appRequestRange == other.appRequestRange &&
+ return defaultMode == other.defaultMode && primaryRanges == other.primaryRanges &&
+ appRequestRanges == other.appRequestRanges &&
allowGroupSwitching == other.allowGroupSwitching;
}
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/Fps.h b/services/surfaceflinger/Scheduler/include/scheduler/Fps.h
index bd4f409..d89f685 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/Fps.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/Fps.h
@@ -68,6 +68,15 @@
bool includes(Fps) const;
};
+struct FpsRanges {
+ // The range of refresh rates that refers to the display mode setting.
+ FpsRange physical;
+
+ // the range of frame rates that refers to the render rate, which is
+ // the rate that frames are swapped.
+ FpsRange render;
+};
+
static_assert(std::is_trivially_copyable_v<Fps>);
constexpr Fps operator""_Hz(unsigned long long frequency) {
@@ -127,6 +136,14 @@
return !(lhs == rhs);
}
+inline bool operator==(const FpsRanges& lhs, const FpsRanges& rhs) {
+ return lhs.physical == rhs.physical && lhs.render == rhs.render;
+}
+
+inline bool operator!=(const FpsRanges& lhs, const FpsRanges& rhs) {
+ return !(lhs == rhs);
+}
+
} // namespace fps_approx_ops
inline bool FpsRange::includes(Fps fps) const {
@@ -151,4 +168,10 @@
return base::StringPrintf("[%s, %s]", to_string(min).c_str(), to_string(max).c_str());
}
+inline std::string to_string(FpsRanges ranges) {
+ const auto& [physical, render] = ranges;
+ return base::StringPrintf("{physical=%s, render=%s}", to_string(physical).c_str(),
+ to_string(render).c_str());
+}
+
} // namespace android