Support repurposing idle timer to work with kernel timer.

Idle timer would instead enable/disable hw vsyncs in accordance with
inactivity.

Bug: 130684082
Test: systrace
Change-Id: I289600fc41b7ded863c9486cf6c2ab6155b06550
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 88d2638..b91c66e 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -73,6 +73,7 @@
     mEventControlThread = std::make_unique<impl::EventControlThread>(function);
 
     mSetIdleTimerMs = set_idle_timer_ms(0);
+    mSupportKernelTimer = support_kernel_idle_timer(false);
 
     char value[PROPERTY_VALUE_MAX];
     property_get("debug.sf.set_idle_timer_ms", value, "0");
@@ -82,10 +83,20 @@
     }
 
     if (mSetIdleTimerMs > 0) {
-        mIdleTimer =
-                std::make_unique<scheduler::IdleTimer>(std::chrono::milliseconds(mSetIdleTimerMs),
-                                                       [this] { resetTimerCallback(); },
-                                                       [this] { expiredTimerCallback(); });
+        if (mSupportKernelTimer) {
+            mIdleTimer =
+                    std::make_unique<scheduler::IdleTimer>(std::chrono::milliseconds(
+                                                                   mSetIdleTimerMs),
+                                                           [this] { resetKernelTimerCallback(); },
+                                                           [this] {
+                                                               expiredKernelTimerCallback();
+                                                           });
+        } else {
+            mIdleTimer = std::make_unique<scheduler::IdleTimer>(std::chrono::milliseconds(
+                                                                        mSetIdleTimerMs),
+                                                                [this] { resetTimerCallback(); },
+                                                                [this] { expiredTimerCallback(); });
+        }
         mIdleTimer->start();
     }
 }
@@ -344,6 +355,11 @@
     mChangeRefreshRateCallback = changeRefreshRateCallback;
 }
 
+void Scheduler::setGetVsyncPeriodCallback(const GetVsyncPeriod&& getVsyncPeriod) {
+    std::lock_guard<std::mutex> lock(mCallbackLock);
+    mGetVsyncPeriod = getVsyncPeriod;
+}
+
 void Scheduler::updateFrameSkipping(const int64_t skipCount) {
     ATRACE_INT("FrameSkipCount", skipCount);
     if (mSkipCount != skipCount) {
@@ -360,17 +376,30 @@
 }
 
 void Scheduler::resetTimerCallback() {
-    // We do not notify the applications about config changes when idle timer is reset.
     timerChangeRefreshRate(IdleTimerState::RESET);
     ATRACE_INT("ExpiredIdleTimer", 0);
 }
 
+void Scheduler::resetKernelTimerCallback() {
+    ATRACE_INT("ExpiredKernelIdleTimer", 0);
+    std::lock_guard<std::mutex> lock(mCallbackLock);
+    if (mGetVsyncPeriod) {
+        resyncToHardwareVsync(false, mGetVsyncPeriod());
+    }
+}
+
 void Scheduler::expiredTimerCallback() {
-    // We do not notify the applications about config changes when idle timer expires.
     timerChangeRefreshRate(IdleTimerState::EXPIRED);
     ATRACE_INT("ExpiredIdleTimer", 1);
 }
 
+void Scheduler::expiredKernelTimerCallback() {
+    ATRACE_INT("ExpiredKernelIdleTimer", 1);
+    // Disable HW Vsync if the timer expired, as we don't need it
+    // enabled if we're not pushing frames.
+    disableHardwareVsync(false);
+}
+
 std::string Scheduler::doDump() {
     std::ostringstream stream;
     stream << "+  Idle timer interval: " << mSetIdleTimerMs << " ms" << std::endl;