diff --git a/include/libweston/backend-drm.h b/include/libweston/backend-drm.h index f85aabdb..02038e6f 100644 --- a/include/libweston/backend-drm.h +++ b/include/libweston/backend-drm.h @@ -90,7 +90,7 @@ weston_drm_output_get_api(struct weston_compositor *compositor) return (const struct weston_drm_output_api *)api; } -#define WESTON_DRM_VIRTUAL_OUTPUT_API_NAME "weston_drm_virtual_output_api_v1" +#define WESTON_DRM_VIRTUAL_OUTPUT_API_NAME "weston_drm_virtual_output_api_v2" struct drm_fb; typedef int (*submit_frame_cb)(struct weston_output *output, int fd, @@ -101,12 +101,16 @@ struct weston_drm_virtual_output_api { * This is a low-level function, where the caller is expected to wrap * the weston_output function pointers as necessary to make the virtual * output useful. The caller must set up output make, model, serial, - * physical size, the mode list and current mode. + * physical size, the mode list and current mode. The destroy function + * pointer must not be overwritten, as it is used by the DRM backend to + * recognize its outputs. Instead, an auxiliary destroy callback has to + * be provided as a parameter. * * Returns output on success, NULL on failure. */ struct weston_output* (*create_output)(struct weston_compositor *c, - char *name); + char *name, + void (*destroy_func)(struct weston_output *base)); /** Set pixel format same as drm_output set_gbm_format(). * diff --git a/libweston/backend-drm/drm-internal.h b/libweston/backend-drm/drm-internal.h index 107f91e7..77200f2f 100644 --- a/libweston/backend-drm/drm-internal.h +++ b/libweston/backend-drm/drm-internal.h @@ -579,6 +579,7 @@ struct drm_output { struct wl_event_source *pageflip_timer; bool virtual; + void (*virtual_destroy)(struct weston_output *base); submit_frame_cb virtual_submit_frame; }; diff --git a/libweston/backend-drm/drm-virtual.c b/libweston/backend-drm/drm-virtual.c index d2b4c8e3..8f1d3abf 100644 --- a/libweston/backend-drm/drm-virtual.c +++ b/libweston/backend-drm/drm-virtual.c @@ -259,6 +259,9 @@ drm_virtual_output_destroy(struct weston_output *base) drm_output_state_free(output->state_cur); + if (output->virtual_destroy) + output->virtual_destroy(base); + free(output); } @@ -324,7 +327,8 @@ drm_virtual_output_disable(struct weston_output *base) } static struct weston_output * -drm_virtual_output_create(struct weston_compositor *c, char *name) +drm_virtual_output_create(struct weston_compositor *c, char *name, + void (*destroy_func)(struct weston_output *)) { struct drm_output *output; struct drm_backend *b = to_drm_backend(c); @@ -343,6 +347,7 @@ drm_virtual_output_create(struct weston_compositor *c, char *name) } output->virtual = true; + output->virtual_destroy = destroy_func; output->gbm_bo_flags = GBM_BO_USE_LINEAR | GBM_BO_USE_RENDERING; weston_output_init(&output->base, c, name); diff --git a/pipewire/pipewire-plugin.c b/pipewire/pipewire-plugin.c index 23cea2e8..9a913aa3 100644 --- a/pipewire/pipewire-plugin.c +++ b/pipewire/pipewire-plugin.c @@ -67,7 +67,6 @@ struct weston_pipewire { struct pipewire_output { struct weston_output *output; - void (*saved_destroy)(struct weston_output *output); int (*saved_enable)(struct weston_output *output); int (*saved_disable)(struct weston_output *output); int (*saved_start_repaint_loop)(struct weston_output *output); @@ -316,8 +315,6 @@ pipewire_output_destroy(struct weston_output *base_output) free(mode); } - output->saved_destroy(base_output); - pw_stream_destroy(output->stream); wl_list_remove(&output->link); @@ -536,14 +533,12 @@ pipewire_output_create(struct weston_compositor *c, char *name) pw_stream_add_listener(output->stream, &output->stream_listener, &stream_events, output); - output->output = api->create_output(c, name); + output->output = api->create_output(c, name, pipewire_output_destroy); if (!output->output) { weston_log("Cannot create virtual output\n"); goto err; } - output->saved_destroy = output->output->destroy; - output->output->destroy = pipewire_output_destroy; output->saved_enable = output->output->enable; output->output->enable = pipewire_output_enable; output->saved_disable = output->output->disable; diff --git a/remoting/remoting-plugin.c b/remoting/remoting-plugin.c index 7d1d00f4..0af43b5b 100644 --- a/remoting/remoting-plugin.c +++ b/remoting/remoting-plugin.c @@ -95,7 +95,6 @@ static const struct remoted_output_support_gbm_format supported_formats[] = { struct remoted_output { struct weston_output *output; - void (*saved_destroy)(struct weston_output *output); int (*saved_enable)(struct weston_output *output); int (*saved_disable)(struct weston_output *output); int (*saved_start_repaint_loop)(struct weston_output *output); @@ -642,8 +641,6 @@ remoting_output_destroy(struct weston_output *output) free(mode); } - remoted_output->saved_destroy(output); - remoting_gst_pipeline_deinit(remoted_output); remoting_gstpipe_release(&remoted_output->gstpipe); @@ -763,14 +760,12 @@ remoting_output_create(struct weston_compositor *c, char *name) goto err; } - output->output = api->create_output(c, name); + output->output = api->create_output(c, name, remoting_output_destroy); if (!output->output) { weston_log("Can not create virtual output\n"); goto err; } - output->saved_destroy = output->output->destroy; - output->output->destroy = remoting_output_destroy; output->saved_enable = output->output->enable; output->output->enable = remoting_output_enable; output->saved_disable = output->output->disable;