SF: Move mode caching from Scheduler to RefreshRateConfigs

In the existing behavior Scheduler checks if the
layerReuquirements have changes since the last time
and only then calls into RefreshRateConfigs to
getBestRefreshRate. There are two problems with that

1. on the first iteration of the algorithm
   mFeatures.contentRequirements is empty. If we happen
   to have an empty list of current content requirements
   (for example if all layers have NoVote), we
   won't execute the refresh rate selection algorithm
   and we'll end up with a wrong initial refresh rate.

2. the cached value needs to be invalided when one of
   these change
    - globalSignals
    - supported display modes (happens on TV)
    - display manager policy

Bug: 188872896
Test: atest SchedulerTest RefreshRateConfigsTest
Change-Id: I101f401522fae8358752e283d8375caa93957b6a
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 7ace70a..d04a7d7 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -45,9 +45,16 @@
 
 class RefreshRateConfigsTest : public testing::Test {
 protected:
+    using GetBestRefreshRateInvocation = RefreshRateConfigs::GetBestRefreshRateInvocation;
+
     RefreshRateConfigsTest();
     ~RefreshRateConfigsTest();
 
+    RefreshRate createRefreshRate(DisplayModePtr displayMode) {
+        return {displayMode->getId(), displayMode, displayMode->getFps(),
+                RefreshRate::ConstructorTag(0)};
+    }
+
     Fps findClosestKnownFrameRate(const RefreshRateConfigs& refreshRateConfigs, Fps frameRate) {
         return refreshRateConfigs.findClosestKnownFrameRate(frameRate);
     }
@@ -71,6 +78,19 @@
         return *refreshRateConfigs.mMaxSupportedRefreshRate;
     }
 
+    void setLastBestRefreshRateInvocation(RefreshRateConfigs& refreshRateConfigs,
+                                          const GetBestRefreshRateInvocation& invocation) {
+        std::lock_guard lock(refreshRateConfigs.mLock);
+        refreshRateConfigs.lastBestRefreshRateInvocation.emplace(
+                GetBestRefreshRateInvocation(invocation));
+    }
+
+    std::optional<GetBestRefreshRateInvocation> getLastBestRefreshRateInvocation(
+            const RefreshRateConfigs& refreshRateConfigs) {
+        std::lock_guard lock(refreshRateConfigs.mLock);
+        return refreshRateConfigs.lastBestRefreshRateInvocation;
+    }
+
     // Test config IDs
     static inline const DisplayModeId HWC_CONFIG_ID_60 = DisplayModeId(0);
     static inline const DisplayModeId HWC_CONFIG_ID_90 = DisplayModeId(1);
@@ -1752,6 +1772,78 @@
               refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
+TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ReadsCached) {
+    using GlobalSignals = RefreshRateConfigs::GlobalSignals;
+
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
+
+    setLastBestRefreshRateInvocation(*refreshRateConfigs,
+                                     GetBestRefreshRateInvocation{.layerRequirements = std::vector<
+                                                                          LayerRequirement>(),
+                                                                  .globalSignals = {.touch = true,
+                                                                                    .idle = true},
+                                                                  .outSignalsConsidered =
+                                                                          {.touch = true,
+                                                                           .idle = false},
+                                                                  .resultingBestRefreshRate =
+                                                                          createRefreshRate(
+                                                                                  mConfig90)});
+
+    EXPECT_EQ(createRefreshRate(mConfig90),
+              refreshRateConfigs->getBestRefreshRate(std::vector<LayerRequirement>(),
+                                                     {.touch = true, .idle = true}));
+
+    const GlobalSignals cachedSignalsConsidered{.touch = true, .idle = false};
+    setLastBestRefreshRateInvocation(*refreshRateConfigs,
+                                     GetBestRefreshRateInvocation{.layerRequirements = std::vector<
+                                                                          LayerRequirement>(),
+                                                                  .globalSignals = {.touch = true,
+                                                                                    .idle = true},
+                                                                  .outSignalsConsidered =
+                                                                          cachedSignalsConsidered,
+                                                                  .resultingBestRefreshRate =
+                                                                          createRefreshRate(
+                                                                                  mConfig30)});
+
+    GlobalSignals signalsConsidered;
+    EXPECT_EQ(createRefreshRate(mConfig30),
+              refreshRateConfigs->getBestRefreshRate(std::vector<LayerRequirement>(),
+                                                     {.touch = true, .idle = true},
+                                                     &signalsConsidered));
+
+    EXPECT_EQ(cachedSignalsConsidered, signalsConsidered);
+}
+
+TEST_F(RefreshRateConfigsTest, getBestRefreshRate_WritesCache) {
+    using GlobalSignals = RefreshRateConfigs::GlobalSignals;
+
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
+    ASSERT_FALSE(getLastBestRefreshRateInvocation(*refreshRateConfigs).has_value());
+
+    GlobalSignals globalSignals{.touch = true, .idle = true};
+    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
+                                                LayerRequirement{.weight = 0.5f}};
+    const auto lastResult =
+            refreshRateConfigs->getBestRefreshRate(layers, globalSignals,
+                                                   /* outSignalsConsidered */ nullptr);
+
+    const auto lastInvocation = getLastBestRefreshRateInvocation(*refreshRateConfigs);
+
+    ASSERT_TRUE(lastInvocation.has_value());
+    ASSERT_EQ(layers, lastInvocation->layerRequirements);
+    ASSERT_EQ(globalSignals, lastInvocation->globalSignals);
+    ASSERT_EQ(lastResult, lastInvocation->resultingBestRefreshRate);
+
+    // outSignalsConsidered needs to be populated even tho earlier we gave nullptr
+    // to getBestRefreshRate()
+    GlobalSignals detaultSignals;
+    ASSERT_FALSE(detaultSignals == lastInvocation->outSignalsConsidered);
+}
+
 TEST_F(RefreshRateConfigsTest, testComparisonOperator) {
     EXPECT_TRUE(mExpected60Config < mExpected90Config);
     EXPECT_FALSE(mExpected60Config < mExpected60Config);