From 1394ac303e4a7bd02085496645f3c599f349b562 Mon Sep 17 00:00:00 2001 From: Pekka Paalanen Date: Thu, 17 Aug 2017 17:13:08 +0300 Subject: [PATCH] weston: migrate DRM to head-based output API Migrate the DRM frontend to use the simple head-based output configurator, maintaining the exact same features and semantics as before. This is an intermediate step. It is unoptimal to create a weston_output just to turn it off, but the libweston implementation and the DRM backend require it for now. In the future, the DRM frontend will get its own configurator that does not create useless weston_outputs and supports clone mode by attaching multiple heads to the same weston_output. Clone mode is not yet supported by libweston/DRM. Until we remove the need to create a weston_output just to turn it "off", that is, disable it, we will hit simple_head_enable() for heads we have already disabled. As long as the DRM-backend conversion to the head-based API is not complete, attempting to create an output for a head again would lead to a crash. This problem does not exist right now, but it will after the patch "compositor-drm: start migration to head-based output API". Therefore, check if the head we are about to process is already attached, and do nothing if so. DRM outputs set to "off" are the only ones legitimately hitting this condition. This is the last frontend migrated, wet_set_pending_output_handler() is deleted as dead code. v9: - Add the workaround in simple_head_enable(). Signed-off-by: Pekka Paalanen v6 Reviewed-by: Ian Ray v7 Reviewed-by: Daniel Stone Acked-by: Derek Foreman --- compositor/main.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/compositor/main.c b/compositor/main.c index 3885ff6c..9306cb8b 100644 --- a/compositor/main.c +++ b/compositor/main.c @@ -78,7 +78,6 @@ struct wet_head_tracker { struct wet_compositor { struct weston_config *config; struct wet_output_config *parsed_options; - struct wl_listener pending_output_listener; bool drm_use_current_mode; struct wl_listener heads_changed_listener; int (*simple_output_configure)(struct weston_output *output); @@ -361,16 +360,6 @@ to_wet_compositor(struct weston_compositor *compositor) return weston_compositor_get_user_data(compositor); } -static void -wet_set_pending_output_handler(struct weston_compositor *ec, - wl_notify_func_t handler) -{ - struct wet_compositor *compositor = to_wet_compositor(ec); - - compositor->pending_output_listener.notify = handler; - wl_signal_add(&ec->output_pending_signal, &compositor->pending_output_listener); -} - static struct wet_output_config * wet_init_parsed_options(struct weston_compositor *ec) { @@ -1105,6 +1094,12 @@ simple_head_enable(struct weston_compositor *compositor, struct weston_head *hea struct weston_output *output; int ret = 0; + /* Workaround for repeated DRM backend "off" setting. + * For any other case, we should not have an attached head that is not + * enabled. */ + if (weston_head_get_output(head)) + return; + output = weston_compositor_create_output_with_head(compositor, head); if (!output) { weston_log("Could not create an output for head \"%s\".\n", @@ -1125,6 +1120,10 @@ simple_head_enable(struct weston_compositor *compositor, struct weston_head *hea return; } + /* Escape hatch for DRM backend "off" setting. */ + if (ret > 0) + return; + if (weston_output_enable(output) < 0) { weston_log("Enabling output \"%s\" failed.\n", weston_head_get_name(head)); @@ -1218,10 +1217,9 @@ configure_input_device(struct weston_compositor *compositor, } } -static void -drm_backend_output_configure(struct wl_listener *listener, void *data) +static int +drm_backend_output_configure(struct weston_output *output) { - struct weston_output *output = data; struct weston_config *wc = wet_get_config(output->compositor); struct wet_compositor *wet = to_wet_compositor(output->compositor); struct weston_config_section *section; @@ -1236,7 +1234,7 @@ drm_backend_output_configure(struct wl_listener *listener, void *data) if (!api) { weston_log("Cannot use weston_drm_output_api.\n"); - return; + return -1; } section = weston_config_get_section(wc, "output", "name", output->name); @@ -1245,7 +1243,7 @@ drm_backend_output_configure(struct wl_listener *listener, void *data) if (strcmp(s, "off") == 0) { weston_output_disable(output); free(s); - return; + return 1; } else if (wet->drm_use_current_mode || strcmp(s, "current") == 0) { mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT; } else if (strcmp(s, "preferred") != 0) { @@ -1257,7 +1255,7 @@ drm_backend_output_configure(struct wl_listener *listener, void *data) if (api->set_mode(output, mode, modeline) < 0) { weston_log("Cannot configure an output using weston_drm_output_api.\n"); free(modeline); - return; + return -1; } free(modeline); @@ -1275,7 +1273,7 @@ drm_backend_output_configure(struct wl_listener *listener, void *data) api->set_seat(output, seat); free(seat); - weston_output_enable(output); + return 0; } static int @@ -1310,11 +1308,11 @@ load_drm_backend(struct weston_compositor *c, config.base.struct_size = sizeof(struct weston_drm_backend_config); config.configure_device = configure_input_device; + wet_set_simple_head_configurator(c, drm_backend_output_configure); + ret = weston_compositor_load_backend(c, WESTON_BACKEND_DRM, &config.base); - wet_set_pending_output_handler(c, drm_backend_output_configure); - free(config.gbm_format); free(config.seat_id);