summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/out/opengl/context_wayland.c64
-rw-r--r--video/out/vulkan/context_wayland.c57
-rw-r--r--video/out/wayland_common.c7
-rw-r--r--video/out/wayland_common.h1
4 files changed, 68 insertions, 61 deletions
diff --git a/video/out/opengl/context_wayland.c b/video/out/opengl/context_wayland.c
index 6f14305859..11df19da8c 100644
--- a/video/out/opengl/context_wayland.c
+++ b/video/out/opengl/context_wayland.c
@@ -39,24 +39,6 @@ struct priv {
struct wl_egl_window *egl_window;
};
-static const struct wl_callback_listener frame_listener;
-
-static void frame_callback(void *data, struct wl_callback *callback, uint32_t time)
-{
- struct vo_wayland_state *wl = data;
-
- if (callback)
- wl_callback_destroy(callback);
-
- wl->frame_callback = wl_surface_frame(wl->surface);
- wl_callback_add_listener(wl->frame_callback, &frame_listener, wl);
- wl->frame_wait = false;
-}
-
-static const struct wl_callback_listener frame_listener = {
- frame_callback,
-};
-
static const struct wp_presentation_feedback_listener feedback_listener;
static void feedback_sync_output(void *data, struct wp_presentation_feedback *fback,
@@ -71,9 +53,11 @@ static void feedback_presented(void *data, struct wp_presentation_feedback *fbac
uint32_t flags)
{
struct vo_wayland_state *wl = data;
- wp_presentation_feedback_destroy(fback);
vo_wayland_sync_shift(wl);
+ if (fback)
+ wp_presentation_feedback_destroy(fback);
+
// Very similar to oml_sync_control, in this case we assume that every
// time the compositor receives feedback, a buffer swap has been already
// been performed.
@@ -93,11 +77,13 @@ static void feedback_presented(void *data, struct wp_presentation_feedback *fbac
wl->sync[index].ust = sec * 1000000LL + (uint64_t) tv_nsec / 1000;
wl->sync[index].msc = (uint64_t) seq_lo + ((uint64_t) seq_hi << 32);
wl->sync[index].filled = true;
+ wl->presentation_discarded = false;
}
static void feedback_discarded(void *data, struct wp_presentation_feedback *fback)
{
- wp_presentation_feedback_destroy(fback);
+ struct vo_wayland_state *wl = data;
+ wl->presentation_discarded = true;
}
static const struct wp_presentation_feedback_listener feedback_listener = {
@@ -106,6 +92,30 @@ static const struct wp_presentation_feedback_listener feedback_listener = {
feedback_discarded,
};
+static const struct wl_callback_listener frame_listener;
+
+static void frame_callback(void *data, struct wl_callback *callback, uint32_t time)
+{
+ struct vo_wayland_state *wl = data;
+
+ if (callback)
+ wl_callback_destroy(callback);
+
+ wl->frame_callback = wl_surface_frame(wl->surface);
+ wl_callback_add_listener(wl->frame_callback, &frame_listener, wl);
+
+ if (wl->presentation) {
+ wl->feedback = wp_presentation_feedback(wl->presentation, wl->surface);
+ wp_presentation_feedback_add_listener(wl->feedback, &feedback_listener, wl);
+ }
+
+ wl->frame_wait = false;
+}
+
+static const struct wl_callback_listener frame_listener = {
+ frame_callback,
+};
+
static void resize(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
@@ -130,21 +140,15 @@ static void wayland_egl_swap_buffers(struct ra_ctx *ctx)
struct priv *p = ctx->priv;
struct vo_wayland_state *wl = ctx->vo->wl;
- if (wl->presentation) {
- wl->feedback = wp_presentation_feedback(wl->presentation, wl->surface);
- wp_presentation_feedback_add_listener(wl->feedback, &feedback_listener, wl);
- wl->user_sbc += 1;
- int index = last_available_sync(wl);
- if (index < 0)
- queue_new_sync(wl);
- }
-
eglSwapBuffers(p->egl_display, p->egl_surface);
+
if (!wl->opts->disable_vsync)
vo_wayland_wait_frame(wl);
- if (wl->presentation)
+ if (wl->presentation) {
+ wl->user_sbc += 1;
wayland_sync_swap(wl);
+ }
wl->frame_wait = true;
}
diff --git a/video/out/vulkan/context_wayland.c b/video/out/vulkan/context_wayland.c
index fa5994d280..faac07cdcb 100644
--- a/video/out/vulkan/context_wayland.c
+++ b/video/out/vulkan/context_wayland.c
@@ -29,24 +29,6 @@ struct priv {
struct mpvk_ctx vk;
};
-static const struct wl_callback_listener frame_listener;
-
-static void frame_callback(void *data, struct wl_callback *callback, uint32_t time)
-{
- struct vo_wayland_state *wl = data;
-
- if (callback)
- wl_callback_destroy(callback);
-
- wl->frame_callback = wl_surface_frame(wl->surface);
- wl_callback_add_listener(wl->frame_callback, &frame_listener, wl);
- wl->frame_wait = false;
-}
-
-static const struct wl_callback_listener frame_listener = {
- frame_callback,
-};
-
static const struct wp_presentation_feedback_listener feedback_listener;
static void feedback_sync_output(void *data, struct wp_presentation_feedback *fback,
@@ -61,9 +43,11 @@ static void feedback_presented(void *data, struct wp_presentation_feedback *fbac
uint32_t flags)
{
struct vo_wayland_state *wl = data;
- wp_presentation_feedback_destroy(fback);
vo_wayland_sync_shift(wl);
+ if (fback)
+ wp_presentation_feedback_destroy(fback);
+
// Very similar to oml_sync_control, in this case we assume that every
// time the compositor receives feedback, a buffer swap has been already
// been performed.
@@ -83,11 +67,13 @@ static void feedback_presented(void *data, struct wp_presentation_feedback *fbac
wl->sync[index].ust = sec * 1000000LL + (uint64_t) tv_nsec / 1000;
wl->sync[index].msc = (uint64_t) seq_lo + ((uint64_t) seq_hi << 32);
wl->sync[index].filled = true;
+ wl->presentation_discarded = false;
}
static void feedback_discarded(void *data, struct wp_presentation_feedback *fback)
{
- wp_presentation_feedback_destroy(fback);
+ struct vo_wayland_state *wl = data;
+ wl->presentation_discarded = true;
}
static const struct wp_presentation_feedback_listener feedback_listener = {
@@ -96,24 +82,41 @@ static const struct wp_presentation_feedback_listener feedback_listener = {
feedback_discarded,
};
-static void wayland_vk_swap_buffers(struct ra_ctx *ctx)
+static const struct wl_callback_listener frame_listener;
+
+static void frame_callback(void *data, struct wl_callback *callback, uint32_t time)
{
- struct vo_wayland_state *wl = ctx->vo->wl;
+ struct vo_wayland_state *wl = data;
+
+ if (callback)
+ wl_callback_destroy(callback);
+
+ wl->frame_callback = wl_surface_frame(wl->surface);
+ wl_callback_add_listener(wl->frame_callback, &frame_listener, wl);
if (wl->presentation) {
wl->feedback = wp_presentation_feedback(wl->presentation, wl->surface);
wp_presentation_feedback_add_listener(wl->feedback, &feedback_listener, wl);
- wl->user_sbc += 1;
- int index = last_available_sync(wl);
- if (index < 0)
- queue_new_sync(wl);
}
+ wl->frame_wait = false;
+}
+
+static const struct wl_callback_listener frame_listener = {
+ frame_callback,
+};
+
+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)
+ if (wl->presentation) {
+ wl->user_sbc += 1;
wayland_sync_swap(wl);
+ }
wl->frame_wait = true;
}
diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c
index 99aa8ee018..993c7b0e54 100644
--- a/video/out/wayland_common.c
+++ b/video/out/wayland_common.c
@@ -1607,10 +1607,9 @@ void wayland_sync_swap(struct vo_wayland_state *wl)
wl->last_skipped_vsyncs = 0;
- // If these are the same, presentation feedback has not been received.
- // This will happen if the window is obscured/hidden in some way. Update
- // the values based on the difference in mp_time.
- if (wl->sync[index].ust == wl->last_ust && wl->last_ust) {
+ // If the presentation event was discarded, update the values based on
+ // the difference in mp_time.
+ if (wl->presentation_discarded) {
wl->sync[index].ust += mp_time - wl->sync[index].last_mp_time;
wl->sync[index].msc += 1;
wl->sync[index].sbc += 1;
diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h
index 895db3393d..7bfe0e85e0 100644
--- a/video/out/wayland_common.h
+++ b/video/out/wayland_common.h
@@ -107,6 +107,7 @@ struct vo_wayland_state {
/* Presentation Feedback */
struct vo_wayland_sync *sync;
int sync_size;
+ bool presentation_discarded;
int64_t user_sbc;
int64_t last_ust;
int64_t last_msc;