SF: Unify data types for display modes

Remove the RefreshRateConfigs::RefreshRate wrapper around DisplayMode.
Store DisplayModes as a SmallMap, so that RefreshRateConfigs uses the
same data structure for lookup by ID. Use iterators into that map for
all bookkeeping in RefreshRateConfigs.

Bug: 182939859
Bug: 185535769
Test: libsurfaceflinger_unittest
Change-Id: I7708fa997089802c45d906b17b7a073f5c82105e
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 30d3edd..05a8692 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -56,50 +56,6 @@
     static constexpr nsecs_t MARGIN_FOR_PERIOD_CALCULATION =
             std::chrono::nanoseconds(800us).count();
 
-    class RefreshRate {
-    private:
-        // Effectively making the constructor private while allowing
-        // std::make_unique to create the object
-        struct ConstructorTag {
-            explicit ConstructorTag(int) {}
-        };
-
-    public:
-        RefreshRate(DisplayModePtr mode, ConstructorTag) : mode(mode) {}
-
-        DisplayModeId getModeId() const { return mode->getId(); }
-        nsecs_t getVsyncPeriod() const { return mode->getVsyncPeriod(); }
-        int32_t getModeGroup() const { return mode->getGroup(); }
-        std::string getName() const { return to_string(getFps()); }
-        Fps getFps() const { return mode->getFps(); }
-        DisplayModePtr getMode() const { return mode; }
-
-        // Checks whether the fps of this RefreshRate struct is within a given min and max refresh
-        // rate passed in. Margin of error is applied to the boundaries for approximation.
-        bool inPolicy(Fps minRefreshRate, Fps maxRefreshRate) const;
-
-        bool operator==(const RefreshRate& other) const { return mode == other.mode; }
-        bool operator!=(const RefreshRate& other) const { return !operator==(other); }
-
-        bool operator<(const RefreshRate& other) const {
-            return isStrictlyLess(getFps(), other.getFps());
-        }
-
-        std::string toString() const;
-        friend std::ostream& operator<<(std::ostream& os, const RefreshRate& refreshRate) {
-            return os << refreshRate.toString();
-        }
-
-    private:
-        friend RefreshRateConfigs;
-        friend class RefreshRateConfigsTest;
-
-        DisplayModePtr mode;
-    };
-
-    using AllRefreshRatesMapType =
-            std::unordered_map<DisplayModeId, std::unique_ptr<const RefreshRate>>;
-
     struct Policy {
     private:
         static constexpr int kAllowGroupSwitchingDefault = false;
@@ -236,12 +192,12 @@
 
     // Returns the refresh rate that best fits the given layers, and whether the refresh rate was
     // chosen based on touch boost and/or idle timer.
-    std::pair<RefreshRate, GlobalSignals> getBestRefreshRate(const std::vector<LayerRequirement>&,
-                                                             GlobalSignals) const EXCLUDES(mLock);
+    std::pair<DisplayModePtr, GlobalSignals> getBestRefreshRate(
+            const std::vector<LayerRequirement>&, GlobalSignals) const EXCLUDES(mLock);
 
     FpsRange getSupportedRefreshRateRange() const EXCLUDES(mLock) {
         std::lock_guard lock(mLock);
-        return {mMinSupportedRefreshRate->getFps(), mMaxSupportedRefreshRate->getFps()};
+        return {mMinRefreshRateModeIt->second->getFps(), mMaxRefreshRateModeIt->second->getFps()};
     }
 
     std::optional<Fps> onKernelTimerChanged(std::optional<DisplayModeId> desiredActiveModeId,
@@ -249,30 +205,15 @@
 
     // Returns the highest refresh rate according to the current policy. May change at runtime. Only
     // uses the primary range, not the app request range.
-    RefreshRate getMaxRefreshRateByPolicy() const EXCLUDES(mLock);
+    DisplayModePtr getMaxRefreshRateByPolicy() const EXCLUDES(mLock);
 
-    // Returns the current refresh rate
-    RefreshRate getCurrentRefreshRate() const EXCLUDES(mLock);
-
-    // Returns the current refresh rate, if allowed. Otherwise the default that is allowed by
-    // the policy.
-    RefreshRate getCurrentRefreshRateByPolicy() const;
-
-    // Returns the refresh rate that corresponds to a DisplayModeId. This may change at
-    // runtime.
-    // TODO(b/159590486) An invalid mode id may be given here if the dipslay modes have changed.
-    RefreshRate getRefreshRateFromModeId(DisplayModeId modeId) const EXCLUDES(mLock) {
-        std::lock_guard lock(mLock);
-        return *mRefreshRates.at(modeId);
-    };
-
-    // Stores the current modeId the device operates at
-    void setCurrentModeId(DisplayModeId) EXCLUDES(mLock);
+    void setActiveModeId(DisplayModeId) EXCLUDES(mLock);
+    DisplayModePtr getActiveMode() const EXCLUDES(mLock);
 
     // Returns a known frame rate that is the closest to frameRate
     Fps findClosestKnownFrameRate(Fps frameRate) const;
 
-    enum class KernelIdleTimerController { Sysprop, HwcApi };
+    enum class KernelIdleTimerController { Sysprop, HwcApi, ftl_last = HwcApi };
 
     // Configuration flags.
     struct Config {
@@ -291,7 +232,7 @@
         std::optional<KernelIdleTimerController> kernelIdleTimerController;
     };
 
-    RefreshRateConfigs(const DisplayModes&, DisplayModeId,
+    RefreshRateConfigs(DisplayModes, DisplayModeId activeModeId,
                        Config config = {.enableFrameRateOverride = false,
                                         .frameRateMultipleThreshold = 0,
                                         .idleTimerTimeout = 0ms,
@@ -305,7 +246,7 @@
     // differ in resolution.
     bool canSwitch() const EXCLUDES(mLock) {
         std::lock_guard lock(mLock);
-        return mRefreshRates.size() > 1;
+        return mDisplayModes.size() > 1;
     }
 
     // Class to enumerate options around toggling the kernel timer on and off.
@@ -323,7 +264,7 @@
     // Return the display refresh rate divisor to match the layer
     // frame rate, or 0 if the display refresh rate is not a multiple of the
     // layer refresh rate.
-    static int getFrameRateDivisor(Fps displayFrameRate, Fps layerFrameRate);
+    static int getFrameRateDivisor(Fps displayRefreshRate, Fps layerFrameRate);
 
     // Returns if the provided frame rates have a ratio t*1000/1001 or t*1001/1000
     // for an integer t.
@@ -391,54 +332,39 @@
 
     void constructAvailableRefreshRates() REQUIRES(mLock);
 
-    void getSortedRefreshRateListLocked(
-            const std::function<bool(const RefreshRate&)>& shouldAddRefreshRate,
-            std::vector<const RefreshRate*>* outRefreshRates) REQUIRES(mLock);
-
-    std::pair<RefreshRate, GlobalSignals> getBestRefreshRateLocked(
+    std::pair<DisplayModePtr, GlobalSignals> getBestRefreshRateLocked(
             const std::vector<LayerRequirement>&, GlobalSignals) const REQUIRES(mLock);
 
-    // Returns the refresh rate with the highest score in the collection specified from begin
-    // to end. If there are more than one with the same highest refresh rate, the first one is
-    // returned.
-    template <typename Iter>
-    const RefreshRate* getBestRefreshRate(Iter begin, Iter end) const;
-
     // Returns number of display frames and remainder when dividing the layer refresh period by
     // display refresh period.
     std::pair<nsecs_t, nsecs_t> getDisplayFrames(nsecs_t layerPeriod, nsecs_t displayPeriod) const;
 
     // Returns the lowest refresh rate according to the current policy. May change at runtime. Only
     // uses the primary range, not the app request range.
-    const RefreshRate& getMinRefreshRateByPolicyLocked() const REQUIRES(mLock);
+    const DisplayModePtr& getMinRefreshRateByPolicyLocked() const REQUIRES(mLock);
 
     // Returns the highest refresh rate according to the current policy. May change at runtime. Only
     // uses the primary range, not the app request range.
-    const RefreshRate& getMaxRefreshRateByPolicyLocked() const REQUIRES(mLock) {
-        return getMaxRefreshRateByPolicyLocked(mCurrentRefreshRate->getModeGroup());
+    const DisplayModePtr& getMaxRefreshRateByPolicyLocked(int anchorGroup) const REQUIRES(mLock);
+    const DisplayModePtr& getMaxRefreshRateByPolicyLocked() const REQUIRES(mLock) {
+        return getMaxRefreshRateByPolicyLocked(mActiveModeIt->second->getGroup());
     }
 
-    const RefreshRate& getMaxRefreshRateByPolicyLocked(int anchorGroup) const REQUIRES(mLock);
-
-    // Returns the current refresh rate, if allowed. Otherwise the default that is allowed by
-    // the policy.
-    const RefreshRate& getCurrentRefreshRateByPolicyLocked() const REQUIRES(mLock);
-
     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;
+    bool isVoteAllowed(const LayerRequirement&, Fps) 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&,
+    float calculateLayerScoreLocked(const LayerRequirement&, Fps refreshRate,
                                     bool isSeamlessSwitch) const REQUIRES(mLock);
 
-    float calculateNonExactMatchingLayerScoreLocked(const LayerRequirement&,
-                                                    const RefreshRate&) const REQUIRES(mLock);
+    float calculateNonExactMatchingLayerScoreLocked(const LayerRequirement&, Fps refreshRate) const
+            REQUIRES(mLock);
 
-    void updateDisplayModes(const DisplayModes& mode, DisplayModeId currentModeId) EXCLUDES(mLock);
+    void updateDisplayModes(DisplayModes, DisplayModeId activeModeId) EXCLUDES(mLock);
 
     void initializeIdleTimer();
 
@@ -449,32 +375,22 @@
                                                              : mIdleTimerCallbacks->platform;
     }
 
-    // The list of refresh rates, indexed by display modes ID. This may change after this
-    // object is initialized.
-    AllRefreshRatesMapType mRefreshRates GUARDED_BY(mLock);
+    // The display modes of the active display. The DisplayModeIterators below are pointers into
+    // this container, so must be invalidated whenever the DisplayModes change. The Policy below
+    // is also dependent, so must be reset as well.
+    DisplayModes mDisplayModes GUARDED_BY(mLock);
 
-    // The list of refresh rates in the primary range of the current policy, ordered by vsyncPeriod
-    // (the first element is the lowest refresh rate).
-    std::vector<const RefreshRate*> mPrimaryRefreshRates GUARDED_BY(mLock);
+    DisplayModeIterator mActiveModeIt GUARDED_BY(mLock);
+    DisplayModeIterator mMinRefreshRateModeIt GUARDED_BY(mLock);
+    DisplayModeIterator mMaxRefreshRateModeIt GUARDED_BY(mLock);
 
-    // The list of refresh rates in the app request range of the current policy, ordered by
-    // vsyncPeriod (the first element is the lowest refresh rate).
-    std::vector<const RefreshRate*> mAppRequestRefreshRates GUARDED_BY(mLock);
+    // Display modes that satisfy the Policy's ranges, filtered and sorted by refresh rate.
+    std::vector<DisplayModeIterator> mPrimaryRefreshRates GUARDED_BY(mLock);
+    std::vector<DisplayModeIterator> mAppRequestRefreshRates GUARDED_BY(mLock);
 
-    // The current display mode. This will change at runtime. This is set by SurfaceFlinger on
-    // the main thread, and read by the Scheduler (and other objects) on other threads.
-    const RefreshRate* mCurrentRefreshRate GUARDED_BY(mLock);
-
-    // The policy values will change at runtime. They're set by SurfaceFlinger on the main thread,
-    // and read by the Scheduler (and other objects) on other threads.
     Policy mDisplayManagerPolicy GUARDED_BY(mLock);
     std::optional<Policy> mOverridePolicy GUARDED_BY(mLock);
 
-    // The min and max refresh rates supported by the device.
-    // This may change at runtime.
-    const RefreshRate* mMinSupportedRefreshRate GUARDED_BY(mLock);
-    const RefreshRate* mMaxSupportedRefreshRate GUARDED_BY(mLock);
-
     mutable std::mutex mLock;
 
     // A sorted list of known frame rates that a Heuristic layer will choose
@@ -486,7 +402,7 @@
 
     struct GetBestRefreshRateCache {
         std::pair<std::vector<LayerRequirement>, GlobalSignals> arguments;
-        std::pair<RefreshRate, GlobalSignals> result;
+        std::pair<DisplayModePtr, GlobalSignals> result;
     };
     mutable std::optional<GetBestRefreshRateCache> mGetBestRefreshRateCache GUARDED_BY(mLock);