diff --git a/video/out/opengl/context_wayland.c b/video/out/opengl/context_wayland.c index 27a9aab32a..eeaeb11cc1 100644 --- a/video/out/opengl/context_wayland.c +++ b/video/out/opengl/context_wayland.c @@ -63,12 +63,9 @@ static bool wayland_egl_start_frame(struct ra_swapchain *sw, struct ra_fbo *out_ { struct ra_ctx *ctx = sw->ctx; struct vo_wayland_state *wl = ctx->vo->wl; - bool render = true; - - if (!wl->opts->disable_vsync) - render = vo_wayland_wait_frame(wl); - + bool render = wl->render || wl->opts->disable_vsync; wl->frame_wait = true; + return render ? ra_gl_ctx_start_frame(sw, out_fbo) : false; } @@ -80,6 +77,9 @@ static void wayland_egl_swap_buffers(struct ra_swapchain *sw) eglSwapBuffers(p->egl_display, p->egl_surface); + if (!wl->opts->disable_vsync) + vo_wayland_wait_frame(wl); + if (wl->presentation) wayland_sync_swap(wl); } diff --git a/video/out/vo_wlshm.c b/video/out/vo_wlshm.c index 508da4261f..69cfdd9dcc 100644 --- a/video/out/vo_wlshm.c +++ b/video/out/vo_wlshm.c @@ -218,13 +218,10 @@ static void draw_image(struct vo *vo, struct mp_image *src) struct priv *p = vo->priv; struct vo_wayland_state *wl = vo->wl; struct buffer *buf; - bool callback = true; - - if (!wl->opts->disable_vsync) - callback = vo_wayland_wait_frame(wl); - + bool render = wl->render || wl->opts->disable_vsync; wl->frame_wait = true; - if (!callback) + + if (!render) return; buf = p->free_buffers; @@ -277,6 +274,9 @@ static void flip_page(struct vo *vo) mp_rect_h(wl->geometry)); wl_surface_commit(wl->surface); + if (!wl->opts->disable_vsync) + vo_wayland_wait_frame(wl); + if (wl->presentation) wayland_sync_swap(wl); } diff --git a/video/out/vulkan/context_wayland.c b/video/out/vulkan/context_wayland.c index d36ab89ed4..d711a855c4 100644 --- a/video/out/vulkan/context_wayland.c +++ b/video/out/vulkan/context_wayland.c @@ -32,18 +32,19 @@ struct priv { static bool wayland_vk_start_frame(struct ra_ctx *ctx) { struct vo_wayland_state *wl = ctx->vo->wl; - bool render = true; - - if (!wl->opts->disable_vsync) - render = vo_wayland_wait_frame(wl); - + bool render = wl->render || wl->opts->disable_vsync; wl->frame_wait = true; + return render; } static void wayland_vk_swap_buffers(struct ra_ctx *ctx) { struct vo_wayland_state *wl = ctx->vo->wl; + + if (!wl->opts->disable_vsync) + vo_wayland_wait_frame(wl); + if (wl->presentation) wayland_sync_swap(wl); } diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 2c0569a83b..3dcc9641e8 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -1865,7 +1865,7 @@ void vo_wayland_wakeup(struct vo *vo) (void)write(wl->wakeup_pipe[1], &(char){0}, 1); } -bool vo_wayland_wait_frame(struct vo_wayland_state *wl) +void vo_wayland_wait_frame(struct vo_wayland_state *wl) { int64_t vblank_time = 0; struct pollfd fds[1] = { @@ -1917,27 +1917,25 @@ bool vo_wayland_wait_frame(struct vo_wayland_state *wl) } /* If the compositor does not have presentatiom time, we cannot be sure - * that this wait is accurate. Do some crap with wl_display_roundtrip - * and randomly assume that if timeouts > refresh rate, the window is - * hidden. This is neccesary otherwise we may mistakeningly skip rendering.*/ - if (!wl->presentation) { - if (wl_display_get_error(wl->display) == 0) - wl_display_roundtrip(wl->display); - if (wl->frame_wait) { - if (wl->timeout_count > ((1 / (double)vblank_time) * 1e6)) { - return false; - } else { - wl->timeout_count += 1; - return true; - } - } else { - wl->timeout_count = 0; - return true; - } + * that this wait is accurate. Do a hacky block with wl_display_roundtrip. */ + if (!wl->presentation && !wl_display_get_error(wl->display)) + wl_display_roundtrip(wl->display); + if (wl->frame_wait) { + // Only consider consecutive missed callbacks. + if (wl->timeout_count > 1) { + wl->render = false; + return; + } else { + wl->timeout_count += 1; + wl->render = true; + return; + } } - return !wl->frame_wait; + wl->timeout_count = 0; + wl->render = true; + return; } void vo_wayland_wait_events(struct vo *vo, int64_t until_time_us) diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index 948859e79a..bbdfdf82d2 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -74,6 +74,7 @@ struct vo_wayland_state { int reduced_width; int reduced_height; bool frame_wait; + bool render; bool state_change; bool toplevel_configured; bool activated; @@ -152,7 +153,7 @@ int last_available_sync(struct vo_wayland_state *wl); void vo_wayland_uninit(struct vo *vo); void vo_wayland_wakeup(struct vo *vo); void vo_wayland_wait_events(struct vo *vo, int64_t until_time_us); -bool vo_wayland_wait_frame(struct vo_wayland_state *wl); +void vo_wayland_wait_frame(struct vo_wayland_state *wl); void vo_wayland_set_opaque_region(struct vo_wayland_state *wl, int alpha); void wayland_sync_swap(struct vo_wayland_state *wl); void vo_wayland_sync_shift(struct vo_wayland_state *wl);