SurfaceFlinger: fix Sf/App offsets provided in getDisplayConfigs()

In getDisplayConfigs() SF needs to return the corresponding offsets
based on the config it is requested for and not the current config.

Test: manual
Fixes: 130257355
Change-Id: Ie151701cb8765c8bdaea683f328d9c43065ba6b0
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
index 7e2b03d..16f6729 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
@@ -86,8 +86,9 @@
     mHighRefreshRateOffsets.late = {highFpsLateSfOffsetNs, highFpsLateAppOffsetNs};
 }
 
-PhaseOffsets::Offsets PhaseOffsets::getCurrentOffsets() const {
-    switch (mRefreshRateType) {
+PhaseOffsets::Offsets PhaseOffsets::getOffsetsForRefreshRate(
+        android::scheduler::RefreshRateConfigs::RefreshRateType refreshRateType) const {
+    switch (refreshRateType) {
         case RefreshRateConfigs::RefreshRateType::PERFORMANCE:
             return mHighRefreshRateOffsets;
         default:
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.h b/services/surfaceflinger/Scheduler/PhaseOffsets.h
index cbcaade..f26259a 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.h
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.h
@@ -42,6 +42,8 @@
 
     virtual nsecs_t getCurrentAppOffset() = 0;
     virtual nsecs_t getCurrentSfOffset() = 0;
+    virtual Offsets getOffsetsForRefreshRate(
+            RefreshRateConfigs::RefreshRateType refreshRateType) const = 0;
     virtual Offsets getCurrentOffsets() const = 0;
     virtual void setRefreshRateType(RefreshRateConfigs::RefreshRateType refreshRateType) = 0;
     virtual void dump(std::string& result) const = 0;
@@ -55,8 +57,14 @@
     nsecs_t getCurrentAppOffset() override;
     nsecs_t getCurrentSfOffset() override;
 
+    // Returns early, early GL, and late offsets for Apps and SF for a given refresh rate.
+    Offsets getOffsetsForRefreshRate(
+            RefreshRateConfigs::RefreshRateType refreshRateType) const override;
+
     // Returns early, early GL, and late offsets for Apps and SF.
-    Offsets getCurrentOffsets() const override;
+    Offsets getCurrentOffsets() const override {
+        return getOffsetsForRefreshRate(mRefreshRateType);
+    }
 
     // This function should be called when the device is switching between different
     // refresh rates, to properly update the offsets.
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index eb9ae35..d730058 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -47,6 +47,8 @@
         std::string name;
         // Refresh rate in frames per second, rounded to the nearest integer.
         uint32_t fps = 0;
+        // config Id (returned from HWC2::Display::Config::getId())
+        hwc2_config_t id;
     };
 
     // TODO(b/122916473): Get this information from configs prepared by vendors, instead of
@@ -62,13 +64,24 @@
         return nullptr;
     }
 
+    RefreshRateType getRefreshRateType(hwc2_config_t id) const {
+        for (const auto& [type, refreshRate] : mRefreshRates) {
+            if (refreshRate->id == id) {
+                return type;
+            }
+        }
+
+        return RefreshRateType::DEFAULT;
+    }
+
     void populate(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) {
         mRefreshRates.clear();
 
         // This is the rate that HWC encapsulates right now when the device is in DOZE mode.
         mRefreshRates.emplace(RefreshRateType::POWER_SAVING,
                               std::make_shared<RefreshRate>(
-                                      RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0}));
+                                      RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0,
+                                                  HWC2_SCREEN_OFF_CONFIG_ID}));
 
         if (configs.size() < 1) {
             ALOGE("Device does not have valid configs. Config size is 0.");
@@ -91,11 +104,12 @@
         nsecs_t vsyncPeriod = configIdToVsyncPeriod[0].second;
         if (vsyncPeriod != 0) {
             const float fps = 1e9 / vsyncPeriod;
+            const int configId = configIdToVsyncPeriod[0].first;
             mRefreshRates.emplace(RefreshRateType::DEFAULT,
                                   std::make_shared<RefreshRate>(
-                                          RefreshRate{configIdToVsyncPeriod[0].first,
-                                                      base::StringPrintf("%2.ffps", fps),
-                                                      static_cast<uint32_t>(fps)}));
+                                          RefreshRate{configId, base::StringPrintf("%2.ffps", fps),
+                                                      static_cast<uint32_t>(fps),
+                                                      configs.at(configId)->getId()}));
         }
 
         if (configs.size() < 2) {
@@ -107,11 +121,12 @@
         vsyncPeriod = configIdToVsyncPeriod[1].second;
         if (vsyncPeriod != 0) {
             const float fps = 1e9 / vsyncPeriod;
+            const int configId = configIdToVsyncPeriod[1].first;
             mRefreshRates.emplace(RefreshRateType::PERFORMANCE,
                                   std::make_shared<RefreshRate>(
-                                          RefreshRate{configIdToVsyncPeriod[1].first,
-                                                      base::StringPrintf("%2.ffps", fps),
-                                                      static_cast<uint32_t>(fps)}));
+                                          RefreshRate{configId, base::StringPrintf("%2.ffps", fps),
+                                                      static_cast<uint32_t>(fps),
+                                                      configs.at(configId)->getId()}));
         }
     }
 
diff --git a/services/surfaceflinger/Scheduler/SchedulerUtils.h b/services/surfaceflinger/Scheduler/SchedulerUtils.h
index a935cac..3bf3922 100644
--- a/services/surfaceflinger/Scheduler/SchedulerUtils.h
+++ b/services/surfaceflinger/Scheduler/SchedulerUtils.h
@@ -34,6 +34,7 @@
 // the config is not visible to SF, and is completely maintained by HWC. However, we would
 // still like to keep track of time when the device is in this config.
 static constexpr int SCREEN_OFF_CONFIG_ID = -1;
+static constexpr uint32_t HWC2_SCREEN_OFF_CONFIG_ID = 0xffffffff;
 
 // This number is used when we try to determine how long does a given layer stay relevant.
 // Currently it is set to 100ms, because that would indicate 10Hz rendering.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fb0c712..716da12 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -860,7 +860,9 @@
         info.xdpi = xdpi;
         info.ydpi = ydpi;
         info.fps = 1e9 / hwConfig->getVsyncPeriod();
-        info.appVsyncOffset = mPhaseOffsets->getCurrentAppOffset();
+        const auto refreshRateType = mRefreshRateConfigs.getRefreshRateType(hwConfig->getId());
+        const auto offset = mPhaseOffsets->getOffsetsForRefreshRate(refreshRateType);
+        info.appVsyncOffset = offset.late.app;
 
         // This is how far in advance a buffer must be queued for
         // presentation at a given time.  If you want a buffer to appear
@@ -874,8 +876,7 @@
         //
         // We add an additional 1ms to allow for processing time and
         // differences between the ideal and actual refresh rate.
-        info.presentationDeadline =
-                hwConfig->getVsyncPeriod() - mPhaseOffsets->getCurrentSfOffset() + 1000000;
+        info.presentationDeadline = hwConfig->getVsyncPeriod() - offset.late.sf + 1000000;
 
         // All non-virtual displays are currently considered secure.
         info.secure = true;
diff --git a/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h b/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h
index 0739f15..cfa8337 100644
--- a/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h
+++ b/services/surfaceflinger/tests/unittests/FakePhaseOffsets.h
@@ -33,6 +33,11 @@
     nsecs_t getCurrentAppOffset() override { return FAKE_PHASE_OFFSET_NS; }
     nsecs_t getCurrentSfOffset() override { return FAKE_PHASE_OFFSET_NS; }
 
+    PhaseOffsets::Offsets getOffsetsForRefreshRate(
+            RefreshRateConfigs::RefreshRateType /*refreshRateType*/) const override {
+        return getCurrentOffsets();
+    }
+
     // Returns early, early GL, and late offsets for Apps and SF.
     PhaseOffsets::Offsets getCurrentOffsets() const override {
         return Offsets{{FAKE_PHASE_OFFSET_NS, FAKE_PHASE_OFFSET_NS},
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 8b37c22..5067fe8 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -37,7 +37,9 @@
 class RefreshRateConfigsTest : public testing::Test {
 protected:
     static constexpr int CONFIG_ID_60 = 0;
+    static constexpr hwc2_config_t HWC2_CONFIG_ID_60 = 0;
     static constexpr int CONFIG_ID_90 = 1;
+    static constexpr hwc2_config_t HWC2_CONFIG_ID_90 = 1;
     static constexpr int64_t VSYNC_60 = 16666667;
     static constexpr int64_t VSYNC_90 = 11111111;
 
@@ -81,7 +83,8 @@
     ASSERT_EQ(rates.end(), rates.find(RefreshRateType::PERFORMANCE));
     ASSERT_EQ(rates.end(), rates.find(RefreshRateType::DEFAULT));
 
-    RefreshRate expectedConfig = RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0};
+    RefreshRate expectedConfig =
+            RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0, HWC2_SCREEN_OFF_CONFIG_ID};
     assertRatesEqual(expectedConfig, *powerSavingRate->second);
 
     ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
@@ -109,9 +112,10 @@
     ASSERT_NE(rates.end(), defaultRate);
     ASSERT_EQ(rates.end(), rates.find(RefreshRateType::PERFORMANCE));
 
-    RefreshRate expectedPowerSavingConfig = RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0};
+    RefreshRate expectedPowerSavingConfig =
+            RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0, HWC2_SCREEN_OFF_CONFIG_ID};
     assertRatesEqual(expectedPowerSavingConfig, *powerSavingRate->second);
-    RefreshRate expectedDefaultConfig = RefreshRate{CONFIG_ID_60, "60fps", 60};
+    RefreshRate expectedDefaultConfig = RefreshRate{CONFIG_ID_60, "60fps", 60, HWC2_CONFIG_ID_60};
     assertRatesEqual(expectedDefaultConfig, *defaultRate->second);
 
     ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));
@@ -145,11 +149,13 @@
     ASSERT_NE(rates.end(), defaultRate);
     ASSERT_NE(rates.end(), performanceRate);
 
-    RefreshRate expectedPowerSavingConfig = RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0};
+    RefreshRate expectedPowerSavingConfig =
+            RefreshRate{SCREEN_OFF_CONFIG_ID, "ScreenOff", 0, HWC2_SCREEN_OFF_CONFIG_ID};
     assertRatesEqual(expectedPowerSavingConfig, *powerSavingRate->second);
-    RefreshRate expectedDefaultConfig = RefreshRate{CONFIG_ID_60, "60fps", 60};
+    RefreshRate expectedDefaultConfig = RefreshRate{CONFIG_ID_60, "60fps", 60, HWC2_CONFIG_ID_60};
     assertRatesEqual(expectedDefaultConfig, *defaultRate->second);
-    RefreshRate expectedPerformanceConfig = RefreshRate{CONFIG_ID_90, "90fps", 90};
+    RefreshRate expectedPerformanceConfig =
+            RefreshRate{CONFIG_ID_90, "90fps", 90, HWC2_CONFIG_ID_90};
     assertRatesEqual(expectedPerformanceConfig, *performanceRate->second);
 
     ASSERT_TRUE(mConfigs.getRefreshRate(RefreshRateType::POWER_SAVING));