wayland: implement `surface-invalidation-v1`

This allows mpv to recover from gpu resets if the compositor supports
the protocol
This commit is contained in:
llyyr 2024-02-24 19:31:54 +05:30
parent cd0031212a
commit a192ae2c4f
5 changed files with 43 additions and 0 deletions

View File

@ -1071,6 +1071,12 @@ void write_video(struct MPContext *mpctx)
struct vo_chain *vo_c = mpctx->vo_chain;
struct vo *vo = vo_c->vo;
if (vo->wants_reinit) {
vo->wants_reinit = false;
mp_force_video_reinit(mpctx);
return;
}
if (vo_c->filter->reconfig_happened) {
mp_notify(mpctx, MPV_EVENT_VIDEO_RECONFIG, NULL);
vo_c->filter->reconfig_happened = false;

View File

@ -25,6 +25,9 @@ if features['wayland-protocols-1-32']
[wl_protocol_dir, 'unstable/tablet/tablet-unstable-v2.xml']] # required by cursor-shape
endif
#TODO: guard this against a version check once the protocol is actually released
protocols += [[wl_protocol_dir, 'staging/surface-invalidation/surface-invalidation-v1.xml']]
foreach p: protocols
xml = join_paths(p)
wl_protocols_source += custom_target(xml.underscorify() + '_c',

View File

@ -489,6 +489,8 @@ struct vo {
bool want_redraw; // redraw as soon as possible
bool wants_reinit; // VO wants to be reinitialized
// current window state
int dwidth;
int dheight;

View File

@ -42,6 +42,7 @@
#include "xdg-decoration-unstable-v1.h"
#include "xdg-shell.h"
#include "viewporter.h"
#include "surface-invalidation-v1.h"
#if HAVE_WAYLAND_PROTOCOLS_1_27
#include "content-type-v1.h"
@ -905,6 +906,21 @@ static const struct wl_output_listener output_listener = {
output_handle_description,
};
static void surface_invalidation_handle_invalidated(void *data,
struct wp_surface_invalidation_v1 *wp_surface_invalidation_v1,
uint32_t serial)
{
struct vo_wayland_state *wl = data;
wp_surface_invalidation_v1_ack(wp_surface_invalidation_v1, serial);
MP_WARN(wl, "Surface invalidated, attempting to reinitialize\n");
wl->vo->wants_reinit = true;
}
static struct wp_surface_invalidation_v1_listener surface_invalidation_listener = {
.invalidated = surface_invalidation_handle_invalidated,
};
static void surface_handle_enter(void *data, struct wl_surface *wl_surface,
struct wl_output *output)
{
@ -1497,6 +1513,12 @@ static void registry_handle_add(void *data, struct wl_registry *reg, uint32_t id
wl->shm = wl_registry_bind(reg, id, &wl_shm_interface, 1);
}
if (!strcmp(interface, wp_surface_invalidation_manager_v1_interface.name) && found++) {
wl->surface_invalidation_manager = wl_registry_bind(reg, id, &wp_surface_invalidation_manager_v1_interface, 1);
wl->surface_invalidation = wp_surface_invalidation_manager_v1_get_surface_invalidation(wl->surface_invalidation_manager, wl->surface);
wp_surface_invalidation_v1_add_listener(wl->surface_invalidation, &surface_invalidation_listener, wl);
}
#if HAVE_WAYLAND_PROTOCOLS_1_27
if (!strcmp(interface, wp_content_type_manager_v1_interface.name) && found++) {
wl->content_type_manager = wl_registry_bind(reg, id, &wp_content_type_manager_v1_interface, 1);
@ -2665,6 +2687,12 @@ void vo_wayland_uninit(struct vo *vo)
if (wl->idle_inhibit_manager)
zwp_idle_inhibit_manager_v1_destroy(wl->idle_inhibit_manager);
if (wl->surface_invalidation)
wp_surface_invalidation_v1_destroy(wl->surface_invalidation);
if (wl->surface_invalidation_manager)
wp_surface_invalidation_manager_v1_destroy(wl->surface_invalidation_manager);
if (wl->presentation)
wp_presentation_destroy(wl->presentation);

View File

@ -122,6 +122,10 @@ struct vo_wayland_state {
/* TODO: unvoid this if required wayland-protocols is bumped to 1.27+ */
void *single_pixel_manager;
/* surface-invalidation */
struct wp_surface_invalidation_manager_v1 *surface_invalidation_manager;
struct wp_surface_invalidation_v1 *surface_invalidation;
/* xdg-decoration */
struct zxdg_decoration_manager_v1 *xdg_decoration_manager;
struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration;