[mutter] backends/native: Add meta_calculate_drm_mode_vblank_duration_us()



commit e40ff9d8b758572d5914ee0f9cbf8f631dd8d788
Author: Ivan Molodetskikh <yalterz gmail com>
Date:   Wed Jan 6 11:36:04 2021 +0300

    backends/native: Add meta_calculate_drm_mode_vblank_duration_us()
    
    Computes the vblank duration from mode timings.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>

 src/backends/native/meta-kms-utils.c |  21 +++++++
 src/backends/native/meta-kms-utils.h |   3 +
 src/tests/kms-utils-unit-tests.c     | 109 +++++++++++++++++++++++++++++++++--
 3 files changed, 129 insertions(+), 4 deletions(-)
---
diff --git a/src/backends/native/meta-kms-utils.c b/src/backends/native/meta-kms-utils.c
index 1c58db83d5..2289cfa918 100644
--- a/src/backends/native/meta-kms-utils.c
+++ b/src/backends/native/meta-kms-utils.c
@@ -47,6 +47,27 @@ meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *drm_mode)
   return numerator / denominator;
 }
 
+int64_t
+meta_calculate_drm_mode_vblank_duration_us (const drmModeModeInfo *drm_mode)
+{
+  int64_t value;
+
+  if (drm_mode->htotal <= 0 || drm_mode->vtotal <= 0)
+    return 0;
+
+  /* Convert to int64_t early. */
+  value = drm_mode->vtotal - drm_mode->vdisplay;
+  value *= drm_mode->htotal;
+
+  if (drm_mode->flags & DRM_MODE_FLAG_DBLSCAN)
+    value *= 2;
+
+  /* Round the duration up as it is used for buffer swap deadline computation. */
+  value = (value * 1000 + drm_mode->clock - 1) / drm_mode->clock;
+
+  return value;
+}
+
 /**
  * meta_drm_format_to_string:
  * @tmp: temporary buffer
diff --git a/src/backends/native/meta-kms-utils.h b/src/backends/native/meta-kms-utils.h
index c22ceaaa0f..2f2bad1f90 100644
--- a/src/backends/native/meta-kms-utils.h
+++ b/src/backends/native/meta-kms-utils.h
@@ -34,6 +34,9 @@ typedef struct _MetaDrmFormatBuf
 META_EXPORT_TEST
 float meta_calculate_drm_mode_refresh_rate (const drmModeModeInfo *drm_mode);
 
+META_EXPORT_TEST
+int64_t meta_calculate_drm_mode_vblank_duration_us (const drmModeModeInfo *drm_mode);
+
 const char * meta_drm_format_to_string (MetaDrmFormatBuf *tmp,
                                         uint32_t          drm_format);
 
diff --git a/src/tests/kms-utils-unit-tests.c b/src/tests/kms-utils-unit-tests.c
index 324166d684..40b768b3e6 100644
--- a/src/tests/kms-utils-unit-tests.c
+++ b/src/tests/kms-utils-unit-tests.c
@@ -26,9 +26,9 @@
 typedef struct {
   drmModeModeInfo drm_mode;
   float expected_refresh_rate;
-} ModeInfoTestCase;
+} RefreshRateTestCase;
 
-static const ModeInfoTestCase test_cases[] = {
+static const RefreshRateTestCase refresh_rate_test_cases[] = {
   /* "cvt 640 480" */
   {
     .drm_mode = {
@@ -125,9 +125,9 @@ meta_test_kms_refresh_rate (void)
 {
   size_t index;
 
-  for (index = 0; index < G_N_ELEMENTS(test_cases); index++)
+  for (index = 0; index < G_N_ELEMENTS (refresh_rate_test_cases); index++)
     {
-      const ModeInfoTestCase *test_case = test_cases + index;
+      const RefreshRateTestCase *test_case = refresh_rate_test_cases + index;
       float refresh_rate;
 
       refresh_rate =
@@ -138,6 +138,105 @@ meta_test_kms_refresh_rate (void)
     }
 }
 
+typedef struct
+{
+  drmModeModeInfo drm_mode;
+  int64_t expected_vblank_duration_us;
+} VblankDurationTestCase;
+
+static const VblankDurationTestCase vblank_duration_test_cases[] = {
+  /* "cvt 640 480" */
+  {
+    .drm_mode = {
+      .clock = 23975,
+      .hdisplay = 640,
+      .hsync_start = 664,
+      .hsync_end = 720,
+      .htotal = 800,
+      .vdisplay = 480,
+      .vsync_start = 483,
+      .vsync_end = 487,
+      .vtotal = 500,
+      .vscan = 0,
+      .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
+    },
+    .expected_vblank_duration_us = 668,
+  },
+
+  /* "cvt 640 480" with htotal 0 */
+  {
+    .drm_mode = {
+       .clock = 23975,
+       .hdisplay = 640,
+       .hsync_start = 664,
+       .hsync_end = 720,
+       .htotal = 0,
+       .vdisplay = 480,
+       .vsync_start = 483,
+       .vsync_end = 487,
+       .vtotal = 500,
+       .vscan = 0,
+       .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
+    },
+    .expected_vblank_duration_us = 0,
+  },
+
+  /* "cvt 640 480" with vtotal 0 */
+  {
+    .drm_mode = {
+      .clock = 23975,
+      .hdisplay = 640,
+      .hsync_start = 664,
+      .hsync_end = 720,
+      .htotal = 800,
+      .vdisplay = 480,
+      .vsync_start = 483,
+      .vsync_end = 487,
+      .vtotal = 0,
+      .vscan = 0,
+      .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC,
+    },
+    .expected_vblank_duration_us = 0,
+  },
+
+  /* "cvt 640 480" with DBLSCAN */
+  {
+    .drm_mode = {
+      .clock = 23975,
+      .hdisplay = 640,
+      .hsync_start = 664,
+      .hsync_end = 720,
+      .htotal = 800,
+      .vdisplay = 480,
+      .vsync_start = 483,
+      .vsync_end = 487,
+      .vtotal = 500,
+      .vscan = 0,
+      .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC |
+               DRM_MODE_FLAG_DBLSCAN,
+    },
+    .expected_vblank_duration_us = 1335,
+  },
+};
+
+static void
+meta_test_kms_vblank_duration (void)
+{
+  size_t index;
+
+  for (index = 0; index < G_N_ELEMENTS (vblank_duration_test_cases); index++)
+    {
+      const VblankDurationTestCase *test_case = vblank_duration_test_cases + index;
+      int64_t vblank_duration_us;
+
+      vblank_duration_us =
+        meta_calculate_drm_mode_vblank_duration_us (&test_case->drm_mode);
+      g_assert_cmpint (vblank_duration_us,
+                       ==,
+                       test_case->expected_vblank_duration_us);
+    }
+}
+
 static void
 meta_test_kms_update_fixed16 (void)
 {
@@ -152,6 +251,8 @@ init_kms_utils_tests (void)
 {
   g_test_add_func ("/backends/native/kms/refresh-rate",
                    meta_test_kms_refresh_rate);
+  g_test_add_func ("/backends/native/kms/vblank-duration",
+                   meta_test_kms_vblank_duration);
   g_test_add_func ("/backends/native/kms/update/fixed16",
                    meta_test_kms_update_fixed16);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]