From 006ec9ce4357cd198955bc2e56caec34943db52d Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Sun, 22 Jan 2023 17:06:15 -0600 Subject: [PATCH] wayland: rewrite geometry and scaling handling This is in preparation for fractional scaling support. Basically, redo all the coordinates in wayland so that wl->geometry is equal exactly to what is being put out to the screen (no extra wl->scaling multiplication required). The wl->vdparams variable is also eliminated for simplicity. This changes mpv's behavior on wayland with hidpi scaling but that will be addressed in more detail with the next commit. --- video/out/opengl/context_wayland.c | 8 +++--- video/out/vo_dmabuf_wayland.c | 7 ++--- video/out/vo_wlshm.c | 4 +-- video/out/vulkan/context_wayland.c | 4 +-- video/out/wayland_common.c | 46 ++++++++++++++---------------- video/out/wayland_common.h | 1 - 6 files changed, 31 insertions(+), 39 deletions(-) diff --git a/video/out/opengl/context_wayland.c b/video/out/opengl/context_wayland.c index 400da0047d..a932ca48fc 100644 --- a/video/out/opengl/context_wayland.c +++ b/video/out/opengl/context_wayland.c @@ -43,8 +43,8 @@ static void egl_create_window(struct ra_ctx *ctx) struct vo_wayland_state *wl = ctx->vo->wl; p->egl_window = wl_egl_window_create(wl->surface, - mp_rect_w(wl->geometry) * wl->scaling, - mp_rect_h(wl->geometry) * wl->scaling); + mp_rect_w(wl->geometry), + mp_rect_h(wl->geometry)); p->egl_surface = mpegl_create_window_surface( p->egl_display, p->egl_config, p->egl_window); @@ -75,8 +75,8 @@ static void resize(struct ra_ctx *ctx) if (!p->egl_window) egl_create_window(ctx); - const int32_t width = wl->scaling * mp_rect_w(wl->geometry); - const int32_t height = wl->scaling * mp_rect_h(wl->geometry); + const int32_t width = mp_rect_w(wl->geometry); + const int32_t height = mp_rect_h(wl->geometry); vo_wayland_set_opaque_region(wl, ctx->opts.want_alpha); if (p->egl_window) diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c index 4c0594911a..ead01e6ed9 100644 --- a/video/out/vo_dmabuf_wayland.c +++ b/video/out/vo_dmabuf_wayland.c @@ -1,6 +1,4 @@ /* - * Based on vo_gl.c by Reimar Doeffinger. - * * This file is part of mpv. * * mpv is free software; you can redistribute it and/or @@ -178,8 +176,8 @@ static void resize(struct vo *vo) struct mp_rect dst; struct mp_osd_res osd; struct mp_vo_opts *vo_opts = wl->vo_opts; - const int width = wl->scaling * mp_rect_w(wl->geometry); - const int height = wl->scaling * mp_rect_h(wl->geometry); + const int width = mp_rect_w(wl->geometry); + const int height = mp_rect_h(wl->geometry); vo_wayland_set_opaque_region(wl, 0); vo->dwidth = width; @@ -378,7 +376,6 @@ static int preinit(struct vo *vo) goto err; } - if (vo->wl->single_pixel_manager) { #if HAVE_WAYLAND_PROTOCOLS_1_27 p->solid_buffer = wp_single_pixel_buffer_manager_v1_create_u32_rgba_buffer( diff --git a/video/out/vo_wlshm.c b/video/out/vo_wlshm.c index 9b35364c6d..6f70767b29 100644 --- a/video/out/vo_wlshm.c +++ b/video/out/vo_wlshm.c @@ -182,8 +182,8 @@ static int resize(struct vo *vo) { struct priv *p = vo->priv; struct vo_wayland_state *wl = vo->wl; - const int32_t width = wl->scaling * mp_rect_w(wl->geometry); - const int32_t height = wl->scaling * mp_rect_h(wl->geometry); + const int32_t width = mp_rect_w(wl->geometry); + const int32_t height = mp_rect_h(wl->geometry); struct buffer *buf; vo_wayland_set_opaque_region(wl, 0); diff --git a/video/out/vulkan/context_wayland.c b/video/out/vulkan/context_wayland.c index fb6d91dacd..157c76855c 100644 --- a/video/out/vulkan/context_wayland.c +++ b/video/out/vulkan/context_wayland.c @@ -114,8 +114,8 @@ static bool resize(struct ra_ctx *ctx) MP_VERBOSE(wl, "Handling resize on the vk side\n"); - const int32_t width = wl->scaling * mp_rect_w(wl->geometry); - const int32_t height = wl->scaling * mp_rect_h(wl->geometry); + const int32_t width = mp_rect_w(wl->geometry); + const int32_t height = mp_rect_h(wl->geometry); vo_wayland_set_opaque_region(wl, ctx->opts.want_alpha); return ra_vk_ctx_resize(ctx, width, height); diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 9c399b7346..aa987480c3 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -920,21 +920,21 @@ static void handle_toplevel_config(void *data, struct xdg_toplevel *toplevel, } wl->window_size.x0 = 0; wl->window_size.y0 = 0; - wl->window_size.x1 = width; - wl->window_size.y1 = height; + wl->window_size.x1 = round(width * wl->scaling); + wl->window_size.y1 = round(height * wl->scaling); } wl->geometry.x0 = 0; wl->geometry.y0 = 0; - wl->geometry.x1 = width; - wl->geometry.y1 = height; + wl->geometry.x1 = round(width * wl->scaling); + wl->geometry.y1 = round(height * wl->scaling); if (mp_rect_equals(&old_geometry, &wl->geometry)) return; resize: MP_VERBOSE(wl, "Resizing due to xdg from %ix%i to %ix%i\n", - mp_rect_w(old_geometry)*wl->scaling, mp_rect_h(old_geometry)*wl->scaling, - mp_rect_w(wl->geometry)*wl->scaling, mp_rect_h(wl->geometry)*wl->scaling); + mp_rect_w(old_geometry), mp_rect_h(old_geometry), + mp_rect_w(wl->geometry), mp_rect_h(wl->geometry)); wl->pending_vo_events |= VO_EVENT_RESIZE; wl->toplevel_configured = true; @@ -1593,17 +1593,14 @@ static void set_geometry(struct vo_wayland_state *wl) struct vo_win_geometry geo; struct mp_rect screenrc = wl->current_output->geometry; - vo_calc_window_geometry(vo, &screenrc, &geo); + vo_calc_window_geometry2(vo, &screenrc, wl->scaling, &geo); vo_apply_window_geometry(vo, &geo); greatest_common_divisor(wl, vo->dwidth, vo->dheight); wl->reduced_width = vo->dwidth / wl->gcd; wl->reduced_height = vo->dheight / wl->gcd; - wl->vdparams.x0 = 0; - wl->vdparams.y0 = 0; - wl->vdparams.x1 = vo->dwidth / wl->scaling; - wl->vdparams.y1 = vo->dheight / wl->scaling; + wl->window_size = (struct mp_rect){0, 0, vo->dwidth, vo->dheight}; } static int set_screensaver_inhibitor(struct vo_wayland_state *wl, int state) @@ -1635,10 +1632,11 @@ static void set_surface_scaling(struct vo_wayland_state *wl) } double factor = (double)old_scale / wl->scaling; - wl->vdparams.x1 *= factor; - wl->vdparams.y1 *= factor; - wl->window_size.x1 *= factor; - wl->window_size.y1 *= factor; + wl->window_size.x1 /= factor; + wl->window_size.y1 /= factor; + wl->geometry.x1 /= factor; + wl->geometry.y1 /= factor; + wl_surface_set_buffer_scale(wl->surface, wl->scaling); } @@ -1865,7 +1863,6 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg) { if (wl->current_output) { set_geometry(wl); - wl->window_size = wl->vdparams; if (!wl->vo_opts->fullscreen && !wl->vo_opts->window_maximized) wl->geometry = wl->window_size; wl->pending_vo_events |= VO_EVENT_RESIZE; @@ -1892,11 +1889,11 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg) case VOCTRL_GET_UNFS_WINDOW_SIZE: { int *s = arg; if (wl->vo_opts->window_maximized) { - s[0] = mp_rect_w(wl->geometry) * wl->scaling; - s[1] = mp_rect_h(wl->geometry) * wl->scaling; + s[0] = mp_rect_w(wl->geometry); + s[1] = mp_rect_h(wl->geometry); } else { - s[0] = mp_rect_w(wl->window_size) * wl->scaling; - s[1] = mp_rect_h(wl->window_size) * wl->scaling; + s[0] = mp_rect_w(wl->window_size); + s[1] = mp_rect_h(wl->window_size); } return VO_TRUE; } @@ -1904,8 +1901,8 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg) int *s = arg; wl->window_size.x0 = 0; wl->window_size.y0 = 0; - wl->window_size.x1 = s[0] / wl->scaling; - wl->window_size.y1 = s[1] / wl->scaling; + wl->window_size.x1 = s[0]; + wl->window_size.y1 = s[1]; if (!wl->vo_opts->fullscreen) { if (wl->vo_opts->window_maximized) { xdg_toplevel_unset_maximized(wl->xdg_toplevel); @@ -2114,7 +2111,6 @@ bool vo_wayland_reconfig(struct vo *vo) } set_geometry(wl); - wl->window_size = wl->vdparams; if (wl->opts->configure_bounds) set_window_bounds(wl); @@ -2141,8 +2137,8 @@ bool vo_wayland_reconfig(struct vo *vo) void vo_wayland_set_opaque_region(struct vo_wayland_state *wl, int alpha) { - const int32_t width = wl->scaling * mp_rect_w(wl->geometry); - const int32_t height = wl->scaling * mp_rect_h(wl->geometry); + const int32_t width = mp_rect_w(wl->geometry); + const int32_t height = mp_rect_h(wl->geometry); if (!alpha) { struct wl_region *region = wl_compositor_create_region(wl->compositor); wl_region_add(region, 0, 0, width, height); diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index 6672dab5c0..c073ae4250 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -48,7 +48,6 @@ struct vo_wayland_state { /* Geometry */ struct mp_rect geometry; - struct mp_rect vdparams; struct mp_rect window_size; struct wl_list output_list; struct vo_wayland_output *current_output;