summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
Diffstat (limited to 'video/out')
-rw-r--r--video/out/opengl/context_wayland.c18
-rw-r--r--video/out/vo_wlshm.c10
-rw-r--r--video/out/vulkan/context_wayland.c15
-rw-r--r--video/out/wayland_common.c38
-rw-r--r--video/out/wayland_common.h4
5 files changed, 36 insertions, 49 deletions
diff --git a/video/out/opengl/context_wayland.c b/video/out/opengl/context_wayland.c
index 05c2b6c436..27a9aab32a 100644
--- a/video/out/opengl/context_wayland.c
+++ b/video/out/opengl/context_wayland.c
@@ -63,15 +63,12 @@ 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;
- bool render = !wl->hidden || wl->opts->disable_vsync;
-
- if (wl->frame_wait && wl->presentation)
- vo_wayland_sync_clear(wl);
-
- if (render)
- wl->frame_wait = true;
+ if (!wl->opts->disable_vsync)
+ render = vo_wayland_wait_frame(wl);
+ wl->frame_wait = true;
return render ? ra_gl_ctx_start_frame(sw, out_fbo) : false;
}
@@ -83,16 +80,13 @@ 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);
}
static const struct ra_swapchain_fns wayland_egl_swapchain = {
- .start_frame = wayland_egl_start_frame,
- .swap_buffers = wayland_egl_swap_buffers,
+ .start_frame = wayland_egl_start_frame,
+ .swap_buffers = wayland_egl_swap_buffers,
};
static void wayland_egl_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info)
diff --git a/video/out/vo_wlshm.c b/video/out/vo_wlshm.c
index a71f9507fc..508da4261f 100644
--- a/video/out/vo_wlshm.c
+++ b/video/out/vo_wlshm.c
@@ -218,11 +218,14 @@ 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->hidden)
- return;
+ if (!wl->opts->disable_vsync)
+ callback = vo_wayland_wait_frame(wl);
wl->frame_wait = true;
+ if (!callback)
+ return;
buf = p->free_buffers;
if (buf) {
@@ -274,9 +277,6 @@ 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 8782af5527..d36ab89ed4 100644
--- a/video/out/vulkan/context_wayland.c
+++ b/video/out/vulkan/context_wayland.c
@@ -32,25 +32,18 @@ struct priv {
static bool wayland_vk_start_frame(struct ra_ctx *ctx)
{
struct vo_wayland_state *wl = ctx->vo->wl;
+ bool render = true;
- bool render = !wl->hidden || wl->opts->disable_vsync;
-
- if (wl->frame_wait && wl->presentation)
- vo_wayland_sync_clear(wl);
-
- if (render)
- wl->frame_wait = true;
+ if (!wl->opts->disable_vsync)
+ render = vo_wayland_wait_frame(wl);
+ 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 1902475ead..6075b9a34b 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -1796,13 +1796,6 @@ void vo_wayland_set_opaque_region(struct vo_wayland_state *wl, int alpha)
}
}
-void vo_wayland_sync_clear(struct vo_wayland_state *wl)
-{
- struct vo_wayland_sync sync = {0, 0, 0, 0};
- for (int i = 0; i < wl->sync_size; ++i)
- wl->sync[i] = sync;
-}
-
void vo_wayland_sync_shift(struct vo_wayland_state *wl)
{
for (int i = wl->sync_size - 1; i > 0; --i) {
@@ -1871,7 +1864,7 @@ void vo_wayland_wakeup(struct vo *vo)
(void)write(wl->wakeup_pipe[1], &(char){0}, 1);
}
-void vo_wayland_wait_frame(struct vo_wayland_state *wl)
+bool vo_wayland_wait_frame(struct vo_wayland_state *wl)
{
int64_t vblank_time = 0;
struct pollfd fds[1] = {
@@ -1922,19 +1915,28 @@ void vo_wayland_wait_frame(struct vo_wayland_state *wl)
wl_display_dispatch_pending(wl->display);
}
- if (!wl->hidden && wl->frame_wait) {
- wl->timeout_count += 1;
- if (wl->timeout_count > ((1 / (double)vblank_time) * 1e6))
- wl->hidden = true;
- }
+ /* 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;
+ }
- if (!wl->frame_wait) {
- wl->timeout_count = 0;
- wl->hidden = false;
}
- if (wl_display_get_error(wl->display) == 0)
- wl_display_roundtrip(wl->display);
+ return !wl->frame_wait;
}
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 0414ac6352..948859e79a 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -79,7 +79,6 @@ struct vo_wayland_state {
bool activated;
bool has_keyboard_input;
bool focused;
- bool hidden;
int timeout_count;
int wakeup_pipe[2];
int pending_vo_events;
@@ -153,9 +152,8 @@ 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);
-void vo_wayland_wait_frame(struct vo_wayland_state *wl);
+bool vo_wayland_wait_frame(struct vo_wayland_state *wl);
void vo_wayland_set_opaque_region(struct vo_wayland_state *wl, int alpha);
-void vo_wayland_sync_clear(struct vo_wayland_state *wl);
void wayland_sync_swap(struct vo_wayland_state *wl);
void vo_wayland_sync_shift(struct vo_wayland_state *wl);
void queue_new_sync(struct vo_wayland_state *wl);