From 3000b8615fd4ba62b1a0f804caf0b150d5edf22c Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sat, 13 May 2017 22:27:25 +1200 Subject: [PATCH 1/2] More accurate refresh rates (mHz) --- backend/drm/drm.c | 22 +++++++++++++++++----- include/wlr/wayland.h | 4 ++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 7cbd3e4a..fb49d46c 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -249,6 +249,20 @@ static struct wlr_output_impl output_impl = { .destroy = wlr_drm_output_destroy, }; +static uint32_t calculate_refresh_rate(drmModeModeInfo *mode) { + uint32_t refresh = (mode->clock * 1000000LL / mode->htotal + + mode->vtotal / 2) / mode->vtotal; + + if (mode->flags & DRM_MODE_FLAG_INTERLACE) + refresh *= 2; + if (mode->flags & DRM_MODE_FLAG_DBLSCAN) + refresh /= 2; + if (mode->vscan > 1) + refresh /= mode->vscan; + + return refresh; +} + void wlr_drm_scan_connectors(struct wlr_backend_state *state) { wlr_log(L_INFO, "Scanning DRM connectors"); @@ -321,14 +335,12 @@ void wlr_drm_scan_connectors(struct wlr_backend_state *state) { struct wlr_output_mode *mode = calloc(1, sizeof(struct wlr_output_mode)); mode->width = _state->mode.hdisplay; - // TODO: Calculate more accurate refresh rate - // TODO: Check that this refresh rate is mHz mode->height = _state->mode.vdisplay; + mode->refresh = calculate_refresh_rate(&_state->mode); mode->state = _state; - wlr_log(L_INFO, " %"PRIu16"@%"PRIu16"@%"PRIu32, - _state->mode.hdisplay, _state->mode.vdisplay, - _state->mode.vrefresh); + wlr_log(L_INFO, " %"PRIu32"@%"PRIu32"@%"PRIu32, + mode->width, mode->height, mode->refresh); list_add(wlr_output->modes, mode); } diff --git a/include/wlr/wayland.h b/include/wlr/wayland.h index 158acc33..de3f5f10 100644 --- a/include/wlr/wayland.h +++ b/include/wlr/wayland.h @@ -10,8 +10,8 @@ struct wlr_output_mode_state; struct wlr_output_mode { struct wlr_output_mode_state *state; uint32_t flags; // enum wl_output_mode - int32_t width, height; - int32_t refresh; // mHz + uint32_t width, height; + uint32_t refresh; // mHz }; struct wlr_output_impl; From 409065ba2ecd34d249383704f9a63b4894f55dba Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sun, 14 May 2017 01:26:43 +1200 Subject: [PATCH 2/2] Changed to signed --- backend/drm/drm.c | 6 +++--- include/wlr/wayland.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 8a64dfa6..db75853d 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -249,8 +249,8 @@ static struct wlr_output_impl output_impl = { .destroy = wlr_drm_output_destroy, }; -static uint32_t calculate_refresh_rate(drmModeModeInfo *mode) { - uint32_t refresh = (mode->clock * 1000000LL / mode->htotal + +static int32_t calculate_refresh_rate(drmModeModeInfo *mode) { + int32_t refresh = (mode->clock * 1000000LL / mode->htotal + mode->vtotal / 2) / mode->vtotal; if (mode->flags & DRM_MODE_FLAG_INTERLACE) @@ -365,7 +365,7 @@ void wlr_drm_scan_connectors(struct wlr_backend_state *state) { mode->refresh = calculate_refresh_rate(&_state->mode); mode->state = _state; - wlr_log(L_INFO, " %"PRIu32"@%"PRIu32"@%"PRIu32, + wlr_log(L_INFO, " %"PRId32"@%"PRId32"@%"PRId32, mode->width, mode->height, mode->refresh); list_add(wlr_output->modes, mode); diff --git a/include/wlr/wayland.h b/include/wlr/wayland.h index de3f5f10..158acc33 100644 --- a/include/wlr/wayland.h +++ b/include/wlr/wayland.h @@ -10,8 +10,8 @@ struct wlr_output_mode_state; struct wlr_output_mode { struct wlr_output_mode_state *state; uint32_t flags; // enum wl_output_mode - uint32_t width, height; - uint32_t refresh; // mHz + int32_t width, height; + int32_t refresh; // mHz }; struct wlr_output_impl;