sdm: Add support for vsync enable/disable

Add support for enabling/disabling vsync events. Deprecate
SetVSyncState() API on HWDevice and add a new API
SetEventState() on HWEvents.

Change-Id: I9d08accde3e528f9b0a15dc85345cc801dd6bc17
CRs-fixed: 1114808
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 3953ce2..da19398 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -986,10 +986,14 @@
   DisplayError error = kErrorNone;
   if (vsync_enable_ != enable) {
     error = hw_intf_->SetVSyncState(enable);
+    if (error == kErrorNotSupported) {
+      error = hw_events_intf_->SetEventState(HWEvent::VSYNC, enable);
+    }
     if (error == kErrorNone) {
       vsync_enable_ = enable;
     }
   }
+
   return error;
 }
 
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 8052613..e866cd0 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -878,7 +878,7 @@
 }
 
 DisplayError HWDeviceDRM::SetVSyncState(bool enable) {
-  return kErrorNone;
+  return kErrorNotSupported;
 }
 
 void HWDeviceDRM::SetIdleTimeoutMs(uint32_t timeout_ms) {}
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index cc2ae7b..47ceb39 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -75,6 +75,7 @@
   virtual DisplayError Flush();
   virtual DisplayError GetPPFeaturesVersion(PPFeatureVersion *vers);
   virtual DisplayError SetPPFeatures(PPFeaturesConfig *feature_list);
+  // This API is no longer supported, expectation is to call the correct API on HWEvents
   virtual DisplayError SetVSyncState(bool enable);
   virtual void SetIdleTimeoutMs(uint32_t timeout_ms);
   virtual DisplayError SetDisplayMode(const HWDisplayMode hw_display_mode);
diff --git a/sdm/libs/core/drm/hw_events_drm.cpp b/sdm/libs/core/drm/hw_events_drm.cpp
index 09293a9..cea76fc 100644
--- a/sdm/libs/core/drm/hw_events_drm.cpp
+++ b/sdm/libs/core/drm/hw_events_drm.cpp
@@ -160,7 +160,30 @@
 DisplayError HWEventsDRM::Deinit() {
   exit_threads_ = true;
   Sys::pthread_cancel_(event_thread_);
+  WakeUpEventThread();
+  pthread_join(event_thread_, NULL);
+  CloseFds();
 
+  return kErrorNone;
+}
+
+DisplayError HWEventsDRM::SetEventState(HWEvent event, bool enable, void *arg) {
+  switch (event) {
+    case HWEvent::VSYNC:
+      vsync_enabled_ = enable;
+      if (enable) {
+        WakeUpEventThread();
+      }
+      break;
+    default:
+      DLOGE("Event not supported");
+      return kErrorNotSupported;
+  }
+
+  return kErrorNone;
+}
+
+void HWEventsDRM::WakeUpEventThread() {
   for (uint32_t i = 0; i < event_data_list_.size(); i++) {
     if (event_data_list_[i].event_type == HWEvent::EXIT) {
       uint64_t exit_value = 1;
@@ -169,13 +192,9 @@
         DLOGW("Error triggering exit fd (%d). write size = %d, error = %s", poll_fds_[i].fd,
               write_size, strerror(errno));
       }
+      break;
     }
   }
-
-  pthread_join(event_thread_, NULL);
-  CloseFds();
-
-  return kErrorNone;
 }
 
 DisplayError HWEventsDRM::CloseFds() {
@@ -217,7 +236,7 @@
   setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent);
 
   while (!exit_threads_) {
-    if (RegisterVSync() != kErrorNone) {
+    if (vsync_enabled_ && RegisterVSync() != kErrorNone) {
       pthread_exit(0);
       return nullptr;
     }
diff --git a/sdm/libs/core/drm/hw_events_drm.h b/sdm/libs/core/drm/hw_events_drm.h
index 8703321..41050c7 100644
--- a/sdm/libs/core/drm/hw_events_drm.h
+++ b/sdm/libs/core/drm/hw_events_drm.h
@@ -48,6 +48,7 @@
   virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
                             const vector<HWEvent> &event_list);
   virtual DisplayError Deinit();
+  virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr);
 
  private:
   static const int kMaxStringLength = 1024;
@@ -72,6 +73,7 @@
   void HandleBlank(char *data) {}
   void HandleIdlePowerCollapse(char *data);
   void PopulateHWEventData(const vector<HWEvent> &event_list);
+  void WakeUpEventThread();
   DisplayError SetEventParser();
   DisplayError InitializePollFd();
   DisplayError CloseFds();
@@ -84,6 +86,7 @@
   std::string event_thread_name_ = "SDM_EventThread";
   bool exit_threads_ = false;
   uint32_t vsync_index_ = 0;
+  bool vsync_enabled_ = true;
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/fb/hw_events.h b/sdm/libs/core/fb/hw_events.h
index 347495f..3d9cec8 100644
--- a/sdm/libs/core/fb/hw_events.h
+++ b/sdm/libs/core/fb/hw_events.h
@@ -44,6 +44,9 @@
   virtual DisplayError Init(int fb_num, HWEventHandler *event_handler,
                             const vector<HWEvent> &event_list);
   virtual DisplayError Deinit();
+  virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) {
+    return kErrorNotSupported;
+  }
 
  private:
   static const int kMaxStringLength = 1024;
diff --git a/sdm/libs/core/hw_events_interface.h b/sdm/libs/core/hw_events_interface.h
index e6a714c..482e077 100644
--- a/sdm/libs/core/hw_events_interface.h
+++ b/sdm/libs/core/hw_events_interface.h
@@ -49,6 +49,7 @@
   virtual DisplayError Init(int display_type, HWEventHandler *event_handler,
                             const std::vector<HWEvent> &event_list) = 0;
   virtual DisplayError Deinit() = 0;
+  virtual DisplayError SetEventState(HWEvent event, bool enable, void *aux = nullptr) = 0;
 
   static DisplayError Create(int display_type, HWEventHandler *event_handler,
                              const std::vector<HWEvent> &event_list, HWEventsInterface **intf);