drm_hwcomposer: Clean up VsyncWorker destruction

With VsyncWorker no longer acquiring the main lock, we can use
std::thread::join on the main thread to ensure that the vsync thread is
stopped cleanly in the VSyncWorker destructor.

- Don't pass a shared_ptr<> into VSyncWorker::ThreadFn to simplify
  lifetime management
- Change to unique_ptr to simplify lifetime management
- Remove the hack to destroy the HwcDisplays in two stages when
  destructing ComposerClient
- Add std::thread::join to VSyncWorker destructor

Change-Id: I25a34fd304c7b2ec48e43d538bf15794bdc9d68e
Signed-off-by: Drew Davenport <ddavenport@google.com>
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index ff8de47..60861af 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -301,8 +301,6 @@
   }
 
   if (vsync_worker_) {
-    // TODO: There should be a mechanism to wait for this worker to complete,
-    // otherwise there is a race condition while destructing the HwcDisplay.
     vsync_worker_->StopThread();
     vsync_worker_ = {};
   }
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index 5d593bb..acefff8 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -246,7 +246,7 @@
   std::unique_ptr<Backend> backend_;
   std::shared_ptr<FlatteningController> flatcon_;
 
-  std::shared_ptr<VSyncWorker> vsync_worker_;
+  std::unique_ptr<VSyncWorker> vsync_worker_;
   bool vsync_event_en_{};
 
   const hwc2_display_t handle_;