Add sysprop for refresh rate threshold.

When the sysprop is enabled, layers asking for heuristic or multiple
will not vote for multiples >= $threshold amount. For example, 24 fps
would normally vote 120 hz because it is a multiple. Instead, it should
use the scoring calculation to determine a refresh rate < 120 Hz.

This addresses 24 fps videos for 60Hz and 120 Hz displays. The request
wants the refresh rate vote to be 60 Hz. (see bug)

BUG: 190815773
Test: atest libsurfaceflinger_tests
Change-Id: If2619258b93fb9c30e09253266d3d65e1a732047
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 0eb16e2..4f47ed8 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -107,9 +107,39 @@
     return {quotient, remainder};
 }
 
+bool RefreshRateConfigs::isVoteAllowed(const LayerRequirement& layer,
+                                       const RefreshRate& refreshRate) const {
+    switch (layer.vote) {
+        case LayerVoteType::ExplicitExactOrMultiple:
+        case LayerVoteType::Heuristic:
+            if (mConfig.frameRateMultipleThreshold != 0 &&
+                refreshRate.fps.greaterThanOrEqualWithMargin(
+                        Fps(mConfig.frameRateMultipleThreshold)) &&
+                layer.desiredRefreshRate.lessThanWithMargin(
+                        Fps(mConfig.frameRateMultipleThreshold / 2))) {
+                // Don't vote high refresh rates past the threshold for layers with a low desired
+                // refresh rate. For example, desired 24 fps with 120 Hz threshold means no vote for
+                // 120 Hz, but desired 60 fps should have a vote.
+                return false;
+            }
+            break;
+        case LayerVoteType::ExplicitDefault:
+        case LayerVoteType::ExplicitExact:
+        case LayerVoteType::Max:
+        case LayerVoteType::Min:
+        case LayerVoteType::NoVote:
+            break;
+    }
+    return true;
+}
+
 float RefreshRateConfigs::calculateLayerScoreLocked(const LayerRequirement& layer,
                                                     const RefreshRate& refreshRate,
                                                     bool isSeamlessSwitch) const {
+    if (!isVoteAllowed(layer, refreshRate)) {
+        return 0;
+    }
+
     // Slightly prefer seamless switches.
     constexpr float kSeamedSwitchPenalty = 0.95f;
     const float seamlessness = isSeamlessSwitch ? 1.0f : kSeamedSwitchPenalty;
@@ -331,8 +361,9 @@
     const auto& defaultMode = mRefreshRates.at(policy->defaultMode);
 
     for (const auto& layer : layers) {
-        ALOGV("Calculating score for %s (%s, weight %.2f)", layer.name.c_str(),
-              layerVoteTypeString(layer.vote).c_str(), layer.weight);
+        ALOGV("Calculating score for %s (%s, weight %.2f, desired %.2f) ", layer.name.c_str(),
+              layerVoteTypeString(layer.vote).c_str(), layer.weight,
+              layer.desiredRefreshRate.getValue());
         if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min) {
             continue;
         }
@@ -646,9 +677,8 @@
 }
 
 RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& modes, DisplayModeId currentModeId,
-                                       bool enableFrameRateOverride)
-      : mKnownFrameRates(constructKnownFrameRates(modes)),
-        mEnableFrameRateOverride(enableFrameRateOverride) {
+                                       Config config)
+      : mKnownFrameRates(constructKnownFrameRates(modes)), mConfig(config) {
     updateDisplayModes(modes, currentModeId);
 }
 
@@ -685,7 +715,7 @@
     mMaxSupportedRefreshRate = sortedModes.back();
 
     mSupportsFrameRateOverride = false;
-    if (mEnableFrameRateOverride) {
+    if (mConfig.enableFrameRateOverride) {
         for (const auto& mode1 : sortedModes) {
             for (const auto& mode2 : sortedModes) {
                 if (getFrameRateDivider(mode1->getFps(), mode2->getFps()) >= 2) {
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 6cd0f42..0358e8c 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -53,7 +53,7 @@
 public:
     // Margin used when matching refresh rates to the content desired ones.
     static constexpr nsecs_t MARGIN_FOR_PERIOD_CALCULATION =
-        std::chrono::nanoseconds(800us).count();
+            std::chrono::nanoseconds(800us).count();
 
     class RefreshRate {
     private:
@@ -302,8 +302,19 @@
     // Returns a known frame rate that is the closest to frameRate
     Fps findClosestKnownFrameRate(Fps frameRate) const;
 
+    // Configuration flags.
+    struct Config {
+        bool enableFrameRateOverride = false;
+
+        // Specifies the upper refresh rate threshold (inclusive) for layer vote types of multiple
+        // or heuristic, such that refresh rates higher than this value will not be voted for. 0 if
+        // no threshold is set.
+        int frameRateMultipleThreshold = 0;
+    };
+
     RefreshRateConfigs(const DisplayModes& modes, DisplayModeId currentModeId,
-                       bool enableFrameRateOverride = false);
+                       Config config = {.enableFrameRateOverride = false,
+                                        .frameRateMultipleThreshold = 0});
 
     void updateDisplayModes(const DisplayModes& mode, DisplayModeId currentModeId) EXCLUDES(mLock);
 
@@ -387,6 +398,9 @@
     const Policy* getCurrentPolicyLocked() const REQUIRES(mLock);
     bool isPolicyValidLocked(const Policy& policy) const REQUIRES(mLock);
 
+    // Returns whether the layer is allowed to vote for the given refresh rate.
+    bool isVoteAllowed(const LayerRequirement&, const RefreshRate&) const;
+
     // calculates a score for a layer. Used to determine the display refresh rate
     // and the frame rate override for certains applications.
     float calculateLayerScoreLocked(const LayerRequirement&, const RefreshRate&,
@@ -424,7 +438,7 @@
     // from based on the closest value.
     const std::vector<Fps> mKnownFrameRates;
 
-    const bool mEnableFrameRateOverride;
+    const Config mConfig;
     bool mSupportsFrameRateOverride;
 
     struct GetBestRefreshRateInvocation {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f346465..e2f3ebb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3118,10 +3118,15 @@
         return;
     }
     const auto displayId = displayState.physical->id;
-    mRefreshRateConfigs = std::make_unique<
-            scheduler::RefreshRateConfigs>(displayState.physical->supportedModes,
-                                           displayState.physical->activeMode->getId(),
-                                           android::sysprop::enable_frame_rate_override(false));
+    scheduler::RefreshRateConfigs::Config config =
+            {.enableFrameRateOverride = android::sysprop::enable_frame_rate_override(false),
+             .frameRateMultipleThreshold =
+                     base::GetIntProperty("debug.sf.frame_rate_multiple_threshold", 0)};
+    mRefreshRateConfigs =
+            std::make_unique<scheduler::RefreshRateConfigs>(displayState.physical->supportedModes,
+                                                            displayState.physical->activeMode
+                                                                    ->getId(),
+                                                            config);
     const auto currRefreshRate = displayState.physical->activeMode->getFps();
     mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate,
                                                                       hal::PowerMode::OFF);
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index d4b229f..9bb5ca1 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -165,6 +165,7 @@
                                      RefreshRate::ConstructorTag(0)};
     RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, Fps(120),
                                       RefreshRate::ConstructorTag(0)};
+
 private:
     DisplayModePtr createDisplayMode(DisplayModeId modeId, int32_t group, int64_t vsyncPeriod,
                                      ui::Size resolution = ui::Size());
@@ -487,6 +488,52 @@
               refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
+TEST_F(RefreshRateConfigsTest, getBestRefreshRate_multipleThreshold_60_90) {
+    RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 90};
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);
+
+    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
+    auto& lr = layers[0];
+
+    lr.vote = LayerVoteType::Min;
+    lr.name = "Min";
+    EXPECT_EQ(mExpected60Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr.vote = LayerVoteType::Max;
+    lr.name = "Max";
+    EXPECT_EQ(mExpected90Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr.desiredRefreshRate = Fps(90.0f);
+    lr.vote = LayerVoteType::Heuristic;
+    lr.name = "90Hz Heuristic";
+    EXPECT_EQ(mExpected90Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr.desiredRefreshRate = Fps(60.0f);
+    lr.name = "60Hz Heuristic";
+    EXPECT_EQ(mExpected60Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr.desiredRefreshRate = Fps(45.0f);
+    lr.name = "45Hz Heuristic";
+    EXPECT_EQ(mExpected90Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr.desiredRefreshRate = Fps(30.0f);
+    lr.name = "30Hz Heuristic";
+    EXPECT_EQ(mExpected60Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr.desiredRefreshRate = Fps(24.0f);
+    lr.name = "24Hz Heuristic";
+    EXPECT_EQ(mExpected60Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+}
+
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) {
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_72_90Device,
@@ -649,6 +696,99 @@
               refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
+TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes_multipleThreshold) {
+    RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120};
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);
+
+    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
+                                                LayerRequirement{.weight = 1.0f}};
+    auto& lr1 = layers[0];
+    auto& lr2 = layers[1];
+
+    lr1.desiredRefreshRate = Fps(24.0f);
+    lr1.vote = LayerVoteType::ExplicitDefault;
+    lr1.name = "24Hz ExplicitDefault";
+    lr2.desiredRefreshRate = Fps(60.0f);
+    lr2.vote = LayerVoteType::Heuristic;
+    lr2.name = "60Hz Heuristic";
+    EXPECT_EQ(mExpected120Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr1.desiredRefreshRate = Fps(24.0f);
+    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+    lr1.name = "24Hz ExplicitExactOrMultiple";
+    lr2.desiredRefreshRate = Fps(60.0f);
+    lr2.vote = LayerVoteType::Heuristic;
+    lr2.name = "60Hz Heuristic";
+    EXPECT_EQ(mExpected60Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr1.desiredRefreshRate = Fps(24.0f);
+    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+    lr1.name = "24Hz ExplicitExactOrMultiple";
+    lr2.desiredRefreshRate = Fps(60.0f);
+    lr2.vote = LayerVoteType::ExplicitDefault;
+    lr2.name = "60Hz ExplicitDefault";
+    EXPECT_EQ(mExpected72Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr1.desiredRefreshRate = Fps(24.0f);
+    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+    lr1.name = "24Hz ExplicitExactOrMultiple";
+    lr2.desiredRefreshRate = Fps(90.0f);
+    lr2.vote = LayerVoteType::Heuristic;
+    lr2.name = "90Hz Heuristic";
+    EXPECT_EQ(mExpected90Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr1.desiredRefreshRate = Fps(24.0f);
+    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+    lr1.name = "24Hz ExplicitExactOrMultiple";
+    lr2.desiredRefreshRate = Fps(90.0f);
+    lr2.vote = LayerVoteType::ExplicitDefault;
+    lr2.name = "90Hz Heuristic";
+    EXPECT_EQ(mExpected72Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr1.desiredRefreshRate = Fps(24.0f);
+    lr1.vote = LayerVoteType::ExplicitDefault;
+    lr1.name = "24Hz ExplicitDefault";
+    lr2.desiredRefreshRate = Fps(90.0f);
+    lr2.vote = LayerVoteType::Heuristic;
+    lr2.name = "90Hz Heuristic";
+    EXPECT_EQ(mExpected90Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr1.desiredRefreshRate = Fps(24.0f);
+    lr1.vote = LayerVoteType::Heuristic;
+    lr1.name = "24Hz Heuristic";
+    lr2.desiredRefreshRate = Fps(90.0f);
+    lr2.vote = LayerVoteType::ExplicitDefault;
+    lr2.name = "90Hz ExplicitDefault";
+    EXPECT_EQ(mExpected72Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr1.desiredRefreshRate = Fps(24.0f);
+    lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+    lr1.name = "24Hz ExplicitExactOrMultiple";
+    lr2.desiredRefreshRate = Fps(90.0f);
+    lr2.vote = LayerVoteType::ExplicitDefault;
+    lr2.name = "90Hz ExplicitDefault";
+    EXPECT_EQ(mExpected72Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    lr1.desiredRefreshRate = Fps(24.0f);
+    lr1.vote = LayerVoteType::ExplicitDefault;
+    lr1.name = "24Hz ExplicitDefault";
+    lr2.desiredRefreshRate = Fps(90.0f);
+    lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
+    lr2.name = "90Hz ExplicitExactOrMultiple";
+    EXPECT_EQ(mExpected90Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+}
+
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) {
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60Device,
@@ -819,6 +959,24 @@
     }
 }
 
+TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo_multipleThreshold_60_120) {
+    RefreshRateConfigs::Config config = {.frameRateMultipleThreshold = 120};
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m60_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);
+
+    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
+    auto& lr = layers[0];
+
+    lr.vote = LayerVoteType::ExplicitExactOrMultiple;
+    for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) {
+        lr.desiredRefreshRate = Fps(fps);
+        const auto& refreshRate =
+                refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
+        EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName();
+    }
+}
+
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getBestRefreshRate_Explicit) {
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90Device,
@@ -1732,10 +1890,10 @@
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) {
+    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
-                                                 /*currentConfigId=*/HWC_CONFIG_ID_60,
-                                                 /*enableFrameRateOverride=*/true);
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 0.5f}};
@@ -1846,10 +2004,10 @@
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactTouchBoost) {
+    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_120Device,
-                                                 /*currentConfigId=*/HWC_CONFIG_ID_60,
-                                                 /*enableFrameRateOverride=*/true);
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60, config);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 0.5f}};
@@ -1950,10 +2108,10 @@
 }
 
 TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) {
+    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
-                                                 HWC_CONFIG_ID_120,
-                                                 /*enableFrameRateOverride=*/true);
+                                                 HWC_CONFIG_ID_120, config);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     layers[0].name = "Test layer";
@@ -1995,10 +2153,10 @@
 }
 
 TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) {
+    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
-                                                 HWC_CONFIG_ID_120,
-                                                 /*enableFrameRateOverride=*/true);
+                                                 HWC_CONFIG_ID_120, config);
 
     auto layers = std::vector<LayerRequirement>{
             LayerRequirement{.ownerUid = 1234, .weight = 1.0f},
@@ -2035,10 +2193,10 @@
 }
 
 TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) {
+    RefreshRateConfigs::Config config = {.enableFrameRateOverride = true};
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
-                                                 HWC_CONFIG_ID_120,
-                                                 /*enableFrameRateOverride=*/true);
+                                                 HWC_CONFIG_ID_120, config);
 
     auto layers = std::vector<LayerRequirement>{
             LayerRequirement{.ownerUid = 1234, .weight = 1.0f},