drm_hwcomposer: Fix missing present and release fence handling

- Use wrappers instead of exposed raw fd in the HwcDisplay API.
- Add fences to the HWC3 command stream.

Fixes: b864ccf845e5 ("drm_hwcomposer: Remove HWC2 usage for Present")
Change-Id: Iadfa39d9b3f58d1e542a1738f27809155fdbf3f6
Signed-off-by: Roman Stratiienko <r.stratiienko@gmail.com>
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index ad5d177..a0c200e 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -408,20 +408,26 @@
 }
 
 auto HwcDisplay::PresentStagedComposition(
-    int32_t *out_present_fence, std::vector<ReleaseFence> *out_release_fences)
-    -> HWC2::Error {
-  auto error = PresentDisplay(out_present_fence);
-  if (error != HWC2::Error::None || *out_present_fence == -1) {
-    return error;
+    SharedFd &out_present_fence, std::vector<ReleaseFence> &out_release_fences)
+    -> bool {
+  int out_fd = -1;
+  auto error = PresentDisplay(&out_fd);
+  out_present_fence = MakeSharedFd(out_fd);
+  if (error != HWC2::Error::None) {
+    return false;
+  }
+
+  if (!out_present_fence) {
+    return true;
   }
 
   for (auto &l : layers_) {
-    if (!l.second.GetPriorBufferScanOutFlag() || !present_fence_) {
-      continue;
+    if (l.second.GetPriorBufferScanOutFlag()) {
+      out_release_fences.emplace_back(l.first, out_present_fence);
     }
-    out_release_fences->emplace_back(l.first, DupFd(present_fence_));
   }
-  return error;
+
+  return true;
 }
 
 void HwcDisplay::SetPipeline(std::shared_ptr<DrmDisplayPipeline> pipeline) {
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index 8dc059c..ad58ae8 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -101,10 +101,10 @@
   // Present previously staged properties, and return fences to indicate when
   // the new content has been presented, and when the previous buffers have
   // been released.
-  using ReleaseFence = std::pair<hwc2_layer_t, int32_t>;
-  auto PresentStagedComposition(int32_t *out_present_fence,
-                                std::vector<ReleaseFence> *out_release_fences)
-      -> HWC2::Error;
+  using ReleaseFence = std::pair<hwc2_layer_t, SharedFd>;
+  auto PresentStagedComposition(SharedFd &out_present_fence,
+                                std::vector<ReleaseFence> &out_release_fences)
+      -> bool;
 
   // HWC2 Hooks - these should not be used outside of the hwc2 device.
   HWC2::Error AcceptDisplayChanges();
diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
index f067147..04beb3a 100644
--- a/hwc3/ComposerClient.cpp
+++ b/hwc3/ComposerClient.cpp
@@ -593,14 +593,25 @@
       cmd_result_writer_->AddError(hwc3::Error::kNotValidated);
       return;
     }
-    int32_t present_fence = -1;
+    ::android::SharedFd present_fence;
     std::vector<HwcDisplay::ReleaseFence> release_fences;
-    error = Hwc2toHwc3Error(
-        display->PresentStagedComposition(&present_fence, &release_fences));
-    if (error != hwc3::Error::kNone) {
-      cmd_result_writer_->AddError(error);
+    bool ret = display->PresentStagedComposition(present_fence, release_fences);
+
+    if (!ret) {
+      cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);
       return;
     }
+
+    using ::android::base::unique_fd;
+    cmd_result_writer_->AddPresentFence(  //
+        display_id, unique_fd(::android::DupFd(present_fence)));
+
+    std::unordered_map<int64_t, unique_fd> hal_release_fences;
+    for (const auto& [layer_id, release_fence] : release_fences) {
+      hal_release_fences[Hwc2LayerToHwc3(layer_id)] =  //
+          unique_fd(::android::DupFd(release_fence));
+    }
+    cmd_result_writer_->AddReleaseFence(display_id, hal_release_fences);
   }
 }