drm_hwcomposer: Support DisplayCommand.expectedPresentTime

DisplayCommand.expectedPresentTime indicates that the HWC should present
the composition as close to the desired time as possible. It may be that
the desired time is some number of vsync periods in the future.

A drm atomic commit will always present at the next vsync, and there is
no mechanism for userspace to indicate a desired present time.

Lacking a kernel uAPI to support this, an alternative is to sleep in
userspace until the next expected vsync aligns with the expected present
time.

Change-Id: Iad703eed9b0e459194f895339dd604990875f157
Signed-off-by: Drew Davenport <ddavenport@google.com>
diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
index 4dafb48..368d5eb 100644
--- a/hwc3/ComposerClient.cpp
+++ b/hwc3/ComposerClient.cpp
@@ -152,6 +152,14 @@
   return AidlToSampleRange(dataspace->dataspace);
 }
 
+std::optional<int64_t> AidlToPresentTimeNs(
+    const std::optional<ClockMonotonicTimestamp>& expected_present_time) {
+  if (!expected_present_time || expected_present_time->timestampNanos == 0) {
+    return std::nullopt;
+  }
+  return expected_present_time->timestampNanos;
+}
+
 bool IsSupportedCompositionType(
     const std::optional<ParcelableComposition> composition) {
   if (!composition) {
@@ -725,6 +733,8 @@
     cmd_result_writer_->AddChanges(changes);
     auto hwc3_display = DrmHwcThree::GetHwc3Display(*display);
     hwc3_display->must_validate = false;
+    hwc3_display->desired_present_time = AidlToPresentTimeNs(
+        command.expectedPresentTime);
 
     // TODO: DisplayRequests are not implemented.
   }
@@ -749,9 +759,12 @@
       cmd_result_writer_->AddError(hwc3::Error::kNotValidated);
       return;
     }
+
     ::android::SharedFd present_fence;
     std::vector<HwcDisplay::ReleaseFence> release_fences;
-    bool ret = display->PresentStagedComposition(present_fence, release_fences);
+    bool ret = display->PresentStagedComposition(hwc3_display
+                                                     ->desired_present_time,
+                                                 present_fence, release_fences);
 
     if (!ret) {
       cmd_result_writer_->AddError(hwc3::Error::kBadDisplay);