SF: Round the min/max checking to the closest int
Pixel display config is reporting FPS for a given display at 60.000004.
Make sure to take a small deviation into the account.
Test: manual. open swappy and change between refresh rates.
Test: manual. open setting and turn smooth display on/off.
Test: unit.
Change-Id: I0086c98406a2bd1a9b836fa171b8be14f3152acd
Bug: 147252378
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 847e20c..692ded9 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -126,7 +126,7 @@
return BAD_VALUE;
}
const RefreshRate& refreshRate = mRefreshRates.at(defaultConfigId);
- if (refreshRate.fps < minRefreshRate || refreshRate.fps > maxRefreshRate) {
+ if (!refreshRate.inPolicy(minRefreshRate, maxRefreshRate)) {
return BAD_VALUE;
}
mDefaultConfig = defaultConfigId;
@@ -180,8 +180,8 @@
group.value(), mMinRefreshRateFps, mMaxRefreshRateFps);
getSortedRefreshRateList(
[&](const RefreshRate& refreshRate) REQUIRES(mLock) {
- return refreshRate.configGroup == group && refreshRate.fps >= mMinRefreshRateFps &&
- refreshRate.fps <= mMaxRefreshRateFps;
+ return refreshRate.configGroup == group &&
+ refreshRate.inPolicy(mMinRefreshRateFps, mMaxRefreshRateFps);
},
&mAvailableRefreshRates);
LOG_ALWAYS_FATAL_IF(mAvailableRefreshRates.empty(),
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 1e740ca..0c3369a 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -44,6 +44,9 @@
class RefreshRateConfigs {
public:
struct RefreshRate {
+ // The tolerance within which we consider FPS approximately equals.
+ static constexpr float FPS_EPSILON = 0.001f;
+
RefreshRate(HwcConfigIndexType configId, nsecs_t vsyncPeriod,
HwcConfigGroupType configGroup, std::string name, float fps)
: configId(configId),
@@ -63,6 +66,12 @@
// Refresh rate in frames per second
const float fps = 0;
+ // Checks whether the fps of this RefreshRate struct is within a given min and max refresh
+ // rate passed in. FPS_EPSILON is applied to the boundaries for approximation.
+ bool inPolicy(float minRefreshRate, float maxRefreshRate) const {
+ return (fps >= (minRefreshRate - FPS_EPSILON) && fps <= (maxRefreshRate + FPS_EPSILON));
+ }
+
bool operator!=(const RefreshRate& other) const {
return configId != other.configId || vsyncPeriod != other.vsyncPeriod ||
configGroup != other.configGroup;
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index ed620ef..cc3c985 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -39,6 +39,7 @@
static inline const HwcConfigGroupType HWC_GROUP_ID_0 = HwcConfigGroupType(0);
static inline const HwcConfigGroupType HWC_GROUP_ID_1 = HwcConfigGroupType(1);
static constexpr int64_t VSYNC_60 = 16666667;
+ static constexpr int64_t VSYNC_60_POINT_4 = 16666665;
static constexpr int64_t VSYNC_90 = 11111111;
RefreshRateConfigsTest();
@@ -238,6 +239,16 @@
ASSERT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(24.0f));
}
+TEST_F(RefreshRateConfigsTest, testInPolicy) {
+ RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60_POINT_4, HWC_GROUP_ID_0,
+ "60fps", 60};
+ ASSERT_TRUE(expectedDefaultConfig.inPolicy(60.000004, 60.000004));
+ ASSERT_TRUE(expectedDefaultConfig.inPolicy(59.0f, 60.1f));
+ ASSERT_FALSE(expectedDefaultConfig.inPolicy(75.0, 90.0));
+ ASSERT_FALSE(expectedDefaultConfig.inPolicy(60.0011, 90.0));
+ ASSERT_FALSE(expectedDefaultConfig.inPolicy(50.0, 59.998));
+}
+
} // namespace
} // namespace scheduler
} // namespace android