diff --git a/video/out/opengl/context_glx.c b/video/out/opengl/context_glx.c index 677260c197..6ca9f19d3e 100644 --- a/video/out/opengl/context_glx.c +++ b/video/out/opengl/context_glx.c @@ -223,6 +223,11 @@ static void update_vsync_oml(struct ra_ctx *ctx) oml_sync_swap(&p->sync, ust, msc, sbc); } +static bool glx_check_visible(struct ra_ctx *ctx) +{ + return vo_x11_check_visible(ctx->vo); +} + static void glx_swap_buffers(struct ra_ctx *ctx) { struct priv *p = ctx->priv; @@ -313,6 +318,7 @@ static bool glx_init(struct ra_ctx *ctx) goto uninit; struct ra_gl_ctx_params params = { + .check_visible = glx_check_visible, .swap_buffers = glx_swap_buffers, .get_vsync = glx_get_vsync, }; diff --git a/video/out/opengl/context_x11egl.c b/video/out/opengl/context_x11egl.c index f1596bcee4..4e0b277da7 100644 --- a/video/out/opengl/context_x11egl.c +++ b/video/out/opengl/context_x11egl.c @@ -75,6 +75,11 @@ static int pick_xrgba_config(void *user_data, EGLConfig *configs, int num_config return 0; } +static bool mpegl_check_visible(struct ra_ctx *ctx) +{ + return vo_x11_check_visible(ctx->vo); +} + static void mpegl_swap_buffers(struct ra_ctx *ctx) { struct priv *p = ctx->priv; @@ -169,6 +174,7 @@ static bool mpegl_init(struct ra_ctx *ctx) mpegl_load_functions(&p->gl, ctx->log); struct ra_gl_ctx_params params = { + .check_visible = mpegl_check_visible, .swap_buffers = mpegl_swap_buffers, .get_vsync = mpegl_get_vsync, }; diff --git a/video/out/vo_x11.c b/video/out/vo_x11.c index 67fac3c9a7..6b7a797412 100644 --- a/video/out/vo_x11.c +++ b/video/out/vo_x11.c @@ -315,6 +315,9 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) struct priv *p = vo->priv; wait_for_completion(vo, 1); + bool render = vo_x11_check_visible(vo); + if (!render) + return; struct mp_image *img = &p->mp_ximages[p->current_buf]; diff --git a/video/out/vo_xv.c b/video/out/vo_xv.c index 43fc046f9f..d93673493f 100644 --- a/video/out/vo_xv.c +++ b/video/out/vo_xv.c @@ -697,6 +697,9 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) struct xvctx *ctx = vo->priv; wait_for_completion(vo, ctx->num_buffers - 1); + bool render = vo_x11_check_visible(vo); + if (!render) + return; struct mp_image xv_buffer = get_xv_buffer(vo, ctx->current_buf); if (mpi) { diff --git a/video/out/vulkan/context_xlib.c b/video/out/vulkan/context_xlib.c index 6278bc3c69..2d498723df 100644 --- a/video/out/vulkan/context_xlib.c +++ b/video/out/vulkan/context_xlib.c @@ -26,6 +26,11 @@ struct priv { struct mpvk_ctx vk; }; +static bool xlib_check_visible(struct ra_ctx *ctx) +{ + return vo_x11_check_visible(ctx->vo); +} + static void xlib_uninit(struct ra_ctx *ctx) { struct priv *p = ctx->priv; @@ -56,7 +61,9 @@ static bool xlib_init(struct ra_ctx *ctx) .window = ctx->vo->x11->window, }; - struct ra_vk_ctx_params params = {0}; + struct ra_vk_ctx_params params = { + .check_visible = xlib_check_visible, + }; VkInstance inst = vk->vkinst->instance; VkResult res = vkCreateXlibSurfaceKHR(inst, &xinfo, NULL, &vk->surface); diff --git a/video/out/x11_common.c b/video/out/x11_common.c index d1fb3b6f0a..d8cda687f8 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -1043,6 +1043,7 @@ static void vo_x11_check_net_wm_state_change(struct vo *vo) } opts->window_minimized = is_minimized; + x11->hidden = is_minimized; m_config_cache_write_opt(x11->opts_cache, &opts->window_minimized); opts->window_maximized = is_maximized; m_config_cache_write_opt(x11->opts_cache, &opts->window_maximized); @@ -1863,6 +1864,14 @@ static void vo_x11_set_geometry(struct vo *vo) } } +bool vo_x11_check_visible(struct vo *vo) { + struct vo_x11_state *x11 = vo->x11; + struct mp_vo_opts *opts = x11->opts; + + bool render = !x11->hidden || VS_IS_DISP(opts->video_sync); + return render; +} + int vo_x11_control(struct vo *vo, int *events, int request, void *arg) { struct vo_x11_state *x11 = vo->x11; diff --git a/video/out/x11_common.h b/video/out/x11_common.h index 45c8d04d21..acc08f2ee0 100644 --- a/video/out/x11_common.h +++ b/video/out/x11_common.h @@ -80,6 +80,7 @@ struct vo_x11_state { Colormap colormap; int wm_type; + bool hidden; // _NET_WM_STATE_HIDDEN bool window_hidden; // the window was mapped at least once bool pseudo_mapped; // not necessarily mapped, but known window size int fs; // whether we assume the window is in fullscreen mode @@ -142,6 +143,7 @@ bool vo_x11_screen_is_composited(struct vo *vo); bool vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, const char *classname); void vo_x11_config_vo_window(struct vo *vo); +bool vo_x11_check_visible(struct vo *vo); int vo_x11_control(struct vo *vo, int *events, int request, void *arg); void vo_x11_wakeup(struct vo *vo); void vo_x11_wait_events(struct vo *vo, int64_t until_time_us);