drm_hwcomposer: Use single VSyncWorker per display

Composer 2.4 will require another vsyncworker callback to send
VsyncPeriodTimingChanged event. It makes sence to use single
VSyncWorker and flags to indicate which actions are required
to perform. This should also save some runtime resources.

Signed-off-by: Roman Stratiienko <roman.o.stratiienko@globallogic.com>
diff --git a/hwc2_device/DrmHwcTwo.cpp b/hwc2_device/DrmHwcTwo.cpp
index 2002b85..37901ee 100644
--- a/hwc2_device/DrmHwcTwo.cpp
+++ b/hwc2_device/DrmHwcTwo.cpp
@@ -203,4 +203,21 @@
   }
 }
 
+void DrmHwcTwo::SendVsyncEventToClient(
+    hwc2_display_t displayid, int64_t timestamp,
+    [[maybe_unused]] uint32_t vsync_period) const {
+  /* vsync callback */
+#if PLATFORM_SDK_VERSION > 29
+  if (vsync_2_4_callback_.first != nullptr &&
+      vsync_2_4_callback_.second != nullptr) {
+    vsync_2_4_callback_.first(vsync_2_4_callback_.second, displayid, timestamp,
+                              vsync_period);
+  } else
+#endif
+      if (vsync_callback_.first != nullptr &&
+          vsync_callback_.second != nullptr) {
+    vsync_callback_.first(vsync_callback_.second, displayid, timestamp);
+  }
+}
+
 }  // namespace android
diff --git a/hwc2_device/DrmHwcTwo.h b/hwc2_device/DrmHwcTwo.h
index 83fbd79..5379cba 100644
--- a/hwc2_device/DrmHwcTwo.h
+++ b/hwc2_device/DrmHwcTwo.h
@@ -64,6 +64,9 @@
   bool UnbindDisplay(DrmDisplayPipeline *pipeline) override;
   void FinalizeDisplayBinding() override;
 
+  void SendVsyncEventToClient(hwc2_display_t displayid, int64_t timestamp,
+                              uint32_t vsync_period) const;
+
  private:
   void SendHotplugEventToClient(hwc2_display_t displayid, bool connected);
 
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 7ca4549..656aa94 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -115,8 +115,6 @@
   auto &main_lock = hwc2_->GetResMan().GetMainLock();
   /* Unlock to allow pending vsync callbacks to finish */
   main_lock.unlock();
-  flattening_vsync_worker_.VSyncControl(false);
-  flattening_vsync_worker_.Exit();
   vsync_worker_.VSyncControl(false);
   vsync_worker_.Exit();
   main_lock.lock();
@@ -135,37 +133,16 @@
 HWC2::Error HwcDisplay::Init() {
   int ret = vsync_worker_.Init(pipeline_, [this](int64_t timestamp) {
     const std::lock_guard<std::mutex> lock(hwc2_->GetResMan().GetMainLock());
-    /* vsync callback */
-#if PLATFORM_SDK_VERSION > 29
-    if (hwc2_->vsync_2_4_callback_.first != nullptr &&
-        hwc2_->vsync_2_4_callback_.second != nullptr) {
-      hwc2_vsync_period_t period_ns{};
+    if (vsync_event_en_) {
+      uint32_t period_ns{};
       GetDisplayVsyncPeriod(&period_ns);
-      hwc2_->vsync_2_4_callback_.first(hwc2_->vsync_2_4_callback_.second,
-                                       handle_, timestamp, period_ns);
-    } else
-#endif
-        if (hwc2_->vsync_callback_.first != nullptr &&
-            hwc2_->vsync_callback_.second != nullptr) {
-      hwc2_->vsync_callback_.first(hwc2_->vsync_callback_.second, handle_,
-                                   timestamp);
+      hwc2_->SendVsyncEventToClient(handle_, timestamp, period_ns);
     }
-  });
-  if (ret) {
-    ALOGE("Failed to create event worker for d=%d %d\n", int(handle_), ret);
-    return HWC2::Error::BadDisplay;
-  }
-
-  ret = flattening_vsync_worker_.Init(pipeline_, [this](int64_t /*timestamp*/) {
-    const std::lock_guard<std::mutex> lock(hwc2_->GetResMan().GetMainLock());
-    /* Frontend flattening */
-    if (flattenning_state_ > ClientFlattenningState::ClientRefreshRequested &&
-        --flattenning_state_ ==
-            ClientFlattenningState::ClientRefreshRequested &&
-        hwc2_->refresh_callback_.first != nullptr &&
-        hwc2_->refresh_callback_.second != nullptr) {
-      hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second, handle_);
-      flattening_vsync_worker_.VSyncControl(false);
+    if (vsync_flattening_en_) {
+      ProcessFlatenningVsyncInternal();
+    }
+    if (!vsync_event_en_ && !vsync_flattening_en_) {
+      vsync_worker_.VSyncControl(false);
     }
   });
   if (ret) {
@@ -700,7 +677,10 @@
 }
 
 HWC2::Error HwcDisplay::SetVsyncEnabled(int32_t enabled) {
-  vsync_worker_.VSyncControl(HWC2_VSYNC_ENABLE == enabled);
+  vsync_event_en_ = HWC2_VSYNC_ENABLE == enabled;
+  if (vsync_event_en_) {
+    vsync_worker_.VSyncControl(true);
+  }
   return HWC2::Error::None;
 }
 
@@ -729,6 +709,13 @@
   return ordered_layers;
 }
 
+HWC2::Error HwcDisplay::GetDisplayVsyncPeriod(
+    uint32_t *outVsyncPeriod /* ns */) {
+  return GetDisplayAttribute(configs_.active_config_id,
+                             HWC2_ATTRIBUTE_VSYNC_PERIOD,
+                             (int32_t *)(outVsyncPeriod));
+}
+
 #if PLATFORM_SDK_VERSION > 29
 HWC2::Error HwcDisplay::GetDisplayConnectionType(uint32_t *outType) {
   if (IsInHeadlessMode()) {
@@ -748,13 +735,6 @@
   return HWC2::Error::None;
 }
 
-HWC2::Error HwcDisplay::GetDisplayVsyncPeriod(
-    hwc2_vsync_period_t *outVsyncPeriod /* ns */) {
-  return GetDisplayAttribute(configs_.active_config_id,
-                             HWC2_ATTRIBUTE_VSYNC_PERIOD,
-                             (int32_t *)(outVsyncPeriod));
-}
-
 HWC2::Error HwcDisplay::SetActiveConfigWithConstraints(
     hwc2_config_t /*config*/,
     hwc_vsync_period_change_constraints_t *vsyncPeriodChangeConstraints,
@@ -887,4 +867,37 @@
   backend_ = std::move(backend);
 }
 
+/* returns true if composition should be sent to client */
+bool HwcDisplay::ProcessClientFlatteningState(bool skip) {
+  int flattenning_state = flattenning_state_;
+  if (flattenning_state == ClientFlattenningState::Disabled) {
+    return false;
+  }
+
+  if (skip) {
+    flattenning_state_ = ClientFlattenningState::NotRequired;
+    return false;
+  }
+
+  if (flattenning_state == ClientFlattenningState::ClientRefreshRequested) {
+    flattenning_state_ = ClientFlattenningState::Flattened;
+    return true;
+  }
+
+  vsync_flattening_en_ = true;
+  vsync_worker_.VSyncControl(true);
+  flattenning_state_ = ClientFlattenningState::VsyncCountdownMax;
+  return false;
+}
+
+void HwcDisplay::ProcessFlatenningVsyncInternal() {
+  if (flattenning_state_ > ClientFlattenningState::ClientRefreshRequested &&
+      --flattenning_state_ == ClientFlattenningState::ClientRefreshRequested &&
+      hwc2_->refresh_callback_.first != nullptr &&
+      hwc2_->refresh_callback_.second != nullptr) {
+    hwc2_->refresh_callback_.first(hwc2_->refresh_callback_.second, handle_);
+    vsync_flattening_en_ = false;
+  }
+}
+
 }  // namespace android
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index 42b000a..5a5c98e 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -83,7 +83,6 @@
 #endif
 #if PLATFORM_SDK_VERSION > 29
   HWC2::Error GetDisplayConnectionType(uint32_t *outType);
-  HWC2::Error GetDisplayVsyncPeriod(hwc2_vsync_period_t *outVsyncPeriod);
 
   HWC2::Error SetActiveConfigWithConstraints(
       hwc2_config_t config,
@@ -96,6 +95,7 @@
 
   HWC2::Error SetContentType(int32_t contentType);
 #endif
+  HWC2::Error GetDisplayVsyncPeriod(uint32_t *outVsyncPeriod);
 
   HWC2::Error GetDozeSupport(int32_t *support);
   HWC2::Error GetHdrCapabilities(uint32_t *num_types, int32_t *types,
@@ -165,26 +165,8 @@
   }
 
   /* returns true if composition should be sent to client */
-  bool ProcessClientFlatteningState(bool skip) {
-    int flattenning_state = flattenning_state_;
-    if (flattenning_state == ClientFlattenningState::Disabled) {
-      return false;
-    }
-
-    if (skip) {
-      flattenning_state_ = ClientFlattenningState::NotRequired;
-      return false;
-    }
-
-    if (flattenning_state == ClientFlattenningState::ClientRefreshRequested) {
-      flattenning_state_ = ClientFlattenningState::Flattened;
-      return true;
-    }
-
-    flattening_vsync_worker_.VSyncControl(true);
-    flattenning_state_ = ClientFlattenningState::VsyncCountdownMax;
-    return false;
-  }
+  bool ProcessClientFlatteningState(bool skip);
+  void ProcessFlatenningVsyncInternal();
 
   /* Headless mode required to keep SurfaceFlinger alive when all display are
    * disconnected, Without headless mode Android will continuously crash.
@@ -206,7 +188,6 @@
   };
 
   std::atomic_int flattenning_state_{ClientFlattenningState::NotRequired};
-  VSyncWorker flattening_vsync_worker_;
 
   constexpr static size_t MATRIX_SIZE = 16;
 
@@ -221,6 +202,8 @@
   std::unique_ptr<Backend> backend_;
 
   VSyncWorker vsync_worker_;
+  bool vsync_event_en_{};
+  bool vsync_flattening_en_{};
 
   const hwc2_display_t handle_;
   HWC2::DisplayType type_;