SurfaceFlinger: throttle applications based on uid

Add the ability for SurfaceFlinger to be able to throttle down to
a divider of the refresh rate (i.e. for 30/45 for 90Hz)

Change-Id: I6bfd6f43ee1f30e771a136c558d8ae9a6d7fbe0f
Test: Manually via 1039 SF backdoor
Bug: 170502573
Bug: 169270763
Bug: 169271059
diff --git a/services/surfaceflinger/Scheduler/VSyncPredictor.h b/services/surfaceflinger/Scheduler/VSyncPredictor.h
index 5f2ec49..381cf81 100644
--- a/services/surfaceflinger/Scheduler/VSyncPredictor.h
+++ b/services/surfaceflinger/Scheduler/VSyncPredictor.h
@@ -38,10 +38,10 @@
                    uint32_t outlierTolerancePercent);
     ~VSyncPredictor();
 
-    bool addVsyncTimestamp(nsecs_t timestamp) final;
-    nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const final;
-    nsecs_t currentPeriod() const final;
-    void resetModel() final;
+    bool addVsyncTimestamp(nsecs_t timestamp) final EXCLUDES(mMutex);
+    nsecs_t nextAnticipatedVSyncTimeFrom(nsecs_t timePoint) const final EXCLUDES(mMutex);
+    nsecs_t currentPeriod() const final EXCLUDES(mMutex);
+    void resetModel() final EXCLUDES(mMutex);
 
     /*
      * Inform the model that the period is anticipated to change to a new value.
@@ -50,16 +50,23 @@
      *
      * \param [in] period   The new period that should be used.
      */
-    void setPeriod(nsecs_t period) final;
+    void setPeriod(nsecs_t period) final EXCLUDES(mMutex);
 
     /* Query if the model is in need of more samples to make a prediction.
      * \return  True, if model would benefit from more samples, False if not.
      */
-    bool needsMoreSamples() const final;
+    bool needsMoreSamples() const final EXCLUDES(mMutex);
 
-    std::tuple<nsecs_t /* slope */, nsecs_t /* intercept */> getVSyncPredictionModel() const;
+    struct Model {
+        nsecs_t slope;
+        nsecs_t intercept;
+    };
 
-    void dump(std::string& result) const final;
+    VSyncPredictor::Model getVSyncPredictionModel() const EXCLUDES(mMutex);
+
+    bool isVSyncInPhase(nsecs_t timePoint, int divider) const final EXCLUDES(mMutex);
+
+    void dump(std::string& result) const final EXCLUDES(mMutex);
 
 private:
     VSyncPredictor(VSyncPredictor const&) = delete;
@@ -76,13 +83,19 @@
     std::mutex mutable mMutex;
     size_t next(size_t i) const REQUIRES(mMutex);
     bool validate(nsecs_t timestamp) const REQUIRES(mMutex);
-    std::tuple<nsecs_t, nsecs_t> getVSyncPredictionModel(std::lock_guard<std::mutex> const&) const
-            REQUIRES(mMutex);
+
+    Model getVSyncPredictionModelLocked() const REQUIRES(mMutex);
+
+    nsecs_t nextAnticipatedVSyncTimeFromLocked(nsecs_t timePoint) const REQUIRES(mMutex);
 
     nsecs_t mIdealPeriod GUARDED_BY(mMutex);
     std::optional<nsecs_t> mKnownTimestamp GUARDED_BY(mMutex);
 
-    std::unordered_map<nsecs_t, std::tuple<nsecs_t, nsecs_t>> mutable mRateMap GUARDED_BY(mMutex);
+    // Map between ideal vsync period and the calculated model
+    std::unordered_map<nsecs_t, Model> mutable mRateMap GUARDED_BY(mMutex);
+
+    // Map between the divided vsync period and the last known vsync timestamp
+    std::unordered_map<nsecs_t, nsecs_t> mutable mRateDividerKnownTimestampMap GUARDED_BY(mMutex);
 
     size_t mLastTimestampIndex GUARDED_BY(mMutex) = 0;
     std::vector<nsecs_t> mTimestamps GUARDED_BY(mMutex);