diff options
author | Rostislav Pehlivanov <atomnuker@gmail.com> | 2016-05-30 18:34:31 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-05-30 20:17:26 +0200 |
commit | 098ff4174c6c9cc59e65c6f09b23b3adaee03983 (patch) | |
tree | ac5c85fcb7519e6d394df6367a3422bd2652c553 /video/out/vo_wayland.c | |
parent | 9009601c2d3b2a6d7806d63346c900e0a4c9e2ca (diff) | |
download | mpv-098ff4174c6c9cc59e65c6f09b23b3adaee03983.tar.bz2 mpv-098ff4174c6c9cc59e65c6f09b23b3adaee03983.tar.xz |
wayland: implement HIDPI support
The wayland protocol exposes scaling done by the compositor to
compensate for small window sizes on small high DPI displays. If the
program ignores the scaling done, what'll happen is the compositor is
going to ask the program to be scaled down by N times the window size and
then it'll upscale the program's surface by N times. The scaling
algorithm seems to be bilinear so the scaling is quite obvious.
This commit sets up callbacks to listen for the scaling factor of each
output and, on rescale events, notifies the compositor that the
surface's scale is what the compositor asked for and changes the
player's surface to the appropriate size, causing no scaling to be done
by the compositor.
Compositors not supporting this interface will ignore the callbacks and do
nothing, keeping program behaviour the same. For compositors supporting
and using this interface (mutter), this will fix the rendering to be pixel
precise as it should be.
Both the opengl wayland backend and the wayland vo have been fixed to support
this. Verified to not break either on weston and mutter.
Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
Diffstat (limited to 'video/out/vo_wayland.c')
-rw-r--r-- | video/out/vo_wayland.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/video/out/vo_wayland.c b/video/out/vo_wayland.c index 57d6c7f8b8..2997b38cde 100644 --- a/video/out/vo_wayland.c +++ b/video/out/vo_wayland.c @@ -249,10 +249,15 @@ static bool resize(struct priv *p) if (!p->video_bufpool.back_buffer || SHM_BUFFER_IS_BUSY(p->video_bufpool.back_buffer)) return false; // skip resizing if we can't guarantee pixel perfectness! + int32_t scale = 1; int32_t x = wl->window.sh_x; int32_t y = wl->window.sh_y; - wl->vo->dwidth = wl->window.sh_width; - wl->vo->dheight = wl->window.sh_height; + + if (wl->display.current_output) + scale = wl->display.current_output->scale; + + wl->vo->dwidth = scale*wl->window.sh_width; + wl->vo->dheight = scale*wl->window.sh_height; vo_get_src_dst_rects(p->vo, &p->src, &p->dst, &p->osd); p->src_w = p->src.x1 - p->src.x0; @@ -273,6 +278,7 @@ static bool resize(struct priv *p) if (y != 0) y = wl->window.height - p->dst_h; + wl_surface_set_buffer_scale(wl->window.video_surface, scale); mp_sws_set_from_cmdline(p->sws, p->vo->opts->sws_opts); p->sws->src = p->in_format; p->sws->dst = (struct mp_image_params) { @@ -301,7 +307,7 @@ static bool resize(struct priv *p) if (!p->enable_alpha) { struct wl_region *opaque = wl_compositor_create_region(wl->display.compositor); - wl_region_add(opaque, 0, 0, p->dst_w, p->dst_h); + wl_region_add(opaque, 0, 0, p->dst_w/scale, p->dst_h/scale); wl_surface_set_opaque_region(wl->window.video_surface, opaque); wl_region_destroy(opaque); } @@ -464,14 +470,19 @@ static const bool osd_formats[SUBBITMAP_COUNT] = { static void draw_osd(struct vo *vo) { + int32_t scale = 1; struct priv *p = vo->priv; + if (p->wl && p->wl->display.current_output) + scale = p->wl->display.current_output->scale; + // detach all buffers and attach all needed buffers in osd_draw // only the most recent attach & commit is applied once the parent surface // is committed for (int i = 0; i < MAX_OSD_PARTS; ++i) { struct wl_surface *s = p->osd_surfaces[i]; wl_surface_attach(s, NULL, 0, 0); + wl_surface_set_buffer_scale(s, scale); wl_surface_damage(s, 0, 0, p->dst_w, p->dst_h); wl_surface_commit(s); } |