summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDudemanguy <random342@airmail.cc>2024-01-20 12:41:11 -0600
committerDudemanguy <random342@airmail.cc>2024-01-27 05:12:12 +0000
commite32554cd570d984efb712a7214a40237233a3cea (patch)
treef392ed4372179f0053df75d90b4ea6aa10dc6621
parent99d387bbc81e36f60da26d63b96736e2461bcd2e (diff)
downloadmpv-e32554cd570d984efb712a7214a40237233a3cea.tar.bz2
mpv-e32554cd570d984efb712a7214a40237233a3cea.tar.xz
wayland: drop buffer_scale use for viewporter
The core wayland protocol way of handling scaling is to use the buffer_scale mechanism. But this sucks in several ways for reasons I won't list here and fractional scaling rightly avoids this altogether and uses a buffer_scale of 1 (i.e. not setting it) along with viewporter. When originally implemented, this was only specifically used when the fractional scale protocol was available, but we actually can use it as a full replacement instead. This means that mpv now hard requires viewporter, but this protocol is supported by everyone and is one of the few that is actually stable. How it works is the same regardless of fractional scaling or not. When the compositor has a scale value not equal to 1, it will always scale the client by that factor (unless you set buffer_scale). What we do here is pass a viewporter size that exactly undos the compositor-side scale (sans a possible rounding error). So what we are left with is just the exactly physical pixels we want to display. Fixes #13316.
-rw-r--r--video/out/opengl/context_wayland.c4
-rw-r--r--video/out/vo_dmabuf_wayland.c6
-rw-r--r--video/out/vo_wlshm.c2
-rw-r--r--video/out/vulkan/context_wayland.c2
-rw-r--r--video/out/wayland_common.c35
-rw-r--r--video/out/wayland_common.h2
6 files changed, 23 insertions, 28 deletions
diff --git a/video/out/opengl/context_wayland.c b/video/out/opengl/context_wayland.c
index 26c52688d3..2c5611b2e6 100644
--- a/video/out/opengl/context_wayland.c
+++ b/video/out/opengl/context_wayland.c
@@ -47,14 +47,14 @@ static void resize(struct ra_ctx *ctx)
const int32_t width = mp_rect_w(wl->geometry);
const int32_t height = mp_rect_h(wl->geometry);
+ vo_wayland_handle_scale(wl);
+
vo_wayland_set_opaque_region(wl, ctx->opts.want_alpha);
if (p->egl_window)
wl_egl_window_resize(p->egl_window, width, height, 0, 0);
wl->vo->dwidth = width;
wl->vo->dheight = height;
-
- vo_wayland_handle_fractional_scale(wl);
}
static bool wayland_egl_check_visible(struct ra_ctx *ctx)
diff --git a/video/out/vo_dmabuf_wayland.c b/video/out/vo_dmabuf_wayland.c
index 3052046935..3b8190e18e 100644
--- a/video/out/vo_dmabuf_wayland.c
+++ b/video/out/vo_dmabuf_wayland.c
@@ -781,12 +781,6 @@ static int preinit(struct vo *vo)
goto err;
}
- if (!vo->wl->viewport) {
- MP_FATAL(vo->wl, "Compositor doesn't support the %s protocol!\n",
- wp_viewporter_interface.name);
- 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 1e5e009bc7..0a64e6ccb2 100644
--- a/video/out/vo_wlshm.c
+++ b/video/out/vo_wlshm.c
@@ -209,7 +209,7 @@ static int resize(struct vo *vo)
talloc_free(buf);
}
- vo_wayland_handle_fractional_scale(wl);
+ vo_wayland_handle_scale(wl);
return mp_sws_reinit(p->sws);
}
diff --git a/video/out/vulkan/context_wayland.c b/video/out/vulkan/context_wayland.c
index 761ff5b12c..cdf1ba60b8 100644
--- a/video/out/vulkan/context_wayland.c
+++ b/video/out/vulkan/context_wayland.c
@@ -118,7 +118,7 @@ static bool resize(struct ra_ctx *ctx)
const int32_t height = mp_rect_h(wl->geometry);
vo_wayland_set_opaque_region(wl, ctx->opts.want_alpha);
- vo_wayland_handle_fractional_scale(wl);
+ vo_wayland_handle_scale(wl);
return ra_vk_ctx_resize(ctx, width, height);
}
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index cf4fb8a574..b8c5e00997 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -1012,13 +1012,13 @@ 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 = round(width * wl->scaling);
- wl->window_size.y1 = round(height * wl->scaling);
+ wl->window_size.x1 = lround(width * wl->scaling);
+ wl->window_size.y1 = lround(height * wl->scaling);
}
wl->geometry.x0 = 0;
wl->geometry.y0 = 0;
- wl->geometry.x1 = round(width * wl->scaling);
- wl->geometry.y1 = round(height * wl->scaling);
+ wl->geometry.x1 = lround(width * wl->scaling);
+ wl->geometry.y1 = lround(height * wl->scaling);
if (mp_rect_equals(&old_geometry, &wl->geometry))
return;
@@ -1500,13 +1500,11 @@ static bool create_input(struct vo_wayland_state *wl)
static int create_viewports(struct vo_wayland_state *wl)
{
- if (wl->viewporter) {
- wl->viewport = wp_viewporter_get_viewport(wl->viewporter, wl->surface);
- wl->osd_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->osd_surface);
- wl->video_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->video_surface);
- }
+ wl->viewport = wp_viewporter_get_viewport(wl->viewporter, wl->surface);
+ wl->osd_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->osd_surface);
+ wl->video_viewport = wp_viewporter_get_viewport(wl->viewporter, wl->video_surface);
- if (wl->viewporter && (!wl->viewport || !wl->osd_viewport || !wl->video_viewport)) {
+ if (!wl->viewport || !wl->osd_viewport || !wl->video_viewport) {
MP_ERR(wl, "failed to create viewport interfaces!\n");
return 1;
}
@@ -1847,9 +1845,7 @@ static void set_surface_scaling(struct vo_wayland_state *wl)
// dmabuf_wayland is always wl->scaling = 1
double old_scale = wl->scaling;
wl->scaling = !wl->using_dmabuf_wayland ? wl->current_output->scale : 1;
-
rescale_geometry(wl, old_scale);
- wl_surface_set_buffer_scale(wl->surface, wl->scaling);
}
static void set_window_bounds(struct vo_wayland_state *wl)
@@ -2182,12 +2178,11 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg)
return VO_NOTIMPL;
}
-void vo_wayland_handle_fractional_scale(struct vo_wayland_state *wl)
+void vo_wayland_handle_scale(struct vo_wayland_state *wl)
{
- if (wl->fractional_scale_manager && wl->viewport)
- wp_viewport_set_destination(wl->viewport,
- round(mp_rect_w(wl->geometry) / wl->scaling),
- round(mp_rect_h(wl->geometry) / wl->scaling));
+ wp_viewport_set_destination(wl->viewport,
+ lround(mp_rect_w(wl->geometry) / wl->scaling),
+ lround(mp_rect_h(wl->geometry) / wl->scaling));
}
bool vo_wayland_init(struct vo *vo)
@@ -2244,6 +2239,12 @@ bool vo_wayland_init(struct vo *vo)
goto err;
}
+ if (!wl->viewporter) {
+ MP_FATAL(wl, "Compositor doesn't support the required %s protocol!\n",
+ wp_viewporter_interface.name);
+ goto err;
+ }
+
/* Can't be initialized during registry due to multi-protocol dependence */
if (create_viewports(wl))
goto err;
diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h
index adbcca63b2..b6f951995b 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -178,7 +178,7 @@ bool vo_wayland_reconfig(struct vo *vo);
int vo_wayland_allocate_memfd(struct vo *vo, size_t size);
int vo_wayland_control(struct vo *vo, int *events, int request, void *arg);
-void vo_wayland_handle_fractional_scale(struct vo_wayland_state *wl);
+void vo_wayland_handle_scale(struct vo_wayland_state *wl);
void vo_wayland_set_opaque_region(struct vo_wayland_state *wl, bool alpha);
void vo_wayland_sync_swap(struct vo_wayland_state *wl);
void vo_wayland_uninit(struct vo *vo);