drm_hwcomposer: Set vsync callback on demand

Set and clear a vsync callback based on when the client requests vsync
events to be enabled or not. The new vsync callback does not need to
acquire the global resource lock.

The vsync callback uses the vsync period that was set in the VSyncWorker
rather than querying it from the HwcDisplay.

Change-Id: Ic7868af4963ad40aa5a0982a190c67f1642d5b32
Signed-off-by: Drew Davenport <ddavenport@google.com>
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 8d6b0a3..5dff79c 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -318,11 +318,6 @@
       .out_event =
           [this](int64_t timestamp) {
             const std::unique_lock lock(hwc_->GetResMan().GetMainLock());
-            if (vsync_event_en_) {
-              uint32_t period_ns{};
-              GetDisplayVsyncPeriod(&period_ns);
-              hwc_->SendVsyncEventToClient(handle_, timestamp, period_ns);
-            }
             if (!vsync_event_en_) {
               vsync_worker_->VSyncControl(false);
             }
@@ -1067,8 +1062,18 @@
   }
 
   vsync_event_en_ = HWC2_VSYNC_ENABLE == enabled;
+
   if (vsync_event_en_) {
+    DrmHwc *hwc = hwc_;
+    hwc2_display_t id = handle_;
+    // Callback will be called from the vsync thread.
+    auto callback = [hwc, id](int64_t timestamp, uint32_t period_ns) {
+      hwc->SendVsyncEventToClient(id, timestamp, period_ns);
+    };
+    vsync_worker_->SetTimestampCallback(callback);
     vsync_worker_->VSyncControl(true);
+  } else {
+    vsync_worker_->SetTimestampCallback(std::nullopt);
   }
   return HWC2::Error::None;
 }