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
This commit is contained in:
parent
f3e1964362
commit
c16a5ec1cf
@ -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->name = g_strndup (mode->name, DRM_DISPLAY_MODE_LEN);
|
||||||
meta_mode->width = mode->hdisplay;
|
meta_mode->width = mode->hdisplay;
|
||||||
meta_mode->height = mode->vdisplay;
|
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_private = g_slice_dup (drmModeModeInfo, mode);
|
||||||
meta_mode->driver_notify = (GDestroyNotify)meta_monitor_mode_destroy_notify;
|
meta_mode->driver_notify = (GDestroyNotify)meta_monitor_mode_destroy_notify;
|
||||||
|
@ -99,7 +99,7 @@ bind_output (struct wl_client *client,
|
|||||||
mode_flags,
|
mode_flags,
|
||||||
(int)monitor_info->rect.width,
|
(int)monitor_info->rect.width,
|
||||||
(int)monitor_info->rect.height,
|
(int)monitor_info->rect.height,
|
||||||
(int)monitor_info->refresh_rate);
|
(int)(monitor_info->refresh_rate * 1000));
|
||||||
|
|
||||||
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
||||||
wl_output_send_scale (resource, output->scale);
|
wl_output_send_scale (resource, output->scale);
|
||||||
@ -160,7 +160,7 @@ wayland_output_update_for_output (MetaWaylandOutput *wayland_output,
|
|||||||
mode_flags,
|
mode_flags,
|
||||||
(int)monitor_info->rect.width,
|
(int)monitor_info->rect.width,
|
||||||
(int)monitor_info->rect.height,
|
(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
|
/* It's very important that we change the output pointer here, as
|
||||||
|
Loading…
Reference in New Issue
Block a user