[PATCH 06/10] weston: Port headless backend to new output handling API

Quentin Glidic sardemff7+wayland at sardemff7.net
Fri Aug 12 11:42:22 UTC 2016


On 11/08/2016 17:34, Armin Krezović wrote:
> This is a complete port of the headless backend that
> uses recently added output handling API for output
> configuration.
>
> - Output can be configured at runtime by passing the
>   necessary configuration parameters, which can be
>   filled in manually, obtained from the configuration
>   file or obtained from the command line using
>   previously added functionality. It is required that
>   the scale and transform values are set using the
>   previously added functionality.
>
> - Output can be created at runtime using the output
>   API. The output creation only creates a pending
>   output, which needs to be configured the same way as
>   mentioned above.
>
> After everything has been set, output needs to be
> enabled manually using weston_output_enable().
>
> Same as before, a single output is created at runtime
> using the default configuration or a configuration
> parsed from the command line. The no-outputs
> functionality is also preserved, which means that no
> output will be created initially, but more outputs can
> be added at runtime using the output API.
>
> Signed-off-by: Armin Krezović <krezovic.armin at gmail.com>

Looks good:
Reviewed-by: Quentin Glidic <sardemff7+git at sardemff7.net>

Cheers,


> ---
>  compositor/main.c               |  54 +++++++++++++--
>  libweston/compositor-headless.c | 146 ++++++++++++++++++++++++++--------------
>  libweston/compositor-headless.h |   6 --
>  3 files changed, 144 insertions(+), 62 deletions(-)
>
> diff --git a/compositor/main.c b/compositor/main.c
> index 817eb2e..c9a33f8 100644
> --- a/compositor/main.c
> +++ b/compositor/main.c
> @@ -1225,31 +1225,54 @@ load_drm_backend(struct weston_compositor *c,
>  	return ret;
>  }
>
> +static void
> +headless_backend_output_configure(struct wl_listener *listener, void *data)
> +{
> +	struct weston_output *output = data;
> +	struct weston_compositor *ec = output->compositor;
> +	struct wet_output_config *parsed_options = wet_get_parsed_options(ec);
> +
> +	struct wet_output_config defaults = {
> +		.width = 1024,
> +		.height = 640,
> +		.scale = 1,
> +		.transform = WL_OUTPUT_TRANSFORM_NORMAL
> +	};
> +
> +	if (wet_configure_windowed_output_from_config(output, &defaults, parsed_options) < 0)
> +		weston_log("Cannot configure output \"%s\".\n",
> +			   output->name ? output->name : "unnamed");
> +}
> +
>  static int
>  load_headless_backend(struct weston_compositor *c,
>  		      int *argc, char **argv, struct weston_config *wc)
>  {
> +	const struct weston_windowed_output_api *api;
>  	struct weston_headless_backend_config config = {{ 0, }};
> +	int no_outputs = 0;
>  	int ret = 0;
>  	char *transform = NULL;
>
> -	config.width = 1024;
> -	config.height = 640;
> +	struct wet_output_config *parsed_options = wet_init_parsed_options(c);
> +	if (!parsed_options)
> +		return -1;
>
>  	const struct weston_option options[] = {
> -		{ WESTON_OPTION_INTEGER, "width", 0, &config.width },
> -		{ WESTON_OPTION_INTEGER, "height", 0, &config.height },
> +		{ WESTON_OPTION_INTEGER, "width", 0, &parsed_options->width },
> +		{ WESTON_OPTION_INTEGER, "height", 0, &parsed_options->height },
>  		{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman },
>  		{ WESTON_OPTION_STRING, "transform", 0, &transform },
> -		{ WESTON_OPTION_BOOLEAN, "no-outputs", 0, &config.no_outputs },
> +		{ WESTON_OPTION_BOOLEAN, "no-outputs", 0, &no_outputs },
>  	};
>
>  	parse_options(options, ARRAY_LENGTH(options), argc, argv);
>
> -	config.transform = WL_OUTPUT_TRANSFORM_NORMAL;
>  	if (transform) {
> -		if (weston_parse_transform(transform, &config.transform) < 0)
> +		if (weston_parse_transform(transform, &parsed_options->transform) < 0) {
>  			weston_log("Invalid transform \"%s\"\n", transform);
> +			parsed_options->transform = UINT32_MAX;
> +		}
>  		free(transform);
>  	}
>
> @@ -1260,6 +1283,23 @@ load_headless_backend(struct weston_compositor *c,
>  	ret = weston_compositor_load_backend(c, WESTON_BACKEND_HEADLESS,
>  					     &config.base);
>
> +	if (ret < 0)
> +		return ret;
> +
> +	wet_set_pending_output_handler(c, headless_backend_output_configure);
> +
> +	if (!no_outputs) {
> +		api = weston_windowed_output_get_api(c);
> +
> +		if (!api) {
> +			weston_log("Cannot use weston_windowed_output_api.\n");
> +			return -1;
> +		}
> +
> +		if (api->output_create(c, "headless") < 0)
> +			return -1;
> +	}
> +
>  	return ret;
>  }
>
> diff --git a/libweston/compositor-headless.c b/libweston/compositor-headless.c
> index 8b51207..793b8a9 100644
> --- a/libweston/compositor-headless.c
> +++ b/libweston/compositor-headless.c
> @@ -37,6 +37,7 @@
>  #include "shared/helpers.h"
>  #include "pixman-renderer.h"
>  #include "presentation-time-server-protocol.h"
> +#include "output-api.h"
>
>  struct headless_backend {
>  	struct weston_backend base;
> @@ -106,85 +107,122 @@ headless_output_repaint(struct weston_output *output_base,
>  }
>
>  static void
> -headless_output_destroy(struct weston_output *output_base)
> +headless_output_destroy(struct weston_output *base)
>  {
> -	struct headless_output *output = to_headless_output(output_base);
> -	struct headless_backend *b =
> -			to_headless_backend(output->base.compositor);
> -
> -	wl_event_source_remove(output->finish_frame_timer);
> -
> -	if (b->use_pixman) {
> -		pixman_renderer_output_destroy(&output->base);
> -		pixman_image_unref(output->image);
> -		free(output->image_buf);
> -	}
> +	struct headless_output *output = to_headless_output(base);
>
>  	weston_output_destroy(&output->base);
>
>  	free(output);
> +}
> +
> +static int
> +headless_output_disable(struct weston_output *base)
> +{
> +	struct headless_output *output = to_headless_output(base);
> +	struct headless_backend *b = to_headless_backend(base->compositor);
> +
> +	if (output->base.initialized) {
> +		wl_event_source_remove(output->finish_frame_timer);
>
> -	return;
> +		if (b->use_pixman) {
> +			pixman_renderer_output_destroy(&output->base);
> +			pixman_image_unref(output->image);
> +			free(output->image_buf);
> +		}
> +	}
> +
> +	return 0;
>  }
>
>  static int
> -headless_backend_create_output(struct headless_backend *b,
> -			       struct weston_headless_backend_config *config)
> +headless_output_enable(struct weston_output *base)
>  {
> -	struct weston_compositor *c = b->compositor;
> -	struct headless_output *output;
> +	struct headless_output *output = to_headless_output(base);
> +	struct headless_backend *b = to_headless_backend(base->compositor);
>  	struct wl_event_loop *loop;
>
> -	output = zalloc(sizeof *output);
> -	if (output == NULL)
> -		return -1;
> +	loop = wl_display_get_event_loop(b->compositor->wl_display);
> +	output->finish_frame_timer =
> +		wl_event_loop_add_timer(loop, finish_frame_handler, output);
> +
> +	if (b->use_pixman) {
> +		output->image_buf = malloc(output->base.mm_width *
> +					   output->base.mm_height * 4);
> +		if (!output->image_buf)
> +			goto err_malloc;
> +
> +		output->image = pixman_image_create_bits(PIXMAN_x8r8g8b8,
> +							 output->base.mm_width,
> +							 output->base.mm_height,
> +							 output->image_buf,
> +							 output->base.mm_width * 4);
> +
> +		if (pixman_renderer_output_create(&output->base) < 0)
> +			goto err_renderer;
> +
> +		pixman_renderer_output_set_buffer(&output->base,
> +						  output->image);
> +	}
> +
> +	return 0;
> +
> +err_renderer:
> +	pixman_image_unref(output->image);
> +	free(output->image_buf);
> +err_malloc:
> +	wl_event_source_remove(output->finish_frame_timer);
> +
> +	return -1;
> +}
> +
> +static int
> +headless_output_configure(struct weston_output *base,
> +			  int width, int height)
> +{
> +	struct headless_output *output = to_headless_output(base);
>
>  	output->mode.flags =
>  		WL_OUTPUT_MODE_CURRENT | WL_OUTPUT_MODE_PREFERRED;
> -	output->mode.width = config->width;
> -	output->mode.height = config->height;
> +	output->mode.width = width;
> +	output->mode.height = height;
>  	output->mode.refresh = 60000;
>  	wl_list_init(&output->base.mode_list);
>  	wl_list_insert(&output->base.mode_list, &output->mode.link);
>
>  	output->base.current_mode = &output->mode;
> -	weston_output_init(&output->base, c, 0, 0, config->width,
> -			   config->height, config->transform, 1);
> -
>  	output->base.make = "weston";
>  	output->base.model = "headless";
>
> -	loop = wl_display_get_event_loop(c->wl_display);
> -	output->finish_frame_timer =
> -		wl_event_loop_add_timer(loop, finish_frame_handler, output);
> +	output->base.mm_width = width;
> +	output->base.mm_height = height;
>
>  	output->base.start_repaint_loop = headless_output_start_repaint_loop;
>  	output->base.repaint = headless_output_repaint;
> -	output->base.destroy = headless_output_destroy;
>  	output->base.assign_planes = NULL;
>  	output->base.set_backlight = NULL;
>  	output->base.set_dpms = NULL;
>  	output->base.switch_mode = NULL;
>
> -	if (b->use_pixman) {
> -		output->image_buf = malloc(config->width * config->height * 4);
> -		if (!output->image_buf)
> -			return -1;
> +	return 0;
> +}
>
> -		output->image = pixman_image_create_bits(PIXMAN_x8r8g8b8,
> -							 config->width,
> -							 config->height,
> -							 output->image_buf,
> -							 config->width * 4);
> +static int
> +headless_output_create(struct weston_compositor *compositor,
> +		       const char *name)
> +{
> +	struct headless_output *output;
>
> -		if (pixman_renderer_output_create(&output->base) < 0)
> -			return -1;
> +	output = zalloc(sizeof *output);
> +	if (output == NULL)
> +		return -1;
>
> -		pixman_renderer_output_set_buffer(&output->base,
> -						  output->image);
> -	}
> +	output->base.name = name ? strdup(name) : NULL;
> +	output->base.destroy = headless_output_destroy;
> +	output->base.disable = headless_output_disable;
> +	output->base.enable = headless_output_enable;
>
> -	weston_compositor_add_output(c, &output->base);
> +	weston_output_init_pending(&output->base, compositor);
>
>  	return 0;
>  }
> @@ -204,11 +242,17 @@ headless_destroy(struct weston_compositor *ec)
>  	free(b);
>  }
>
> +static const struct weston_windowed_output_api api = {
> +	headless_output_configure,
> +	headless_output_create,
> +};
> +
>  static struct headless_backend *
>  headless_backend_create(struct weston_compositor *compositor,
>  			struct weston_headless_backend_config *config)
>  {
>  	struct headless_backend *b;
> +	int ret;
>
>  	b = zalloc(sizeof *b);
>  	if (b == NULL)
> @@ -226,15 +270,19 @@ headless_backend_create(struct weston_compositor *compositor,
>  		pixman_renderer_init(compositor);
>  	}
>
> -	if (!config->no_outputs) {
> -		if (headless_backend_create_output(b, config) < 0)
> -			goto err_input;
> -	}
> -
>  	if (!b->use_pixman && noop_renderer_init(compositor) < 0)
>  		goto err_input;
>
>  	compositor->backend = &b->base;
> +
> +	ret = weston_plugin_api_register(compositor, WESTON_WINDOWED_OUTPUT_API_NAME,
> +					 &api, sizeof(api));
> +
> +	if (ret < 0) {
> +		weston_log("Failed to register output API.\n");
> +		goto err_input;
> +	}
> +
>  	return b;
>
>  err_input:
> diff --git a/libweston/compositor-headless.h b/libweston/compositor-headless.h
> index b432b09..14b77c8 100644
> --- a/libweston/compositor-headless.h
> +++ b/libweston/compositor-headless.h
> @@ -39,14 +39,8 @@ extern "C" {
>  struct weston_headless_backend_config {
>  	struct weston_backend_config base;
>
> -	int width;
> -	int height;
> -
>  	/** Whether to use the pixman renderer instead of the OpenGL ES renderer. */
>  	int use_pixman;
> -
> -	uint32_t transform;
> -	bool no_outputs;
>  };
>
>  #ifdef  __cplusplus
>


-- 

Quentin “Sardem FF7” Glidic


More information about the wayland-devel mailing list