mirror of
https://github.com/mpv-player/mpv
synced 2025-02-12 09:57:15 +00:00
wayland: correctly handle non-CLOCK_MONOTONIC clocks
The wayland presentation time code currently always assumes that only CLOCK_MONOTONIC can be used. There is a naive attempt to ignore clocks other than CLOCK_MONOTONIC, but the logic is actually totally wrong and the timestamps would be used anyway. Fix this by checking a use_present bool (similar to use_present in xorg) which is set to true if we receive a valid clock in the clockid event. Additionally, allow CLOCK_MONOTONIC_RAW as a valid clockid. In practice, it should be the same as CLOCK_MONOTONIC for us (ntp/adjustime difference wouldn't matter). Since this is a linux-specific clock, add a define for it if it is not found.
This commit is contained in:
parent
7f5541fc3c
commit
d2a0791fe8
@ -101,14 +101,14 @@ static void wayland_egl_swap_buffers(struct ra_ctx *ctx)
|
||||
if (!wl->opts->disable_vsync)
|
||||
vo_wayland_wait_frame(wl);
|
||||
|
||||
if (wl->presentation)
|
||||
if (wl->use_present)
|
||||
present_sync_swap(wl->present);
|
||||
}
|
||||
|
||||
static void wayland_egl_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info)
|
||||
{
|
||||
struct vo_wayland_state *wl = ctx->vo->wl;
|
||||
if (wl->presentation)
|
||||
if (wl->use_present)
|
||||
present_sync_get_info(wl->present, info);
|
||||
}
|
||||
|
||||
|
@ -361,7 +361,7 @@ static void draw_frame(struct vo *vo, struct vo_frame *frame)
|
||||
|
||||
if (!wl->opts->disable_vsync)
|
||||
vo_wayland_wait_frame(wl);
|
||||
if (wl->presentation)
|
||||
if (wl->use_present)
|
||||
present_sync_swap(wl->present);
|
||||
}
|
||||
static void flip_page(struct vo *vo)
|
||||
@ -372,7 +372,7 @@ static void flip_page(struct vo *vo)
|
||||
static void get_vsync(struct vo *vo, struct vo_vsync_info *info)
|
||||
{
|
||||
struct vo_wayland_state *wl = vo->wl;
|
||||
if (wl->presentation)
|
||||
if (wl->use_present)
|
||||
present_sync_get_info(wl->present, info);
|
||||
}
|
||||
|
||||
|
@ -262,14 +262,14 @@ static void flip_page(struct vo *vo)
|
||||
if (!wl->opts->disable_vsync)
|
||||
vo_wayland_wait_frame(wl);
|
||||
|
||||
if (wl->presentation)
|
||||
if (wl->use_present)
|
||||
present_sync_swap(wl->present);
|
||||
}
|
||||
|
||||
static void get_vsync(struct vo *vo, struct vo_vsync_info *info)
|
||||
{
|
||||
struct vo_wayland_state *wl = vo->wl;
|
||||
if (wl->presentation)
|
||||
if (wl->use_present)
|
||||
present_sync_get_info(wl->present, info);
|
||||
}
|
||||
|
||||
|
@ -39,14 +39,14 @@ static void wayland_vk_swap_buffers(struct ra_ctx *ctx)
|
||||
if (!wl->opts->disable_vsync)
|
||||
vo_wayland_wait_frame(wl);
|
||||
|
||||
if (wl->presentation)
|
||||
if (wl->use_present)
|
||||
present_sync_swap(wl->present);
|
||||
}
|
||||
|
||||
static void wayland_vk_get_vsync(struct ra_ctx *ctx, struct vo_vsync_info *info)
|
||||
{
|
||||
struct vo_wayland_state *wl = ctx->vo->wl;
|
||||
if (wl->presentation)
|
||||
if (wl->use_present)
|
||||
present_sync_get_info(wl->present, info);
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,10 @@
|
||||
#define HAVE_WAYLAND_1_20
|
||||
#endif
|
||||
|
||||
#ifndef CLOCK_MONOTONIC_RAW
|
||||
#define CLOCK_MONOTONIC_RAW 4
|
||||
#endif
|
||||
|
||||
|
||||
static const struct mp_keymap keymap[] = {
|
||||
/* Special keys */
|
||||
@ -968,12 +972,12 @@ static const struct zxdg_toplevel_decoration_v1_listener decoration_listener = {
|
||||
};
|
||||
|
||||
static void pres_set_clockid(void *data, struct wp_presentation *pres,
|
||||
uint32_t clockid)
|
||||
uint32_t clockid)
|
||||
{
|
||||
struct vo_wayland_state *wl = data;
|
||||
|
||||
if (clockid == CLOCK_MONOTONIC)
|
||||
wl->presentation = pres;
|
||||
if (clockid == CLOCK_MONOTONIC || clockid == CLOCK_MONOTONIC_RAW)
|
||||
wl->use_present = true;
|
||||
}
|
||||
|
||||
static const struct wp_presentation_listener pres_listener = {
|
||||
@ -996,6 +1000,9 @@ static void feedback_presented(void *data, struct wp_presentation_feedback *fbac
|
||||
if (fback)
|
||||
wp_presentation_feedback_destroy(fback);
|
||||
|
||||
if (!wl->use_present)
|
||||
return;
|
||||
|
||||
wl->refresh_interval = (int64_t)refresh_nsec / 1000;
|
||||
|
||||
// Very similar to oml_sync_control, in this case we assume that every
|
||||
@ -2099,7 +2106,7 @@ void vo_wayland_wait_frame(struct vo_wayland_state *wl)
|
||||
* 3. refresh rate of the output reported by the compositor
|
||||
* 4. make up crap if vblank_time is still <= 0 (better than nothing) */
|
||||
|
||||
if (wl->presentation)
|
||||
if (wl->use_present)
|
||||
vblank_time = wl->present->vsync_duration;
|
||||
|
||||
if (vblank_time <= 0 && wl->refresh_interval > 0)
|
||||
@ -2126,7 +2133,7 @@ void vo_wayland_wait_frame(struct vo_wayland_state *wl)
|
||||
|
||||
/* If the compositor does not have presentation time, we cannot be sure
|
||||
* that this wait is accurate. Do a hacky block with wl_display_roundtrip. */
|
||||
if (!wl->presentation && !wl_display_get_error(wl->display))
|
||||
if (!wl->use_present && !wl_display_get_error(wl->display))
|
||||
wl_display_roundtrip(wl->display);
|
||||
|
||||
if (wl->frame_wait) {
|
||||
|
@ -92,6 +92,7 @@ struct vo_wayland_state {
|
||||
struct wp_presentation_feedback *feedback;
|
||||
struct mp_present *present;
|
||||
int64_t refresh_interval;
|
||||
bool use_present;
|
||||
|
||||
/* xdg-decoration */
|
||||
struct zxdg_decoration_manager_v1 *xdg_decoration_manager;
|
||||
|
Loading…
Reference in New Issue
Block a user