Variable refresh rate for virtual display

Allow virtual display to request a refresh rate, so it can be different
from VSYNC frequencies. SurfaceFlinger drops frames for the
corresponding virtual display based on the refresh rate.

Bug: 241286579
Test: atest libgui_test libsurfaceflinger_unittest SurfaceFlinger_test
Change-Id: I4fba0e553618bb4c7333514b16206ae4277acf72
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index c61f7d8..ba8b6cf 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -71,6 +71,7 @@
         mRenderFrameRateFPSTrace("RenderRateFPS -" + to_string(getId())),
         mPhysicalOrientation(args.physicalOrientation),
         mIsPrimary(args.isPrimary),
+        mRequestedRefreshRate(args.requestedRefreshRate),
         mRefreshRateSelector(std::move(args.refreshRateSelector)) {
     mCompositionDisplay->editState().isSecure = args.isSecure;
     mCompositionDisplay->createRenderSurface(
@@ -513,6 +514,23 @@
     mDesiredActiveModeChanged = false;
 }
 
+void DisplayDevice::adjustRefreshRate(Fps leaderDisplayRefreshRate) {
+    using fps_approx_ops::operator==;
+    if (mRequestedRefreshRate == 0_Hz) {
+        return;
+    }
+
+    using fps_approx_ops::operator>;
+    if (mRequestedRefreshRate > leaderDisplayRefreshRate) {
+        mAdjustedRefreshRate = leaderDisplayRefreshRate;
+        return;
+    }
+
+    unsigned divisor = static_cast<unsigned>(
+            std::round(leaderDisplayRefreshRate.getValue() / mRequestedRefreshRate.getValue()));
+    mAdjustedRefreshRate = leaderDisplayRefreshRate / divisor;
+}
+
 std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);
 
 }  // namespace android