EXT: [PATCH weston v6 37/73] compositor-wayland: migrate to head-based output API

Ray, Ian (GE Healthcare) ian.ray at ge.com
Sat Mar 24 10:13:48 UTC 2018


> On 16 Feb 2018, at 16.57, Pekka Paalanen <ppaalanen at gmail.com> wrote:
> 
> From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
> 
> Follow the standard pattern used in the headless and x11 backend
> migration, but also cater for the two other backend modes: --sprawl or
> fullscreen-shell, and --fullscreen.
> 
> Stops relying on the implicit weston_output::head.
> 
> Unlike other backends, this uses the attach_head hook to do the
> required head setup that is not possible to do without an output, but
> must be done before weston_output_enable(). This also requires the
> detach_head hook for the one case where the user attaches a --fullscreen
> head and then detaches it without enabling the output.
> 
> It is a little awkward to fully initialize heads as late as attach, but
> aside from the --sprawl/fullscreen-shell case, there is not really a way
> to know the head properties without creating the parent wl_surface and
> configuring it.
> 
> Heads/outputs created for parent outputs now have distinct names instead
> of all being called "wlparent".
> 
> Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
> ---
> libweston/compositor-wayland.c | 239 ++++++++++++++++++++++++++++++-----------
> 1 file changed, 178 insertions(+), 61 deletions(-)
> 
> diff --git a/libweston/compositor-wayland.c b/libweston/compositor-wayland.c
> index cf4a5f3f..455d94a0 100644
> --- a/libweston/compositor-wayland.c
> +++ b/libweston/compositor-wayland.c
> @@ -137,7 +137,7 @@ struct wayland_output {
> 
> struct wayland_parent_output {
> 	struct wayland_backend *backend;	/**< convenience */
> -	struct wayland_output *output;
> +	struct wayland_head *head;
> 	struct wl_list link;
> 
> 	struct wl_output *global;
> @@ -161,6 +161,11 @@ struct wayland_parent_output {
> 	struct weston_mode *current_mode;
> };
> 
> +struct wayland_head {
> +	struct weston_head base;
> +	struct wayland_parent_output *parent_output;
> +};
> +
> struct wayland_shm_buffer {
> 	struct wayland_output *output;
> 	struct wl_list link;
> @@ -210,6 +215,12 @@ struct wayland_input {
> 
> struct gl_renderer_interface *gl_renderer;
> 
> +static inline struct wayland_head *
> +to_wayland_head(struct weston_head *base)
> +{
> +	return container_of(base, struct wayland_head, base);
> +}
> +
> static inline struct wayland_output *
> to_wayland_output(struct weston_output *base)
> {
> @@ -1275,9 +1286,59 @@ err_output:
> 	return -1;
> }
> 
> -static struct wayland_output *
> -wayland_output_create_common(struct weston_compositor *compositor,
> -			     const char *name)
> +static int
> +wayland_output_setup_for_parent_output(struct wayland_output *output,
> +				       struct wayland_parent_output *poutput);
> +
> +static int
> +wayland_output_setup_fullscreen(struct wayland_output *output,
> +				struct wayland_head *head);
> +
> +static int
> +wayland_output_attach_head(struct weston_output *output_base,
> +			   struct weston_head *head_base)
> +{
> +	struct wayland_backend *b = to_wayland_backend(output_base->compositor);
> +	struct wayland_output *output = to_wayland_output(output_base);
> +	struct wayland_head *head = to_wayland_head(head_base);
> +
> +	if (!wl_list_empty(&output->base.head_list))
> +		return -1;
> +
> +	if (head->parent_output) {
> +		if (wayland_output_setup_for_parent_output(output,
> +							   head->parent_output) < 0)
> +			return -1;
> +	} else if (b->fullscreen) {
> +		if (wayland_output_setup_fullscreen(output, head) < 0)
> +			return -1;
> +	} else {
> +		/* A floating window, nothing to do. */
> +	}
> +
> +	return 0;
> +}
> +
> +static void
> +wayland_output_detach_head(struct weston_output *output_base,
> +			   struct weston_head *head)

Nit: head unused.  (GCC_CFLAGS contains `-Wno-unused-parameter' so
presumably I should not report similar occurrences?)


> +{
> +	struct wayland_output *output = to_wayland_output(output_base);
> +
> +	/* Rely on the disable hook if the output was enabled. We do not
> +	 * support cloned heads, so detaching is guaranteed to disable the
> +	 * output.
> +	 */
> +	if (output->base.enabled)
> +		return;
> +
> +	/* undo setup fullscreen */
> +	if (output->parent.surface)
> +		wayland_backend_destroy_output_surface(output);
> +}
> +
> +static struct weston_output *
> +wayland_output_create(struct weston_compositor *compositor, const char *name)
> {
> 	struct wayland_output *output;
> 	char *title;
> @@ -1302,29 +1363,87 @@ wayland_output_create_common(struct weston_compositor *compositor,
> 	output->base.destroy = wayland_output_destroy;
> 	output->base.disable = wayland_output_disable;
> 	output->base.enable = wayland_output_enable;
> +	output->base.attach_head = wayland_output_attach_head;
> +	output->base.detach_head = wayland_output_detach_head;
> +
> +	weston_compositor_add_pending_output(&output->base, compositor);
> +
> +	return &output->base;
> +}
> +
> +static struct wayland_head *
> +wayland_head_create(struct weston_compositor *compositor, const char *name)
> +{
> +	struct wayland_head *head;
> +
> +	assert(name);
> +
> +	head = zalloc(sizeof *head);
> +	if (!head)
> +		return NULL;
> +
> +	weston_head_init(&head->base, name);
> +	weston_head_set_connection_status(&head->base, true);
> +	weston_compositor_add_head(compositor, &head->base);
> 
> -	return output;
> +	return head;
> }
> 
> static int
> -wayland_output_create(struct weston_compositor *compositor, const char *name)
> +wayland_head_create_windowed(struct weston_compositor *compositor,
> +			     const char *name)
> {
> -	struct wayland_output *output;
> +	 if (!wayland_head_create(compositor, name))
> +		return -1;
> 
> -	output = wayland_output_create_common(compositor, name);
> -	if (!output)
> +	return 0;
> +}
> +
> +static int
> +wayland_head_create_for_parent_output(struct weston_compositor *compositor,
> +				      struct wayland_parent_output *poutput)
> +{
> +	struct wayland_head *head;
> +	char name[100];
> +	int ret;
> +
> +	ret = snprintf(name, sizeof(name), "wlparent-%d", poutput->id);
> +	if (ret < 1 || (unsigned)ret >= sizeof(name))
> 		return -1;
> 
> -	weston_compositor_add_pending_output(&output->base, compositor);
> +	head = wayland_head_create(compositor, name);
> +	if (!head)
> +		return -1;
> +
> +	assert(!poutput->head);
> +	head->parent_output = poutput;
> +	poutput->head = head;
> +
> +	weston_head_set_monitor_strings(&head->base,
> +					poutput->physical.make,
> +					poutput->physical.model, NULL);
> +	weston_head_set_physical_size(&head->base,
> +				      poutput->physical.width,
> +				      poutput->physical.height);
> 
> 	return 0;
> }
> 
> +static void
> +wayland_head_destroy(struct wayland_head *head)
> +{
> +	if (head->parent_output)
> +		head->parent_output->head = NULL;
> +
> +	weston_head_release(&head->base);
> +	free(head);
> +}
> +
> static int
> wayland_output_set_size(struct weston_output *base, int width, int height)
> {
> 	struct wayland_output *output = to_wayland_output(base);
> -	struct weston_head *head = &output->base.head;
> +	struct weston_head *head;
> 	int output_width, output_height;
> 
> 	/* We can only be called once. */
> @@ -1345,6 +1464,13 @@ wayland_output_set_size(struct weston_output *base, int width, int height)
> 		return -1;
> 	}
> 
> +	wl_list_for_each(head, &output->base.head_list, output_link) {
> +		weston_head_set_monitor_strings(head, "wayland", "none", NULL);
> +
> +		/* XXX: Calculate proper size. */
> +		weston_head_set_physical_size(head, width, height);
> +	}
> +
> 	output_width = width * output->base.scale;
> 	output_height = height * output->base.scale;
> 
> @@ -1358,25 +1484,15 @@ wayland_output_set_size(struct weston_output *base, int width, int height)
> 
> 	output->base.current_mode = &output->mode;
> 
> -	weston_head_set_monitor_strings(head, "wayland", "none", NULL);
> -
> -	/* XXX: Calculate proper size. */
> -	weston_head_set_physical_size(head, width, height);
> -
> 	return 0;
> }
> 
> static int
> -wayland_output_create_for_parent_output(struct wayland_backend *b,
> -					struct wayland_parent_output *poutput)
> +wayland_output_setup_for_parent_output(struct wayland_output *output,
> +				       struct wayland_parent_output *poutput)
> {
> -	struct wayland_output *output;
> 	struct weston_mode *mode;
> 
> -	output = wayland_output_create_common(b->compositor, "wlparent");
> -	if (!output)
> -		return -1;
> -
> 	if (poutput->current_mode) {
> 		mode = poutput->current_mode;
> 	} else if (poutput->preferred_mode) {
> @@ -1386,7 +1502,7 @@ wayland_output_create_for_parent_output(struct wayland_backend *b,
> 				    struct weston_mode, link);
> 	} else {
> 		weston_log("No valid modes found. Skipping output.\n");
> -		goto out;
> +		return -1;
> 	}
> 
> 	output->base.scale = 1;
> @@ -1394,13 +1510,6 @@ wayland_output_create_for_parent_output(struct wayland_backend *b,
> 
> 	output->parent.output = poutput->global;
> 
> -	weston_head_set_monitor_strings(&output->base.head,
> -					poutput->physical.make,
> -					poutput->physical.model, NULL);
> -	weston_head_set_physical_size(&output->base.head,
> -				      poutput->physical.width,
> -				      poutput->physical.height);
> -
> 	wl_list_insert_list(&output->base.mode_list, &poutput->mode_list);
> 	wl_list_init(&poutput->mode_list);
> 
> @@ -1410,33 +1519,21 @@ wayland_output_create_for_parent_output(struct wayland_backend *b,
> 
> 	/* output->mode is unused in this path. */
> 
> -	weston_compositor_add_pending_output(&output->base, b->compositor);
> -
> 	return 0;
> -
> -out:
> -	weston_output_release(&output->base);
> -	free(output->title);
> -	free(output);
> -
> -	return -1;
> }
> 
> static int
> -wayland_output_create_fullscreen(struct wayland_backend *b)
> +wayland_output_setup_fullscreen(struct wayland_output *output,
> +				struct wayland_head *head)
> {
> -	struct wayland_output *output;
> +	struct wayland_backend *b = to_wayland_backend(output->base.compositor);
> 	int width = 0, height = 0;
> 
> -	output = wayland_output_create_common(b->compositor, "wayland-fullscreen");
> -	if (!output)
> -		return -1;
> -
> 	output->base.scale = 1;
> 	output->base.transform = WL_OUTPUT_TRANSFORM_NORMAL;
> 
> 	if (wayland_backend_create_output_surface(output) < 0)
> -		goto err_surface;
> +		return -1;
> 
> 	/* What should size be set if conditional is false? */
> 	if (b->parent.xdg_shell || b->parent.shell) {
> @@ -1456,16 +1553,15 @@ wayland_output_create_fullscreen(struct wayland_backend *b)
> 	if (wayland_output_set_size(&output->base, width, height) < 0)
> 		goto err_set_size;
> 
> -	weston_compositor_add_pending_output(&output->base, b->compositor);
> +	/* The head is not attached yet, so set_size did not set these. */
> +	weston_head_set_monitor_strings(&head->base, "wayland", "none", NULL);
> +	/* XXX: Calculate proper size. */
> +	weston_head_set_physical_size(&head->base, width, height);
> 
> 	return 0;
> 
> err_set_size:
> 	wayland_backend_destroy_output_surface(output);
> -err_surface:
> -	weston_output_release(&output->base);
> -	free(output->title);
> -	free(output);
> 
> 	return -1;
> }
> @@ -2270,16 +2366,32 @@ find_mode(struct wl_list *list, int32_t width, int32_t height, uint32_t refresh)
> 	return mode;
> }
> 
> +static struct weston_output *
> +wayland_parent_output_get_enabled_output(struct wayland_parent_output *poutput)
> +{
> +	struct wayland_head *head = poutput->head;
> +
> +	if (!head)
> +		return NULL;
> +
> +	if (!weston_head_is_enabled(&head->base))
> +		return NULL;
> +
> +	return weston_head_get_output(&head->base);
> +}
> +
> static void
> wayland_parent_output_mode(void *data, struct wl_output *wl_output_proxy,
> 			   uint32_t flags, int32_t width, int32_t height,
> 			   int32_t refresh)
> {
> 	struct wayland_parent_output *output = data;
> +	struct weston_output *enabled_output;
> 	struct weston_mode *mode;
> 
> -	if (output->output) {
> -		mode = find_mode(&output->output->base.mode_list,
> +	enabled_output = wayland_parent_output_get_enabled_output(output);
> +	if (enabled_output) {
> +		mode = find_mode(&enabled_output->mode_list,
> 				 width, height, refresh);
> 		if (!mode)
> 			return;
> @@ -2313,7 +2425,7 @@ output_sync_callback(void *data, struct wl_callback *callback, uint32_t unused)
> 
> 	assert(output->backend->sprawl_across_outputs);
> 
> -	wayland_output_create_for_parent_output(output->backend, output);
> +	wayland_head_create_for_parent_output(output->backend->compositor, output);
> }
> 
> static const struct wl_callback_listener output_sync_listener = {
> @@ -2361,8 +2473,8 @@ wayland_parent_output_destroy(struct wayland_parent_output *output)
> 	if (output->sync_cb)
> 		wl_callback_destroy(output->sync_cb);
> 
> -	if (output->output)
> -		wayland_output_destroy(&output->output->base);
> +	if (output->head)
> +		wayland_head_destroy(output->head);
> 
> 	wl_output_destroy(output->global);
> 	free(output->physical.make);
> @@ -2467,11 +2579,15 @@ static void
> wayland_destroy(struct weston_compositor *ec)
> {
> 	struct wayland_backend *b = to_wayland_backend(ec);
> +	struct weston_head *base, *next;
> 
> 	wl_event_source_remove(b->parent.wl_source);
> 
> 	weston_compositor_shutdown(ec);
> 
> +	wl_list_for_each_safe(base, next, &ec->head_list, compositor_link)
> +		wayland_head_destroy(to_wayland_head(base));
> +
> 	if (b->parent.shm)
> 		wl_shm_destroy(b->parent.shm);
> 
> @@ -2626,6 +2742,7 @@ wayland_backend_create(struct weston_compositor *compositor,
> 	}
> 
> 	b->base.destroy = wayland_destroy;
> +	b->base.create_output = wayland_output_create;
> 
> 	loop = wl_display_get_event_loop(compositor->wl_display);
> 
> @@ -2670,7 +2787,7 @@ wayland_backend_destroy(struct wayland_backend *b)
> 
> static const struct weston_windowed_output_api windowed_api = {
> 	wayland_output_set_size,
> -	wayland_output_create,
> +	wayland_head_create_windowed,
> };
> 
> static void
> @@ -2707,14 +2824,14 @@ weston_backend_init(struct weston_compositor *compositor,
> 		wl_display_roundtrip(b->parent.wl_display);
> 
> 		wl_list_for_each(poutput, &b->parent.output_list, link)
> -			wayland_output_create_for_parent_output(b, poutput);
> +			wayland_head_create_for_parent_output(compositor, poutput);
> 
> 		return 0;
> 	}
> 
> 	if (new_config.fullscreen) {
> -		if (wayland_output_create_fullscreen(b) < 0) {
> -			weston_log("Unable to create a fullscreen output.\n");
> +		if (!wayland_head_create(compositor, "wayland-fullscreen")) {
> +			weston_log("Unable to create a fullscreen head.\n");
> 			goto err_outputs;
> 		}
> 
> -- 
> 2.13.6
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/wayland-devel



More information about the wayland-devel mailing list