OSDN Git Service

drm_hwcomposer: Use single VSyncWorker per display
authorRoman Stratiienko <roman.o.stratiienko@globallogic.com>
Thu, 20 Jan 2022 09:50:54 +0000 (11:50 +0200)
committerRoman Stratiienko <roman.o.stratiienko@globallogic.com>
Fri, 4 Feb 2022 09:16:05 +0000 (11:16 +0200)
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>
hwc2_device/DrmHwcTwo.cpp
hwc2_device/DrmHwcTwo.h
hwc2_device/HwcDisplay.cpp
hwc2_device/HwcDisplay.h

index 2002b85..37901ee 100644 (file)
@@ -203,4 +203,21 @@ void DrmHwcTwo::SendHotplugEventToClient(hwc2_display_t displayid,
   }
 }
 
+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
index 83fbd79..5379cba 100644 (file)
@@ -64,6 +64,9 @@ class DrmHwcTwo : public PipelineToFrontendBindingInterface {
   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);
 
index 7ca4549..656aa94 100644 (file)
@@ -115,8 +115,6 @@ HwcDisplay::~HwcDisplay() {
   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 @@ void HwcDisplay::ClearDisplay() {
 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::SetPowerMode(int32_t mode_in) {
 }
 
 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 @@ std::vector<HwcLayer *> HwcDisplay::GetOrderLayersByZPos() {
   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 @@ HWC2::Error HwcDisplay::GetDisplayConnectionType(uint32_t *outType) {
   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 @@ void HwcDisplay::set_backend(std::unique_ptr<Backend> backend) {
   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
index 42b000a..5a5c98e 100644 (file)
@@ -83,7 +83,6 @@ class HwcDisplay {
 #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 @@ class HwcDisplay {
 
   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 @@ class HwcDisplay {
   }
 
   /* 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 @@ class HwcDisplay {
   };
 
   std::atomic_int flattenning_state_{ClientFlattenningState::NotRequired};
-  VSyncWorker flattening_vsync_worker_;
 
   constexpr static size_t MATRIX_SIZE = 16;
 
@@ -221,6 +202,8 @@ class HwcDisplay {
   std::unique_ptr<Backend> backend_;
 
   VSyncWorker vsync_worker_;
+  bool vsync_event_en_{};
+  bool vsync_flattening_en_{};
 
   const hwc2_display_t handle_;
   HWC2::DisplayType type_;