mirror of
https://github.com/mpv-player/mpv
synced 2025-01-05 14:40:43 +00:00
wayland: be less strict about when to render
efb0c5c
changed the rendering logic of mpv on wayland and made it skip
rendering when it did not receive frame callback in time. The idea was
to skip rendering when the surface was hidden and be less wasteful. This
unfortunately had issues in certain instances where a frame callback
could be missed (but the window was still in view) due to imprecise
rendering (like the default audio video-sync mode). This would lead to
the video appearing to stutter since mpv would skip rendering in those
cases.
To account for this case, simply re-add an old heuristic for detecting
if a window is hidden or not since the goal is to simply not render when
a window is hidden. If the wait on the frame callback times out enough
times in a row, then we consider the window hidden and thus begin to
skip rendering then. The actual threshold to consider a surface as
hidden is completely arbitrary (greater than your monitor's refresh
rate), but it's safe enough since realistically you're not going to miss
60+ frame callbacks in a row unless the surface actually is hidden.
Fixes #8169.
This commit is contained in:
parent
cfead22b80
commit
deaea70630
@ -145,7 +145,7 @@ 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 = !wl->frame_wait || wl->opts->disable_vsync;
|
||||
bool render = !wl->hidden || wl->opts->disable_vsync;
|
||||
|
||||
if (wl->frame_wait && wl->presentation)
|
||||
vo_wayland_sync_clear(wl);
|
||||
|
@ -248,7 +248,7 @@ static void draw_image(struct vo *vo, struct mp_image *src)
|
||||
struct vo_wayland_state *wl = vo->wl;
|
||||
struct buffer *buf;
|
||||
|
||||
if (wl->frame_wait)
|
||||
if (wl->hidden)
|
||||
return;
|
||||
|
||||
wl->frame_wait = true;
|
||||
|
@ -106,7 +106,7 @@ static bool wayland_vk_start_frame(struct ra_ctx *ctx)
|
||||
{
|
||||
struct vo_wayland_state *wl = ctx->vo->wl;
|
||||
|
||||
bool render = !wl->frame_wait || wl->opts->disable_vsync;
|
||||
bool render = !wl->hidden || wl->opts->disable_vsync;
|
||||
|
||||
if (wl->frame_wait && wl->presentation)
|
||||
vo_wayland_sync_clear(wl);
|
||||
|
@ -1717,6 +1717,17 @@ 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 > wl->current_output->refresh_rate)
|
||||
wl->hidden = 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);
|
||||
}
|
||||
|
@ -79,6 +79,8 @@ 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;
|
||||
int mouse_x;
|
||||
|
Loading…
Reference in New Issue
Block a user