Respect libdrm vsyncs am: 377ff8cf97

Original change: https://android-review.googlesource.com/c/device/generic/goldfish-opengl/+/1959651

Change-Id: I7de1bf21a1a52506c3376e724bf6154771872593
diff --git a/system/hwc2/Composer.h b/system/hwc2/Composer.h
index a0bdb82..0c47eab 100644
--- a/system/hwc2/Composer.h
+++ b/system/hwc2/Composer.h
@@ -38,7 +38,7 @@
       uint32_t /*height*/, uint32_t /*dpiX*/, uint32_t /*dpiY*/,
       uint32_t /*refreshRate*/)>;
 
-  virtual HWC2::Error init(const HotplugCallback& cb) = 0;
+  virtual HWC2::Error init() = 0;
 
   virtual HWC2::Error onDisplayCreate(Display* display) = 0;
 
diff --git a/system/hwc2/Device.cpp b/system/hwc2/Device.cpp
index eaf8bba..b427f60 100644
--- a/system/hwc2/Device.cpp
+++ b/system/hwc2/Device.cpp
@@ -25,6 +25,21 @@
 namespace android {
 namespace {
 
+static bool isMinigbmFromProperty() {
+  static constexpr const auto kGrallocProp = "ro.hardware.gralloc";
+
+  const auto grallocProp = android::base::GetProperty(kGrallocProp, "");
+  DEBUG_LOG("%s: prop value is: %s", __FUNCTION__, grallocProp.c_str());
+
+  if (grallocProp == "minigbm") {
+    ALOGD("%s: Using minigbm, in minigbm mode.\n", __FUNCTION__);
+    return true;
+  } else {
+    ALOGD("%s: Is not using minigbm, in goldfish mode.\n", __FUNCTION__);
+    return false;
+  }
+}
+
 template <typename PFN, typename T>
 static hwc2_function_pointer_t asFP(T function) {
   static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
@@ -51,22 +66,33 @@
   common.close = CloseHook;
   hwc2_device_t::getCapabilities = getCapabilitiesHook;
   hwc2_device_t::getFunction = getFunctionHook;
+
+  mDrmPresenter = std::make_unique<DrmPresenter>();
 }
 
 HWC2::Error Device::init() {
   DEBUG_LOG("%s", __FUNCTION__);
-
+  bool isMinigbm = isMinigbmFromProperty();
   if (ShouldUseGuestComposer()) {
-    mComposer = std::make_unique<GuestComposer>();
+    mComposer = std::make_unique<GuestComposer>(mDrmPresenter.get());
   } else {
-    mComposer = std::make_unique<HostComposer>();
+    mComposer = std::make_unique<HostComposer>(mDrmPresenter.get(), isMinigbm);
   }
 
-  HWC2::Error error = mComposer->init(
-      [this](bool connected, uint32_t id, uint32_t width, uint32_t height,
-             uint32_t dpiX, uint32_t dpiY, uint32_t refreshRate) {
-        handleHotplug(connected, id, width, height, dpiX, dpiY, refreshRate);
-      });
+  if (ShouldUseGuestComposer() || isMinigbm) {
+      bool success = mDrmPresenter->init(
+        [this](bool connected, uint32_t id, uint32_t width, uint32_t height,
+           uint32_t dpiX, uint32_t dpiY, uint32_t refreshRate) {
+      handleHotplug(connected, id, width, height, dpiX, dpiY, refreshRate);
+    });
+
+    if (!success) {
+      ALOGE("%s: failed to initialize DrmPresenter", __FUNCTION__);
+      return HWC2::Error::NoResources;
+    }
+  }
+
+  HWC2::Error error = mComposer->init();
 
   if (error != HWC2::Error::None) {
     ALOGE("%s failed to initialize Composer", __FUNCTION__);
@@ -99,7 +125,7 @@
 
   std::vector<DisplayMultiConfigs> displays;
 
-  HWC2::Error error = findDisplays(displays);
+  HWC2::Error error = findDisplays(mDrmPresenter.get(), displays);
   if (error != HWC2::Error::None) {
     ALOGE("%s failed to find display configs", __FUNCTION__);
     return error;
diff --git a/system/hwc2/Device.h b/system/hwc2/Device.h
index 812d5e9..7361d3a 100644
--- a/system/hwc2/Device.h
+++ b/system/hwc2/Device.h
@@ -29,6 +29,7 @@
 #include "Common.h"
 #include "Composer.h"
 #include "Display.h"
+#include "DrmPresenter.h"
 #include "Layer.h"
 
 namespace android {
@@ -144,8 +145,9 @@
     hwc2_function_pointer_t pointer;
   };
   std::unordered_map<HWC2::Callback, CallbackInfo> mCallbacks;
-
   std::map<hwc2_display_t, std::unique_ptr<Display>> mDisplays;
+
+  std::unique_ptr<DrmPresenter> mDrmPresenter;
 };
 
 }  // namespace android
diff --git a/system/hwc2/DisplayConfig.h b/system/hwc2/DisplayConfig.h
index 67e4c49..02d9b77 100644
--- a/system/hwc2/DisplayConfig.h
+++ b/system/hwc2/DisplayConfig.h
@@ -84,4 +84,4 @@
   int32_t mConfigGroup;
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/system/hwc2/DisplayFinder.cpp b/system/hwc2/DisplayFinder.cpp
index df8f0fd..5fb192b 100644
--- a/system/hwc2/DisplayFinder.cpp
+++ b/system/hwc2/DisplayFinder.cpp
@@ -31,6 +31,30 @@
   return 1000 * 1000 * 1000 / hertz;
 }
 
+static int getVsyncHzFromProperty() {
+  static constexpr const auto kVsyncProp = "ro.boot.qemu.vsync";
+
+  const auto vsyncProp = android::base::GetProperty(kVsyncProp, "");
+  DEBUG_LOG("%s: prop value is: %s", __FUNCTION__, vsyncProp.c_str());
+
+  uint64_t vsyncPeriod;
+  if (!android::base::ParseUint(vsyncProp, &vsyncPeriod)) {
+    ALOGE("%s: failed to parse vsync period '%s', returning default 60",
+          __FUNCTION__, vsyncProp.c_str());
+    return 60;
+  }
+
+  return static_cast<int>(vsyncPeriod);
+}
+
+int32_t getVsyncForDisplay(DrmPresenter* drmPresenter,
+                           uint32_t displayId) {
+    const int32_t vsyncPeriodForDisplay = drmPresenter->refreshRate(displayId);
+    return vsyncPeriodForDisplay < 0 ?
+            HertzToPeriodNanos(getVsyncHzFromProperty()) :
+            HertzToPeriodNanos(vsyncPeriodForDisplay);
+}
+
 HWC2::Error findCuttlefishDisplays(std::vector<DisplayMultiConfigs>& displays) {
   DEBUG_LOG("%s", __FUNCTION__);
 
@@ -39,6 +63,8 @@
 
   hwc2_display_t displayId = 0;
   for (const auto& deviceDisplayConfig : deviceConfig.display_config()) {
+    // crosvm does not fully support EDID yet, so we solely rely on the
+    // device config for our vsync.
     const auto vsyncPeriodNanos =
         HertzToPeriodNanos(deviceDisplayConfig.refresh_rate_hz());
 
@@ -62,29 +88,13 @@
   return HWC2::Error::None;
 }
 
-static int getVsyncHzFromProperty() {
-  static constexpr const auto kVsyncProp = "ro.boot.qemu.vsync";
-
-  const auto vsyncProp = android::base::GetProperty(kVsyncProp, "");
-  DEBUG_LOG("%s: prop value is: %s", __FUNCTION__, vsyncProp.c_str());
-
-  uint64_t vsyncPeriod;
-  if (!android::base::ParseUint(vsyncProp, &vsyncPeriod)) {
-    ALOGE("%s: failed to parse vsync period '%s', returning default 60",
-          __FUNCTION__, vsyncProp.c_str());
-    return 60;
-  }
-
-  return static_cast<int>(vsyncPeriod);
-}
-
 HWC2::Error findGoldfishPrimaryDisplay(
+    DrmPresenter* drmPresenter,
     std::vector<DisplayMultiConfigs>& displays) {
   DEBUG_LOG("%s", __FUNCTION__);
 
   DEFINE_AND_VALIDATE_HOST_CONNECTION
   hostCon->lock();
-  const int32_t vsyncPeriodNanos = HertzToPeriodNanos(getVsyncHzFromProperty());
   DisplayMultiConfigs display;
   display.displayId = 0;
   if (rcEnc->hasHWCMultiConfigs()) {
@@ -102,7 +112,7 @@
           rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_HEIGHT),  //
           rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_XDPI),    //
           rcEnc->rcGetFBDisplayConfigsParam(rcEnc, configId, FB_YDPI),    //
-          vsyncPeriodNanos                                                //
+          getVsyncForDisplay(drmPresenter, configId)                      //
           ));
     }
   } else {
@@ -113,7 +123,7 @@
         rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT),  //
         rcEnc->rcGetFBParam(rcEnc, FB_XDPI),    //
         rcEnc->rcGetFBParam(rcEnc, FB_YDPI),    //
-        vsyncPeriodNanos                        //
+        getVsyncForDisplay(drmPresenter, 0)     //
         ));
   }
   hostCon->unlock();
@@ -179,8 +189,9 @@
   return HWC2::Error::None;
 }
 
-HWC2::Error findGoldfishDisplays(std::vector<DisplayMultiConfigs>& displays) {
-  HWC2::Error error = findGoldfishPrimaryDisplay(displays);
+HWC2::Error findGoldfishDisplays(DrmPresenter* drmPresenter,
+                                 std::vector<DisplayMultiConfigs>& displays) {
+  HWC2::Error error = findGoldfishPrimaryDisplay(drmPresenter, displays);
   if (error != HWC2::Error::None) {
     ALOGE("%s failed to find Goldfish primary display", __FUNCTION__);
     return error;
@@ -196,12 +207,13 @@
 
 }  // namespace
 
-HWC2::Error findDisplays(std::vector<DisplayMultiConfigs>& displays) {
+HWC2::Error findDisplays(DrmPresenter* drmPresenter,
+                         std::vector<DisplayMultiConfigs>& displays) {
   HWC2::Error error = HWC2::Error::None;
   if (IsCuttlefish()) {
     error = findCuttlefishDisplays(displays);
   } else {
-    error = findGoldfishDisplays(displays);
+    error = findGoldfishDisplays(drmPresenter, displays);
   }
 
   if (error != HWC2::Error::None) {
diff --git a/system/hwc2/DisplayFinder.h b/system/hwc2/DisplayFinder.h
index b9e1b19..5f22172 100644
--- a/system/hwc2/DisplayFinder.h
+++ b/system/hwc2/DisplayFinder.h
@@ -21,6 +21,7 @@
 
 #include "Common.h"
 #include "DisplayConfig.h"
+#include "DrmPresenter.h"
 
 namespace android {
 
@@ -31,7 +32,8 @@
   std::vector<DisplayConfig> configs;
 };
 
-HWC2::Error findDisplays(std::vector<DisplayMultiConfigs>& displays);
+HWC2::Error findDisplays(DrmPresenter* drmPresenter,
+                         std::vector<DisplayMultiConfigs>& displays);
 
 }  // namespace android
 
diff --git a/system/hwc2/DrmPresenter.cpp b/system/hwc2/DrmPresenter.cpp
index f1cbe48..b805749 100644
--- a/system/hwc2/DrmPresenter.cpp
+++ b/system/hwc2/DrmPresenter.cpp
@@ -530,14 +530,15 @@
   return edid;
 }
 
-DrmBuffer::DrmBuffer(const native_handle_t* handle, DrmPresenter& DrmPresenter)
-    : mDrmPresenter(DrmPresenter), mBo({}) {
+DrmBuffer::DrmBuffer(const native_handle_t* handle,
+                     DrmPresenter* drmPresenter)
+    : mDrmPresenter(drmPresenter), mBo({}) {
   if (!convertBoInfo(handle)) {
-    mDrmPresenter.getDrmFB(mBo);
+    mDrmPresenter->getDrmFB(mBo);
   }
 }
 
-DrmBuffer::~DrmBuffer() { mDrmPresenter.clearDrmFB(mBo); }
+DrmBuffer::~DrmBuffer() { mDrmPresenter->clearDrmFB(mBo); }
 
 int DrmBuffer::convertBoInfo(const native_handle_t* handle) {
   cros_gralloc_handle* gr_handle = (cros_gralloc_handle*)handle;
@@ -557,7 +558,7 @@
 
 std::tuple<HWC2::Error, base::unique_fd> DrmBuffer::flushToDisplay(
     int display, base::borrowed_fd inWaitSyncFd) {
-  return mDrmPresenter.flushToDisplay(display, mBo, inWaitSyncFd);
+  return mDrmPresenter->flushToDisplay(display, mBo, inWaitSyncFd);
 }
 
 DrmPresenter::DrmEventListener::DrmEventListener(DrmPresenter& presenter)
diff --git a/system/hwc2/DrmPresenter.h b/system/hwc2/DrmPresenter.h
index aec71eb..fdf06b7 100644
--- a/system/hwc2/DrmPresenter.h
+++ b/system/hwc2/DrmPresenter.h
@@ -40,7 +40,8 @@
 // A RAII object that will clear a drm framebuffer upon destruction.
 class DrmBuffer {
  public:
-  DrmBuffer(const native_handle_t* handle, DrmPresenter& drmPresenter);
+  DrmBuffer(const native_handle_t* handle,
+            DrmPresenter* drmPresenter);
   ~DrmBuffer();
 
   DrmBuffer(const DrmBuffer&) = delete;
@@ -55,7 +56,7 @@
  private:
   int convertBoInfo(const native_handle_t* handle);
 
-  DrmPresenter& mDrmPresenter;
+  DrmPresenter* mDrmPresenter;
   hwc_drm_bo_t mBo;
 };
 
@@ -77,7 +78,13 @@
 
   bool init(const HotplugCallback& cb);
 
-  uint32_t refreshRate() const { return mConnectors[0].mRefreshRateAsInteger; }
+  uint32_t refreshRate(uint32_t display) const {
+      if (display < mConnectors.size()) {
+          return mConnectors[display].mRefreshRateAsInteger;
+      }
+
+      return -1;
+  }
 
   std::tuple<HWC2::Error, base::unique_fd> flushToDisplay(
       int display, hwc_drm_bo_t& fb, base::borrowed_fd inWaitSyncFd);
diff --git a/system/hwc2/GuestComposer.cpp b/system/hwc2/GuestComposer.cpp
index f1bdfe6..1bfaaea 100644
--- a/system/hwc2/GuestComposer.cpp
+++ b/system/hwc2/GuestComposer.cpp
@@ -398,14 +398,11 @@
 
 }  // namespace
 
-HWC2::Error GuestComposer::init(const HotplugCallback& cb) {
+GuestComposer::GuestComposer(DrmPresenter* drmPresenter) :
+        mDrmPresenter(drmPresenter) {}
+
+HWC2::Error GuestComposer::init() {
   DEBUG_LOG("%s", __FUNCTION__);
-
-  if (!mDrmPresenter.init(cb)) {
-    ALOGE("%s: failed to initialize DrmPresenter", __FUNCTION__);
-    return HWC2::Error::NoResources;
-  }
-
   return HWC2::Error::None;
 }
 
diff --git a/system/hwc2/GuestComposer.h b/system/hwc2/GuestComposer.h
index bf2084f..a7a8be7 100644
--- a/system/hwc2/GuestComposer.h
+++ b/system/hwc2/GuestComposer.h
@@ -28,7 +28,7 @@
 
 class GuestComposer : public Composer {
  public:
-  GuestComposer() = default;
+  GuestComposer(DrmPresenter* drmPresenter);
 
   GuestComposer(const GuestComposer&) = delete;
   GuestComposer& operator=(const GuestComposer&) = delete;
@@ -36,7 +36,7 @@
   GuestComposer(GuestComposer&&) = delete;
   GuestComposer& operator=(GuestComposer&&) = delete;
 
-  HWC2::Error init(const HotplugCallback& cb) override;
+  HWC2::Error init() override;
 
   HWC2::Error onDisplayCreate(Display*) override;
 
@@ -97,7 +97,7 @@
 
   Gralloc mGralloc;
 
-  DrmPresenter mDrmPresenter;
+  DrmPresenter* mDrmPresenter;
 
   // Cuttlefish on QEMU does not have a display. Disable presenting to avoid
   // spamming logcat with DRM commit failures.
diff --git a/system/hwc2/HostComposer.cpp b/system/hwc2/HostComposer.cpp
index fd9021c..73d717d 100644
--- a/system/hwc2/HostComposer.cpp
+++ b/system/hwc2/HostComposer.cpp
@@ -40,21 +40,6 @@
 namespace android {
 namespace {
 
-static bool isMinigbmFromProperty() {
-  static constexpr const auto kGrallocProp = "ro.hardware.gralloc";
-
-  const auto grallocProp = android::base::GetProperty(kGrallocProp, "");
-  DEBUG_LOG("%s: prop value is: %s", __FUNCTION__, grallocProp.c_str());
-
-  if (grallocProp == "minigbm") {
-    ALOGD("%s: Using minigbm, in minigbm mode.\n", __FUNCTION__);
-    return true;
-  } else {
-    ALOGD("%s: Is not using minigbm, in goldfish mode.\n", __FUNCTION__);
-    return false;
-  }
-}
-
 typedef struct compose_layer {
   uint32_t cbHandle;
   hwc2_composition_t composeMode;
@@ -139,15 +124,13 @@
 
 }  // namespace
 
-HWC2::Error HostComposer::init(const HotplugCallback& cb) {
-  mIsMinigbm = isMinigbmFromProperty();
+HostComposer::HostComposer(DrmPresenter* drmPresenter,
+                           bool isMinigbm) :
+        mDrmPresenter(drmPresenter),
+        mIsMinigbm(isMinigbm) {}
 
-  if (mIsMinigbm) {
-    if (!mDrmPresenter.init(cb)) {
-      ALOGE("%s: failed to initialize DrmPresenter", __FUNCTION__);
-      return HWC2::Error::NoResources;
-    }
-  } else {
+HWC2::Error HostComposer::init() {
+  if (!mIsMinigbm) {
     mSyncDeviceFd = goldfish_sync_open();
   }
 
@@ -300,7 +283,7 @@
 
   std::optional<std::vector<uint8_t>> edid;
   if (mIsMinigbm) {
-    edid = mDrmPresenter.getEdid(displayId);
+    edid = mDrmPresenter->getEdid(displayId);
     if (edid) {
       display->setEdid(*edid);
     }
diff --git a/system/hwc2/HostComposer.h b/system/hwc2/HostComposer.h
index c4c2964..14fc0a7 100644
--- a/system/hwc2/HostComposer.h
+++ b/system/hwc2/HostComposer.h
@@ -29,7 +29,7 @@
 
 class HostComposer : public Composer {
  public:
-  HostComposer() = default;
+  HostComposer(DrmPresenter* drmPresenter, bool isMinigbm);
 
   HostComposer(const HostComposer&) = delete;
   HostComposer& operator=(const HostComposer&) = delete;
@@ -37,7 +37,7 @@
   HostComposer(HostComposer&&) = delete;
   HostComposer& operator=(HostComposer&&) = delete;
 
-  HWC2::Error init(const HotplugCallback& cb) override;
+  HWC2::Error init() override;
 
   HWC2::Error onDisplayCreate(Display* display) override;
 
@@ -83,8 +83,7 @@
   };
 
   std::unordered_map<hwc2_display_t, HostComposerDisplayInfo> mDisplayInfos;
-
-  DrmPresenter mDrmPresenter;
+  DrmPresenter* mDrmPresenter;
 };
 
 }  // namespace android