SF: update consistent criteria for heuristic refresh rate calculation
Enlarge the consistent criteria to apply heuristic logic for more cases.
To prevent introducing oscillation, this makes sure to only select a
valid know refresh rate if all the frametime in the layer history have
the same nearest known refresh rate.
Bug: 299201319
Test: presubmit
Change-Id: Ie317f7fe337c84c2c7314069cba1bd02a147bf6b
diff --git a/services/surfaceflinger/Scheduler/LayerInfo.cpp b/services/surfaceflinger/Scheduler/LayerInfo.cpp
index bf3a7bc..8ee4ebb 100644
--- a/services/surfaceflinger/Scheduler/LayerInfo.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfo.cpp
@@ -276,17 +276,16 @@
if (const auto averageFrameTime = calculateAverageFrameTime()) {
const auto refreshRate = Fps::fromPeriodNsecs(*averageFrameTime);
- const bool refreshRateConsistent = mRefreshRateHistory.add(refreshRate, now);
- if (refreshRateConsistent) {
- const auto knownRefreshRate = selector.findClosestKnownFrameRate(refreshRate);
+ const auto closestKnownRefreshRate = mRefreshRateHistory.add(refreshRate, now, selector);
+ if (closestKnownRefreshRate.isValid()) {
using fps_approx_ops::operator!=;
// To avoid oscillation, use the last calculated refresh rate if it is close enough.
if (std::abs(mLastRefreshRate.calculated.getValue() - refreshRate.getValue()) >
MARGIN &&
- mLastRefreshRate.reported != knownRefreshRate) {
+ mLastRefreshRate.reported != closestKnownRefreshRate) {
mLastRefreshRate.calculated = refreshRate;
- mLastRefreshRate.reported = knownRefreshRate;
+ mLastRefreshRate.reported = closestKnownRefreshRate;
}
ALOGV("%s %s rounded to nearest known frame rate %s", mName.c_str(),
@@ -432,7 +431,8 @@
mRefreshRates.clear();
}
-bool LayerInfo::RefreshRateHistory::add(Fps refreshRate, nsecs_t now) {
+Fps LayerInfo::RefreshRateHistory::add(Fps refreshRate, nsecs_t now,
+ const RefreshRateSelector& selector) {
mRefreshRates.push_back({refreshRate, now});
while (mRefreshRates.size() >= HISTORY_SIZE ||
now - mRefreshRates.front().timestamp > HISTORY_DURATION.count()) {
@@ -447,11 +447,11 @@
ATRACE_INT(mHeuristicTraceTagData->average.c_str(), refreshRate.getIntValue());
}
- return isConsistent();
+ return selectRefreshRate(selector);
}
-bool LayerInfo::RefreshRateHistory::isConsistent() const {
- if (mRefreshRates.empty()) return true;
+Fps LayerInfo::RefreshRateHistory::selectRefreshRate(const RefreshRateSelector& selector) const {
+ if (mRefreshRates.empty()) return Fps();
const auto [min, max] =
std::minmax_element(mRefreshRates.begin(), mRefreshRates.end(),
@@ -459,8 +459,19 @@
return isStrictlyLess(lhs.refreshRate, rhs.refreshRate);
});
- const bool consistent =
- max->refreshRate.getValue() - min->refreshRate.getValue() < MARGIN_CONSISTENT_FPS;
+ const auto maxClosestRate = selector.findClosestKnownFrameRate(max->refreshRate);
+ const bool consistent = [&](Fps maxFps, Fps minFps) {
+ if (FlagManager::getInstance().use_known_refresh_rate_for_fps_consistency()) {
+ if (maxFps.getValue() - minFps.getValue() <
+ MARGIN_CONSISTENT_FPS_FOR_CLOSEST_REFRESH_RATE) {
+ const auto minClosestRate = selector.findClosestKnownFrameRate(minFps);
+ using fps_approx_ops::operator==;
+ return maxClosestRate == minClosestRate;
+ }
+ return false;
+ }
+ return maxFps.getValue() - minFps.getValue() < MARGIN_CONSISTENT_FPS;
+ }(max->refreshRate, min->refreshRate);
if (CC_UNLIKELY(sTraceEnabled)) {
if (!mHeuristicTraceTagData.has_value()) {
@@ -472,7 +483,7 @@
ATRACE_INT(mHeuristicTraceTagData->consistent.c_str(), consistent);
}
- return consistent;
+ return consistent ? maxClosestRate : Fps();
}
FrameRateCompatibility LayerInfo::FrameRate::convertCompatibility(int8_t compatibility) {