[mutter] KMS/Wayland: Correct refresh rate units



commit c16a5ec1cf14d67ee8100afd31a2e85e7003f9a8
Author: Daniel Stone <daniels collabora com>
Date:   Wed Nov 25 12:56:18 2015 +0000

    KMS/Wayland: Correct refresh rate units
    
    On the wire, Wayland specifies the refresh rate in milliHz. Mutter sends
    the refresh rate in Hz, which confuses clients, e.g. weston-info:
    interface: 'wl_output', version: 2, name: 4
        mode:
                width: 2560 px, height: 1440 px, refresh: 0 Hz,
                flags: current preferred
    interface: 'wl_output', version: 2, name: 5
        mode:
                width: 3200 px, height: 1800 px, refresh: 0 Hz,
                flags: current preferred
    
    and xrandr:
    XWAYLAND0 connected 2560x1440+3200+0 600mm x 340mm
       2560x1440 0 1Hz   0.05*+
    XWAYLAND1 connected 3200x1800+0+0 290mm x 170mm
       3200x1800 0 1Hz   0.03*+
    
    Export the refresh rate in the correct units. For improved precision,
    perform the KMS intermediate calculations in milliHz as well, and
    account for interlaced/doublescan modes.
    
    This is also consistent with what GTK+ expects:
          timings->refresh_interval = 16667; /* default to 1/60th of a second */
    
          /* We pick a random output out of the outputs that the window touches
           * The rate here is in milli-hertz */
          int refresh_rate = _gdk_wayland_screen_get_output_refresh_rate (wayland_display->screen,
                                                                          impl->outputs->data);
          if (refresh_rate != 0)
            timings->refresh_interval = G_GINT64_CONSTANT(1000000000) / refresh_rate;
    
    Where the 'refresh_rate' given is exactly what's come off the wire.
    1000000000/60000 comes out as 16667, whereas divided by 60 is ...
    substantially less.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=758653

 src/backends/native/meta-monitor-manager-kms.c |   14 ++++++++++++--
 src/wayland/meta-wayland-outputs.c             |    4 ++--
 2 files changed, 14 insertions(+), 4 deletions(-)
---
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index cc2b18e..1a2338d 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -496,8 +496,18 @@ meta_monitor_manager_kms_read_current (MetaMonitorManager *manager)
       meta_mode->name = g_strndup (mode->name, DRM_DISPLAY_MODE_LEN);
       meta_mode->width = mode->hdisplay;
       meta_mode->height = mode->vdisplay;
-      meta_mode->refresh_rate = (1000 * mode->clock /
-                                 ((float)mode->htotal * mode->vtotal));
+
+      /* Calculate refresh rate in milliHz first for extra precision. */
+      meta_mode->refresh_rate = (mode->clock * 1000000LL) / mode->htotal;
+      meta_mode->refresh_rate += (mode->vtotal / 2);
+      meta_mode->refresh_rate /= mode->vtotal;
+      if (mode->flags & DRM_MODE_FLAG_INTERLACE)
+       meta_mode->refresh_rate *= 2;
+      if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
+        meta_mode->refresh_rate /= 2;
+      if (mode->vscan > 1)
+        meta_mode->refresh_rate /= mode->vscan;
+      meta_mode->refresh_rate /= 1000.0;
 
       meta_mode->driver_private = g_slice_dup (drmModeModeInfo, mode);
       meta_mode->driver_notify = (GDestroyNotify)meta_monitor_mode_destroy_notify;
diff --git a/src/wayland/meta-wayland-outputs.c b/src/wayland/meta-wayland-outputs.c
index 1a7d16e..df19949 100644
--- a/src/wayland/meta-wayland-outputs.c
+++ b/src/wayland/meta-wayland-outputs.c
@@ -99,7 +99,7 @@ bind_output (struct wl_client *client,
                        mode_flags,
                        (int)monitor_info->rect.width,
                        (int)monitor_info->rect.height,
-                       (int)monitor_info->refresh_rate);
+                       (int)(monitor_info->refresh_rate * 1000));
 
   if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
     wl_output_send_scale (resource, output->scale);
@@ -160,7 +160,7 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
                            mode_flags,
                            (int)monitor_info->rect.width,
                            (int)monitor_info->rect.height,
-                           (int)monitor_info->refresh_rate);
+                           (int)(monitor_info->refresh_rate * 1000));
     }
 
   /* It's very important that we change the output pointer here, as


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