From 533f8981328cbb4090722a7c396208435960296e Mon Sep 17 00:00:00 2001 From: Brandon Wright Date: Sun, 15 Apr 2018 17:38:00 -0500 Subject: [PATCH] Add get refresh rate context function. Implement for X11 and Wayland. --- gfx/common/x11_common.c | 17 +++++++++++++++++ gfx/common/x11_common.h | 2 ++ gfx/drivers/gl.c | 10 +++++++++- gfx/drivers/vulkan.c | 12 +++++++++++- gfx/drivers/xshm_gfx.c | 9 +++++++-- gfx/drivers_context/android_ctx.c | 1 + gfx/drivers_context/cgl_ctx.c | 1 + gfx/drivers_context/drm_ctx.c | 1 + gfx/drivers_context/emscriptenegl_ctx.c | 1 + gfx/drivers_context/gdi_ctx.c | 1 + gfx/drivers_context/gfx_null_ctx.c | 1 + gfx/drivers_context/khr_display_ctx.c | 1 + gfx/drivers_context/mali_fbdev_ctx.c | 1 + gfx/drivers_context/opendingux_fbdev_ctx.c | 1 + gfx/drivers_context/osmesa_ctx.c | 1 + gfx/drivers_context/ps3_ctx.c | 1 + gfx/drivers_context/qnx_ctx.c | 1 + gfx/drivers_context/sdl_gl_ctx.c | 1 + gfx/drivers_context/vc_egl_ctx.c | 1 + gfx/drivers_context/vivante_fbdev_ctx.c | 1 + gfx/drivers_context/wayland_ctx.c | 10 ++++++++++ gfx/drivers_context/wgl_ctx.c | 1 + gfx/drivers_context/x_ctx.c | 1 + gfx/drivers_context/xegl_ctx.c | 1 + gfx/video_driver.c | 18 ++++++++++++++++++ gfx/video_driver.h | 6 ++++++ gfx/video_thread_wrapper.c | 1 + 27 files changed, 99 insertions(+), 4 deletions(-) diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index 6de3e8a3d7..97ec6adb08 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -234,6 +234,23 @@ void x11_suspend_screensaver(Window wnd, bool enable) x11_suspend_screensaver_xdg_screensaver(wnd, enable); } +float x11_get_refresh_rate(void *data) +{ + XWindowAttributes attr; + XF86VidModeModeLine modeline; + Screen *screen; + int screenid; + int dotclock; + + XGetWindowAttributes(g_x11_dpy, g_x11_win, &attr); + screen = attr.screen; + screenid = XScreenNumberOfScreen(screen); + + XF86VidModeGetModeLine(g_x11_dpy, screenid, &dotclock, &modeline); + + return (float) dotclock * 1000.0f / modeline.htotal / modeline.vtotal; +} + static bool get_video_mode(video_frame_info_t *video_info, Display *dpy, unsigned width, unsigned height, XF86VidModeModeInfo *mode, XF86VidModeModeInfo *desktop_mode) diff --git a/gfx/common/x11_common.h b/gfx/common/x11_common.h index 6be78245d1..3aa8117075 100644 --- a/gfx/common/x11_common.h +++ b/gfx/common/x11_common.h @@ -48,6 +48,8 @@ void x11_destroy_input_context(XIM *xim, XIC *xic); bool x11_get_metrics(void *data, enum display_metric_types type, float *value); +float x11_get_refresh_rate(void *data); + void x11_check_window(void *data, bool *quit, bool *resize, unsigned *width, unsigned *height, bool is_shutdown); diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 661cf4168b..ef6be56ece 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -2586,6 +2586,14 @@ static void gl_set_coords(void *handle_data, void *shader_data, shader_data, coords); } +static float gl_get_refresh_rate(void *data) +{ + float refresh_rate; + if (video_context_driver_get_refresh_rate(&refresh_rate)) + return refresh_rate; + return 0.0f; +} + static void gl_set_mvp(void *data, void *shader_data, const void *mat_data) { @@ -2601,7 +2609,7 @@ static const video_poke_interface_t gl_poke_interface = { gl_load_texture, gl_unload_texture, gl_set_video_mode, - NULL, /* get_refresh_rate */ + gl_get_refresh_rate, NULL, gl_get_video_output_size, gl_get_video_output_prev, diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 9d596941e8..c6c2aac6d6 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -2292,13 +2292,23 @@ static void vulkan_unload_texture(void *data, uintptr_t handle) free(texture); } +static float vulkan_get_refresh_rate(void *data) +{ + float refresh_rate; + + if (video_context_driver_get_refresh_rate(&refresh_rate)) + return refresh_rate; + + return 0.0f; +} + static const video_poke_interface_t vulkan_poke_interface = { NULL, /* set_coords */ NULL, /* set_mvp */ vulkan_load_texture, vulkan_unload_texture, vulkan_set_video_mode, - NULL, /* get_refresh_rate */ + vulkan_get_refresh_rate, /* get_refresh_rate */ NULL, NULL, NULL, diff --git a/gfx/drivers/xshm_gfx.c b/gfx/drivers/xshm_gfx.c index 218d670e22..6385f591ed 100644 --- a/gfx/drivers/xshm_gfx.c +++ b/gfx/drivers/xshm_gfx.c @@ -189,7 +189,7 @@ static void xshm_poke_texture_enable(void *data, static void xshm_poke_set_osd_msg(void *data, video_frame_info_t *video_info, const char *msg, - const struct font_params *params, void *font) + const void *params, void *font) { } @@ -203,13 +203,18 @@ static void xshm_grab_mouse_toggle(void *data) } +static float xshm_poke_get_refresh_rate(void *data) +{ + return x11_get_refresh_rate(data); +} + static video_poke_interface_t xshm_video_poke_interface = { NULL, /* set_coords */ NULL, /* set_mvp */ NULL, NULL, NULL, - NULL, /* get_refresh_rate */ + xshm_poke_get_refresh_rate, xshm_poke_set_filtering, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ diff --git a/gfx/drivers_context/android_ctx.c b/gfx/drivers_context/android_ctx.c index ca0f7911e1..422dc821cf 100644 --- a/gfx/drivers_context/android_ctx.c +++ b/gfx/drivers_context/android_ctx.c @@ -602,6 +602,7 @@ const gfx_ctx_driver_t gfx_ctx_android = { android_gfx_ctx_set_swap_interval, android_gfx_ctx_set_video_mode, android_gfx_ctx_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/cgl_ctx.c b/gfx/drivers_context/cgl_ctx.c index faeb63fc11..fb26355304 100644 --- a/gfx/drivers_context/cgl_ctx.c +++ b/gfx/drivers_context/cgl_ctx.c @@ -343,6 +343,7 @@ const gfx_ctx_driver_t gfx_ctx_cgl = { gfx_ctx_cgl_swap_interval, gfx_ctx_cgl_set_video_mode, gfx_ctx_cgl_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/drm_ctx.c b/gfx/drivers_context/drm_ctx.c index 2300815c18..a4937368f1 100644 --- a/gfx/drivers_context/drm_ctx.c +++ b/gfx/drivers_context/drm_ctx.c @@ -908,6 +908,7 @@ const gfx_ctx_driver_t gfx_ctx_drm = { gfx_ctx_drm_swap_interval, gfx_ctx_drm_set_video_mode, gfx_ctx_drm_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/emscriptenegl_ctx.c b/gfx/drivers_context/emscriptenegl_ctx.c index 1bc927e334..9e3234d86f 100644 --- a/gfx/drivers_context/emscriptenegl_ctx.c +++ b/gfx/drivers_context/emscriptenegl_ctx.c @@ -376,6 +376,7 @@ const gfx_ctx_driver_t gfx_ctx_emscripten = { gfx_ctx_emscripten_swap_interval, gfx_ctx_emscripten_set_video_mode, gfx_ctx_emscripten_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/gdi_ctx.c b/gfx/drivers_context/gdi_ctx.c index 6316df83a8..d251d75cb9 100644 --- a/gfx/drivers_context/gdi_ctx.c +++ b/gfx/drivers_context/gdi_ctx.c @@ -352,6 +352,7 @@ const gfx_ctx_driver_t gfx_ctx_gdi = { gfx_ctx_gdi_swap_interval, gfx_ctx_gdi_set_video_mode, gfx_ctx_gdi_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/gfx_null_ctx.c b/gfx/drivers_context/gfx_null_ctx.c index f7884ad08c..cf0c2cc742 100644 --- a/gfx/drivers_context/gfx_null_ctx.c +++ b/gfx/drivers_context/gfx_null_ctx.c @@ -141,6 +141,7 @@ const gfx_ctx_driver_t gfx_ctx_null = { gfx_ctx_null_swap_interval, gfx_ctx_null_set_video_mode, gfx_ctx_null_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/khr_display_ctx.c b/gfx/drivers_context/khr_display_ctx.c index c597383fee..0d671bbe4a 100644 --- a/gfx/drivers_context/khr_display_ctx.c +++ b/gfx/drivers_context/khr_display_ctx.c @@ -236,6 +236,7 @@ const gfx_ctx_driver_t gfx_ctx_khr_display = { gfx_ctx_khr_display_set_swap_interval, gfx_ctx_khr_display_set_video_mode, gfx_ctx_khr_display_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/mali_fbdev_ctx.c b/gfx/drivers_context/mali_fbdev_ctx.c index 565796345d..b30de94dcf 100644 --- a/gfx/drivers_context/mali_fbdev_ctx.c +++ b/gfx/drivers_context/mali_fbdev_ctx.c @@ -294,6 +294,7 @@ const gfx_ctx_driver_t gfx_ctx_mali_fbdev = { gfx_ctx_mali_fbdev_set_swap_interval, gfx_ctx_mali_fbdev_set_video_mode, gfx_ctx_mali_fbdev_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/opendingux_fbdev_ctx.c b/gfx/drivers_context/opendingux_fbdev_ctx.c index 5d6c0bf820..69ff6a58c6 100644 --- a/gfx/drivers_context/opendingux_fbdev_ctx.c +++ b/gfx/drivers_context/opendingux_fbdev_ctx.c @@ -271,6 +271,7 @@ const gfx_ctx_driver_t gfx_ctx_opendingux_fbdev = { gfx_ctx_opendingux_set_swap_interval, gfx_ctx_opendingux_set_video_mode, gfx_ctx_opendingux_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/osmesa_ctx.c b/gfx/drivers_context/osmesa_ctx.c index df460a14d5..a3ffaf5957 100644 --- a/gfx/drivers_context/osmesa_ctx.c +++ b/gfx/drivers_context/osmesa_ctx.c @@ -398,6 +398,7 @@ const gfx_ctx_driver_t gfx_ctx_osmesa = osmesa_ctx_swap_interval, osmesa_ctx_set_video_mode, osmesa_ctx_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/ps3_ctx.c b/gfx/drivers_context/ps3_ctx.c index 9ff04dd84f..1a5dd2c0ff 100644 --- a/gfx/drivers_context/ps3_ctx.c +++ b/gfx/drivers_context/ps3_ctx.c @@ -421,6 +421,7 @@ const gfx_ctx_driver_t gfx_ctx_ps3 = { gfx_ctx_ps3_get_video_output_size, gfx_ctx_ps3_get_video_output_prev, gfx_ctx_ps3_get_video_output_next, + NULL, /* get_refresh_rate */ NULL, /* get_metrics */ NULL, NULL, /* update_title */ diff --git a/gfx/drivers_context/qnx_ctx.c b/gfx/drivers_context/qnx_ctx.c index a425aebdac..2ce96ac7aa 100644 --- a/gfx/drivers_context/qnx_ctx.c +++ b/gfx/drivers_context/qnx_ctx.c @@ -471,6 +471,7 @@ const gfx_ctx_driver_t gfx_ctx_qnx = { gfx_ctx_qnx_set_swap_interval, gfx_ctx_qnx_set_video_mode, gfx_ctx_qnx_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/sdl_gl_ctx.c b/gfx/drivers_context/sdl_gl_ctx.c index 5801c4e9a9..aedb29e5dc 100644 --- a/gfx/drivers_context/sdl_gl_ctx.c +++ b/gfx/drivers_context/sdl_gl_ctx.c @@ -422,6 +422,7 @@ const gfx_ctx_driver_t gfx_ctx_sdl_gl = sdl_ctx_swap_interval, sdl_ctx_set_video_mode, sdl_ctx_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/vc_egl_ctx.c b/gfx/drivers_context/vc_egl_ctx.c index a485eb4e43..e507056aed 100644 --- a/gfx/drivers_context/vc_egl_ctx.c +++ b/gfx/drivers_context/vc_egl_ctx.c @@ -712,6 +712,7 @@ const gfx_ctx_driver_t gfx_ctx_videocore = { gfx_ctx_vc_set_swap_interval, gfx_ctx_vc_set_video_mode, gfx_ctx_vc_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/vivante_fbdev_ctx.c b/gfx/drivers_context/vivante_fbdev_ctx.c index 7176ce976b..512e740add 100644 --- a/gfx/drivers_context/vivante_fbdev_ctx.c +++ b/gfx/drivers_context/vivante_fbdev_ctx.c @@ -277,6 +277,7 @@ const gfx_ctx_driver_t gfx_ctx_vivante_fbdev = { gfx_ctx_vivante_set_swap_interval, gfx_ctx_vivante_set_video_mode, gfx_ctx_vivante_get_video_size, + NULL, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 0b5e3d7a26..07e1d7b3aa 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -58,6 +58,7 @@ typedef struct gfx_ctx_wayland_data unsigned height; unsigned physical_width; unsigned physical_height; + int refresh_rate; struct wl_registry *registry; struct wl_compositor *compositor; struct wl_surface *surface; @@ -440,6 +441,7 @@ static void display_handle_mode(void *data, gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; wl->width = width; wl->height = height; + wl->refresh_rate = refresh; /* Certain older Wayland implementations report in Hz, * but it should be mHz. */ @@ -1369,6 +1371,13 @@ static void gfx_ctx_wl_show_mouse(void *data, bool state) wl->cursor.visible = state; } +static float gfx_ctx_wl_get_refresh_rate(void *data) +{ + gfx_ctx_wayland_data_t *wl = (gfx_ctx_wayland_data_t*)data; + + return (float) wl->refresh_rate * 1000.0f; +} + const gfx_ctx_driver_t gfx_ctx_wayland = { gfx_ctx_wl_init, gfx_ctx_wl_destroy, @@ -1377,6 +1386,7 @@ const gfx_ctx_driver_t gfx_ctx_wayland = { gfx_ctx_wl_set_swap_interval, gfx_ctx_wl_set_video_mode, gfx_ctx_wl_get_video_size, + gfx_ctx_wl_get_refresh_rate, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.c index 1545862bd3..a698eadfb3 100644 --- a/gfx/drivers_context/wgl_ctx.c +++ b/gfx/drivers_context/wgl_ctx.c @@ -760,6 +760,7 @@ const gfx_ctx_driver_t gfx_ctx_wgl = { gfx_ctx_wgl_swap_interval, gfx_ctx_wgl_set_video_mode, gfx_ctx_wgl_get_video_size, + NULL, /* get_refresh_rate */ gfx_ctx_wgl_get_video_output_size, gfx_ctx_wgl_get_video_output_prev, gfx_ctx_wgl_get_video_output_next, diff --git a/gfx/drivers_context/x_ctx.c b/gfx/drivers_context/x_ctx.c index e623f6c287..62051b43d8 100644 --- a/gfx/drivers_context/x_ctx.c +++ b/gfx/drivers_context/x_ctx.c @@ -1225,6 +1225,7 @@ const gfx_ctx_driver_t gfx_ctx_x = { gfx_ctx_x_swap_interval, gfx_ctx_x_set_video_mode, x11_get_video_size, + x11_get_refresh_rate, /* get_refresh_rate */ NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/drivers_context/xegl_ctx.c b/gfx/drivers_context/xegl_ctx.c index 04485648e2..45df7e35c1 100644 --- a/gfx/drivers_context/xegl_ctx.c +++ b/gfx/drivers_context/xegl_ctx.c @@ -621,6 +621,7 @@ const gfx_ctx_driver_t gfx_ctx_x_egl = gfx_ctx_xegl_set_swap_interval, gfx_ctx_xegl_set_video_mode, x11_get_video_size, + x11_get_refresh_rate, NULL, /* get_video_output_size */ NULL, /* get_video_output_prev */ NULL, /* get_video_output_next */ diff --git a/gfx/video_driver.c b/gfx/video_driver.c index c17badc092..60f475de59 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -3189,6 +3189,16 @@ bool video_context_driver_get_metrics(gfx_ctx_metrics_t *metrics) return false; } +bool video_context_driver_get_refresh_rate(float *refresh_rate) +{ + if (!current_video_context.get_refresh_rate || !refresh_rate) + return false; + + *refresh_rate = current_video_context.get_refresh_rate(video_context_data); + + return true; +} + bool video_context_driver_input_driver(gfx_ctx_input_t *inp) { settings_t *settings = config_get_ptr(); @@ -3684,3 +3694,11 @@ void video_driver_set_mvp(video_shader_ctx_mvp_t *mvp) video_driver_poke->set_mvp(mvp->data, current_shader_data, mvp->matrix); } } + +float video_driver_get_refresh_rate(void) +{ + if (video_driver_poke && video_driver_poke->get_refresh_rate) + return video_driver_poke->get_refresh_rate(video_driver_data); + + return 0.0f; +} diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 8f84180655..0d2336d003 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -526,6 +526,8 @@ typedef struct gfx_ctx_driver * If not initialized yet, it returns current screen size. */ void (*get_video_size)(void*, unsigned*, unsigned*); + float (*get_refresh_rate)(void*); + void (*get_video_output_size)(void*, unsigned*, unsigned*); void (*get_video_output_prev)(void*); @@ -1275,6 +1277,8 @@ bool video_context_driver_set_video_mode(gfx_ctx_mode_t *mode_info); bool video_context_driver_get_video_size(gfx_ctx_mode_t *mode_info); +bool video_context_driver_get_refresh_rate(float *refresh_rate); + bool video_context_driver_get_context_data(void *data); bool video_context_driver_show_mouse(bool *bool_data); @@ -1333,6 +1337,8 @@ void video_shader_driver_use(void *data); bool video_shader_driver_wrap_type(video_shader_ctx_wrap_t *wrap); +float video_driver_get_refresh_rate(void); + extern bool (*video_driver_cb_has_focus)(void); extern video_driver_t video_gl; diff --git a/gfx/video_thread_wrapper.c b/gfx/video_thread_wrapper.c index 027e4a0daf..e6216a6d8c 100644 --- a/gfx/video_thread_wrapper.c +++ b/gfx/video_thread_wrapper.c @@ -1258,6 +1258,7 @@ static const video_poke_interface_t thread_poke = { thread_load_texture, thread_unload_texture, thread_set_video_mode, + NULL, thread_set_filtering, thread_get_video_output_size, thread_get_video_output_prev,