[PATCH weston 2/3] drm: port the drm backend to the new init api

Bryce Harrington bryce at osg.samsung.com
Mon Aug 24 19:26:48 PDT 2015


On Thu, Aug 13, 2015 at 01:53:05PM +0300, Pekka Paalanen wrote:
> From: Giulio Camuffo <giuliocamuffo at gmail.com>

This is a big patch with a lot of changes, and I'm worried about landing
it right as we're on the eve of beta.  If it could be broken up into
smaller easy-to-review bits, it might make it more digestible...

That said, I like where this is going.  I'd be totally okay with landing
it post-release.
 
> ---
>  Makefile.am          |   3 +
>  src/compositor-drm.c | 234 ++++++++++++++++-----------------------------------
>  src/compositor-drm.h |  89 ++++++++++++++++++++
>  src/main.c           | 127 +++++++++++++++++++++++++++-
>  4 files changed, 292 insertions(+), 161 deletions(-)
>  create mode 100644 src/compositor-drm.h
> 
> diff --git a/Makefile.am b/Makefile.am
> index 76ab546..2f21930 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -72,6 +72,7 @@ weston_SOURCES =					\
>  	src/log.c					\
>  	src/compositor.c				\
>  	src/compositor.h				\
> +	src/compositor-drm.h				\
>  	src/input.c					\
>  	src/data-device.c				\
>  	src/screenshooter.c				\
> @@ -188,6 +189,7 @@ westonincludedir = $(includedir)/weston
>  westoninclude_HEADERS =				\
>  	src/version.h				\
>  	src/compositor.h			\
> +	src/compositor-drm.h			\
>  	src/timeline-object.h			\
>  	shared/matrix.h				\
>  	shared/config-parser.h			\
> @@ -251,6 +253,7 @@ drm_backend_la_CFLAGS =				\
>  	$(AM_CFLAGS)
>  drm_backend_la_SOURCES =			\
>  	src/compositor-drm.c			\
> +	src/compositor-drm.h			\
>  	$(INPUT_BACKEND_SOURCES)		\
>  	shared/helpers.h			\
>  	shared/timespec-util.h			\
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> index ce95d05..4c298fe 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -50,6 +50,7 @@
>  #include "shared/timespec-util.h"
>  #include "libbacklight.h"
>  #include "compositor.h"
> +#include "compositor-drm.h"
>  #include "gl-renderer.h"
>  #include "pixman-renderer.h"
>  #include "libinput-seat.h"
> @@ -73,17 +74,6 @@
>  #define GBM_BO_USE_CURSOR GBM_BO_USE_CURSOR_64X64
>  #endif
>  
> -static int option_current_mode = 0;
> -
> -enum output_config {
> -	OUTPUT_CONFIG_INVALID = 0,
> -	OUTPUT_CONFIG_OFF,
> -	OUTPUT_CONFIG_PREFERRED,
> -	OUTPUT_CONFIG_CURRENT,
> -	OUTPUT_CONFIG_MODE,
> -	OUTPUT_CONFIG_MODELINE
> -};
> -
>  struct drm_backend {
>  	struct weston_backend base;
>  	struct weston_compositor *compositor;
> @@ -106,6 +96,7 @@ struct drm_backend {
>  	uint32_t connector_allocator;
>  	struct wl_listener session_listener;
>  	uint32_t format;
> +	bool option_current_mode;
>  
>  	/* we need these parameters in order to not fail drmModeAddFB2()
>  	 * due to out of bounds dimensions, and then mistakenly set
> @@ -129,6 +120,10 @@ struct drm_backend {
>  
>  	int32_t cursor_width;
>  	int32_t cursor_height;
> +
> +	void (*configure_output)(struct weston_compositor *compositor,
> +				 const char *name,
> +				 struct weston_drm_backend_output_config *config);
>  };
>  
>  struct drm_mode {
> @@ -219,13 +214,6 @@ struct drm_sprite {
>  	uint32_t formats[];
>  };
>  
> -struct drm_parameters {
> -	int connector;
> -	int tty;
> -	int use_pixman;
> -	const char *seat_id;
> -};
> -
>  static struct gl_renderer_interface *gl_renderer;
>  
>  static const char default_seat[] = "seat0";
> @@ -2026,47 +2014,26 @@ find_and_parse_output_edid(struct drm_backend *b,
>  
>  
>  
> -static int
> -parse_modeline(const char *s, drmModeModeInfo *mode)
> -{
> -	char hsync[16];
> -	char vsync[16];
> -	float fclock;
> -
> -	mode->type = DRM_MODE_TYPE_USERDEF;
> -	mode->hskew = 0;
> -	mode->vscan = 0;
> -	mode->vrefresh = 0;
> -	mode->flags = 0;
> -
> -	if (sscanf(s, "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
> -		   &fclock,
> -		   &mode->hdisplay,
> -		   &mode->hsync_start,
> -		   &mode->hsync_end,
> -		   &mode->htotal,
> -		   &mode->vdisplay,
> -		   &mode->vsync_start,
> -		   &mode->vsync_end,
> -		   &mode->vtotal, hsync, vsync) != 11)
> -		return -1;
> -
> -	mode->clock = fclock * 1000;
> -	if (strcmp(hsync, "+hsync") == 0)
> -		mode->flags |= DRM_MODE_FLAG_PHSYNC;
> -	else if (strcmp(hsync, "-hsync") == 0)
> -		mode->flags |= DRM_MODE_FLAG_NHSYNC;
> -	else
> -		return -1;
> +static void
> +parse_modeline(struct weston_drm_backend_modeline *modeline,
> +               drmModeModeInfo *drm_mode)
> +{
> +	drm_mode->type = DRM_MODE_TYPE_USERDEF;
> +	drm_mode->hskew = 0;
> +	drm_mode->vscan = 0;
> +	drm_mode->vrefresh = 0;
> +	drm_mode->flags = modeline->flags;
> +	drm_mode->clock = modeline->clock;
>  
> -	if (strcmp(vsync, "+vsync") == 0)
> -		mode->flags |= DRM_MODE_FLAG_PVSYNC;
> -	else if (strcmp(vsync, "-vsync") == 0)
> -		mode->flags |= DRM_MODE_FLAG_NVSYNC;
> -	else
> -		return -1;
> +	drm_mode->hdisplay = modeline->hdisplay;
> +	drm_mode->hsync_start = modeline->hsync_start;
> +	drm_mode->hsync_end = modeline->hsync_end;
> +	drm_mode->htotal = modeline->htotal;
>  
> -	return 0;
> +	drm_mode->vdisplay = modeline->vdisplay;
> +	drm_mode->vsync_start = modeline->vsync_start;
> +	drm_mode->vsync_end = modeline->vsync_end;
> +	drm_mode->vtotal = modeline->vtotal;
>  }

"parse" is a bit misleading here, since we're just copying data and not
actually parsing anything anymore.  Maybe a more descriptive name would
be something like init_drm_modeinfo() or copy_weston_modeline_to_drm().

This patch also adds a different parse_modeline() over in main.c, which
does actually parse stuff, so a different name here could prevent some
future confusion.

Also, this function would be easy to write a test case for, as it just
copies data from one structure to another.

>  static void
> @@ -2093,16 +2060,10 @@ setup_output_seat_constraint(struct drm_backend *b,
>  }
>  
>  static int
> -get_gbm_format_from_section(struct weston_config_section *section,
> -			    uint32_t default_value,
> -			    uint32_t *format)
> +parse_gbm_format(const char *s, uint32_t default_value, uint32_t *format)
>  {
> -	char *s;
>  	int ret = 0;
>  
> -	weston_config_section_get_string(section,
> -					 "gbm-format", &s, NULL);
> -
>  	if (s == NULL)
>  		*format = default_value;
>  	else if (strcmp(s, "xrgb8888") == 0)
> @@ -2116,8 +2077,6 @@ get_gbm_format_from_section(struct weston_config_section *section,
>  		ret = -1;
>  	}
>  
> -	free(s);
> -
>  	return ret;
>  }

Nice refactoring.  With this change, this function also becomes quite
simple to write a test case for... just pass in various strings and
verify the correct int is returned.

> @@ -2127,31 +2086,29 @@ get_gbm_format_from_section(struct weston_config_section *section,
>   * Find the most suitable mode to use for initial setup (or reconfiguration on
>   * hotplug etc) for a DRM output.
>   *
> + * @param backend The DRM backend object
>   * @param output DRM output to choose mode for
> - * @param kind Strategy and preference to use when choosing mode
> - * @param width Desired width for this output
> - * @param height Desired height for this output
> + * @param config Desired configuration for the output
>   * @param current_mode Mode currently being displayed on this output
> - * @param modeline Manually-entered mode (may be NULL)
>   * @returns A mode from the output's mode list, or NULL if none available
>   */
>  static struct drm_mode *
> -drm_output_choose_initial_mode(struct drm_output *output,
> -			       enum output_config kind,
> -			       int width, int height,
> -			       const drmModeModeInfo *current_mode,
> -			       const drmModeModeInfo *modeline)
> +drm_output_choose_initial_mode(struct drm_backend *backend,
> +			       struct drm_output *output,
> +			       struct weston_drm_backend_output_config *config,
> +			       const drmModeModeInfo *current_mode)

This function has a number of exit points, making it a really good
candidate for writing a thorough collection of test cases.  The tricky
bits would be the two drm_output_add_mode() calls, which will need
mocks; initially though a first cut test could leave those two branches
as TODO.

>  {
>  	struct drm_mode *preferred = NULL;
>  	struct drm_mode *current = NULL;
>  	struct drm_mode *configured = NULL;
>  	struct drm_mode *best = NULL;
>  	struct drm_mode *drm_mode;
> +	drmModeModeInfo modeline;
>  
>  	wl_list_for_each_reverse(drm_mode, &output->base.mode_list, base.link) {
> -		if (kind == OUTPUT_CONFIG_MODE &&
> -		    width == drm_mode->base.width &&
> -		    height == drm_mode->base.height)
> +		if (config->type == WESTON_DRM_BACKEND_OUTPUT_TYPE_MODE &&
> +		    config->base.width == drm_mode->base.width &&
> +		    config->base.height == drm_mode->base.height)
>  			configured = drm_mode;
>  
>  		if (memcmp(&current_mode, &drm_mode->mode_info,
> @@ -2164,8 +2121,9 @@ drm_output_choose_initial_mode(struct drm_output *output,
>  		best = drm_mode;
>  	}
>  
> -	if (kind == OUTPUT_CONFIG_MODELINE) {
> -		configured = drm_output_add_mode(output, modeline);
> +	if (config->type == WESTON_DRM_BACKEND_OUTPUT_TYPE_MODELINE) {
> +		parse_modeline(&config->modeline, &modeline);
> +		configured = drm_output_add_mode(output, &modeline);
>  		if (!configured)
>  			return NULL;
>  	}
> @@ -2176,10 +2134,10 @@ drm_output_choose_initial_mode(struct drm_output *output,
>  			return NULL;
>  	}
>  
> -	if (kind == OUTPUT_CONFIG_CURRENT)
> +	if (config->type == WESTON_DRM_BACKEND_OUTPUT_TYPE_CURRENT)
>  		configured = current;
>  
> -	if (option_current_mode && current)
> +	if (backend->option_current_mode && current)
>  		return current;
>  
>  	if (configured)
> @@ -2245,12 +2203,9 @@ create_output_for_connector(struct drm_backend *b,
>  	struct drm_output *output;
>  	struct drm_mode *drm_mode, *next, *current;
>  	struct weston_mode *m;
> -	struct weston_config_section *section;
> -	drmModeModeInfo crtc_mode, modeline;
> -	int i, width, height, scale;
> -	char *s;
> -	enum output_config config;
> -	uint32_t transform;
> +	drmModeModeInfo crtc_mode;
> +	int i;
> +	struct weston_drm_backend_output_config config;
>  
>  	i = find_crtc_for_connector(b, resources, connector);
>  	if (i < 0) {
> @@ -2269,42 +2224,14 @@ create_output_for_connector(struct drm_backend *b,
>  	output->base.serial_number = "unknown";
>  	wl_list_init(&output->base.mode_list);
>  
> -	section = weston_config_get_section(b->compositor->config, "output", "name",
> -					    output->base.name);
> -	weston_config_section_get_string(section, "mode", &s, "preferred");
> -	if (strcmp(s, "off") == 0)
> -		config = OUTPUT_CONFIG_OFF;
> -	else if (strcmp(s, "preferred") == 0)
> -		config = OUTPUT_CONFIG_PREFERRED;
> -	else if (strcmp(s, "current") == 0)
> -		config = OUTPUT_CONFIG_CURRENT;
> -	else if (sscanf(s, "%dx%d", &width, &height) == 2)
> -		config = OUTPUT_CONFIG_MODE;
> -	else if (parse_modeline(s, &modeline) == 0)
> -		config = OUTPUT_CONFIG_MODELINE;
> -	else {
> -		weston_log("Invalid mode \"%s\" for output %s\n",
> -			   s, output->base.name);
> -		config = OUTPUT_CONFIG_PREFERRED;
> -	}
> -	free(s);
> -
> -	weston_config_section_get_int(section, "scale", &scale, 1);
> -	weston_config_section_get_string(section, "transform", &s, "normal");
> -	if (weston_parse_transform(s, &transform) < 0)
> -		weston_log("Invalid transform \"%s\" for output %s\n",
> -			   s, output->base.name);
> -
> -	free(s);
> -
> -	if (get_gbm_format_from_section(section,
> -					b->format,
> -					&output->format) == -1)
> +	b->configure_output(b->compositor, output->base.name,
> +			    &config);
> +	if (parse_gbm_format(config.format, b->format, &output->format) == -1)
>  		output->format = b->format;
>  
> -	weston_config_section_get_string(section, "seat", &s, "");
> -	setup_output_seat_constraint(b, &output->base, s);
> -	free(s);
> +	setup_output_seat_constraint(b, &output->base,
> +				     config.seat ? config.seat : "");
> +	free(config.seat);
>  
>  	output->crtc_id = resources->crtcs[i];
>  	output->pipe = i;
> @@ -2324,16 +2251,15 @@ create_output_for_connector(struct drm_backend *b,
>  			goto err_free;
>  	}
>  
> -	if (config == OUTPUT_CONFIG_OFF) {
> +	if (config.type == WESTON_DRM_BACKEND_OUTPUT_TYPE_OFF) {
>  		weston_log("Disabling output %s\n", output->base.name);
>  		drmModeSetCrtc(b->drm.fd, output->crtc_id,
>  			       0, 0, 0, 0, 0, NULL);
>  		goto err_free;
>  	}
>  
> -	current = drm_output_choose_initial_mode(output, config,
> -						 width, height,
> -						 &crtc_mode, &modeline);
> +	current = drm_output_choose_initial_mode(b, output, &config,
> +						 &crtc_mode);
>  	if (!current)
>  		goto err_free;
>  	output->base.current_mode = &current->base;
> @@ -2341,7 +2267,7 @@ create_output_for_connector(struct drm_backend *b,
>  
>  	weston_output_init(&output->base, b->compositor, x, y,
>  			   connector->mmWidth, connector->mmHeight,
> -			   transform, scale);
> +			   config.base.transform, config.base.scale);
>  
>  	if (b->use_pixman) {
>  		if (drm_output_init_pixman(output, b) < 0) {
> @@ -3008,16 +2934,14 @@ renderer_switch_binding(struct weston_keyboard *keyboard, uint32_t time,
>  
>  static struct drm_backend *
>  drm_backend_create(struct weston_compositor *compositor,
> -		      struct drm_parameters *param,
> -		      int *argc, char *argv[],
> -		      struct weston_config *config)
> +		   struct weston_drm_backend_config *config)
>  {
>  	struct drm_backend *b;
> -	struct weston_config_section *section;
>  	struct udev_device *drm_device;
>  	struct wl_event_loop *loop;
>  	const char *path;
>  	uint32_t key;
> +	const char *seat_id = default_seat;
>  
>  	weston_log("initializing drm backend\n");
>  
> @@ -3037,18 +2961,18 @@ drm_backend_create(struct weston_compositor *compositor,
>  	b->sprites_are_broken = 1;
>  	b->cursors_are_broken = 1;
>  	b->compositor = compositor;
> +	b->use_pixman = config->use_pixman;
> +	b->configure_output = config->configure_output;
> +	b->option_current_mode = config->default_current_mode;
>  
> -	section = weston_config_get_section(config, "core", NULL, NULL);
> -	if (get_gbm_format_from_section(section,
> -					GBM_FORMAT_XRGB8888,
> -					&b->format) == -1)
> -		goto err_base;
> -
> -	b->use_pixman = param->use_pixman;
> +	if (parse_gbm_format(config->format, GBM_FORMAT_XRGB8888, &b->format) < 0)
> +		goto err_compositor;
>  
> +	if (config->seat_id)
> +		seat_id = config->seat_id;
>  	/* Check if we run drm-backend using weston-launch */
> -	compositor->launcher = weston_launcher_connect(compositor, param->tty,
> -						       param->seat_id, true);
> +	compositor->launcher = weston_launcher_connect(compositor, config->tty,
> +						       seat_id, true);
>  	if (compositor->launcher == NULL) {
>  		weston_log("fatal: drm backend should be run "
>  			   "using weston-launch binary or as root\n");
> @@ -3064,7 +2988,7 @@ drm_backend_create(struct weston_compositor *compositor,
>  	b->session_listener.notify = session_notify;
>  	wl_signal_add(&compositor->session_signal, &b->session_listener);
>  
> -	drm_device = find_primary_gpu(b, param->seat_id);
> +	drm_device = find_primary_gpu(b, seat_id);
>  	if (drm_device == NULL) {
>  		weston_log("no drm device found\n");
>  		goto err_udev;
> @@ -3090,6 +3014,7 @@ drm_backend_create(struct weston_compositor *compositor,
>  
>  	b->base.destroy = drm_destroy;
>  	b->base.restore = drm_restore;
> +	b->base.create_output = NULL;
>  
>  	b->prev_state = WESTON_COMPOSITOR_ACTIVE;
>  
> @@ -3102,12 +3027,12 @@ drm_backend_create(struct weston_compositor *compositor,
>  	create_sprites(b);
>  
>  	if (udev_input_init(&b->input,
> -			    compositor, b->udev, param->seat_id) < 0) {
> +			    compositor, b->udev, seat_id) < 0) {
>  		weston_log("failed to create input devices\n");
>  		goto err_sprite;
>  	}
>  
> -	if (create_outputs(b, param->connector, drm_device) < 0) {
> +	if (create_outputs(b, config->connector, drm_device) < 0) {
>  		weston_log("failed to create output for %s\n", path);
>  		goto err_udev_input;
>  	}
> @@ -3175,32 +3100,21 @@ err_udev:
>  	udev_unref(b->udev);
>  err_compositor:
>  	weston_compositor_shutdown(compositor);
> -err_base:
> +
>  	free(b);
>  	return NULL;
>  }
>  
>  WL_EXPORT int
>  backend_init(struct weston_compositor *compositor, int *argc, char *argv[],
> -	     struct weston_config *config,
> -	     struct weston_backend_config *config_base)
> +             struct weston_config *wc,
> +             struct weston_backend_config *config_base)
>  {
>  	struct drm_backend *b;
> -	struct drm_parameters param = { 0, };
> -
> -	const struct weston_option drm_options[] = {
> -		{ WESTON_OPTION_INTEGER, "connector", 0, &param.connector },
> -		{ WESTON_OPTION_STRING, "seat", 0, &param.seat_id },
> -		{ WESTON_OPTION_INTEGER, "tty", 0, &param.tty },
> -		{ WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode },
> -		{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &param.use_pixman },
> -	};
> -
> -	param.seat_id = default_seat;
> -
> -	parse_options(drm_options, ARRAY_LENGTH(drm_options), argc, argv);
> +	struct weston_drm_backend_config *config =
> +				(struct weston_drm_backend_config *)config_base;
>  
> -	b = drm_backend_create(compositor, &param, argc, argv, config);
> +	b = drm_backend_create(compositor, config);
>  	if (b == NULL)
>  		return -1;
>  	return 0;
> diff --git a/src/compositor-drm.h b/src/compositor-drm.h
> new file mode 100644
> index 0000000..b058ef3
> --- /dev/null
> +++ b/src/compositor-drm.h
> @@ -0,0 +1,89 @@
> +/*
> + * Copyright © 2008-2011 Kristian Høgsberg
> + * Copyright © 2011 Intel Corporation
> + * Copyright © 2015 Giulio Camuffo
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining
> + * a copy of this software and associated documentation files (the
> + * "Software"), to deal in the Software without restriction, including
> + * without limitation the rights to use, copy, modify, merge, publish,
> + * distribute, sublicense, and/or sell copies of the Software, and to
> + * permit persons to whom the Software is furnished to do so, subject to
> + * the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial
> + * portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */
> +
> +#ifndef WESTON_COMPOSITOR_DRM_H
> +#define WESTON_COMPOSITOR_DRM_H
> +
> +#ifdef  __cplusplus
> +extern "C" {
> +#endif
> +
> +#include "compositor.h"
> +
> +struct weston_drm_backend_modeline;

Is this forward declaration actually necessary?

> +enum weston_drm_backend_output_type {
> +	WESTON_DRM_BACKEND_OUTPUT_TYPE_INVALID = 0,
> +	WESTON_DRM_BACKEND_OUTPUT_TYPE_OFF,
> +	WESTON_DRM_BACKEND_OUTPUT_TYPE_PREFERRED,
> +	WESTON_DRM_BACKEND_OUTPUT_TYPE_CURRENT,
> +	WESTON_DRM_BACKEND_OUTPUT_TYPE_MODE,
> +	WESTON_DRM_BACKEND_OUTPUT_TYPE_MODELINE
> +};
> +
> +enum weston_drm_backend_modeline_flags {
> +	WESTON_DRM_BACKEND_MODELINE_FLAG_PHSYNC = (1 << 0),
> +	WESTON_DRM_BACKEND_MODELINE_FLAG_NHSYNC = (1 << 1),
> +	WESTON_DRM_BACKEND_MODELINE_FLAG_PVSYNC = (1 << 2),
> +	WESTON_DRM_BACKEND_MODELINE_FLAG_NVSYNC = (1 << 3),
> +};
> +
> +struct weston_drm_backend_modeline {
> +	uint32_t flags;
> +	uint32_t clock;
> +	uint16_t hdisplay, hsync_start, hsync_end, htotal;
> +	uint16_t vdisplay, vsync_start, vsync_end, vtotal;
> +};
> +
> +struct weston_drm_backend_output_config {
> +	struct weston_backend_output_config base;
> +
> +	char *format;
> +	char *seat;
> +	enum weston_drm_backend_output_type type;
> +	struct weston_drm_backend_modeline modeline;
> +};
> +
> +struct weston_drm_backend_config {
> +	struct weston_backend_config base;
> +
> +	int connector;
> +	int tty;
> +	bool use_pixman;
> +	const char *seat_id;
> +	const char *format;
> +	bool default_current_mode;
> +	void (*configure_output)(struct weston_compositor *compositor,
> +				 const char *name,
> +				 struct weston_drm_backend_output_config *config);
> +};
> +
> +#ifdef  __cplusplus
> +}
> +#endif
> +
> +#endif
> diff --git a/src/main.c b/src/main.c
> index 19124a9..d861c60 100644
> --- a/src/main.c
> +++ b/src/main.c
> @@ -47,6 +47,8 @@
>  #include "git-version.h"
>  #include "version.h"
>  
> +#include "compositor-drm.h"
> +
>  static struct wl_list child_process_list;
>  static struct weston_compositor *segv_compositor;
>  
> @@ -664,12 +666,135 @@ init_backend_new(struct weston_compositor *compositor, const char *backend,
>  }
>  
>  static int
> +parse_modeline(const char *s, struct weston_drm_backend_modeline *mode)
> +{
> +	char hsync[16];
> +	char vsync[16];
> +	float fclock;
> +
> +	mode->flags = 0;
> +
> +	if (sscanf(s, "%f %hd %hd %hd %hd %hd %hd %hd %hd %15s %15s",
> +		   &fclock,
> +		   &mode->hdisplay,
> +		   &mode->hsync_start,
> +		   &mode->hsync_end,
> +		   &mode->htotal,
> +		   &mode->vdisplay,
> +		   &mode->vsync_start,
> +		   &mode->vsync_end,
> +		   &mode->vtotal, hsync, vsync) != 11)
> +		return -1;
> +
> +	mode->clock = fclock * 1000;
> +	if (strcmp(hsync, "+hsync") == 0)
> +		mode->flags |= WESTON_DRM_BACKEND_MODELINE_FLAG_PHSYNC;
> +	else if (strcmp(hsync, "-hsync") == 0)
> +		mode->flags |= WESTON_DRM_BACKEND_MODELINE_FLAG_NHSYNC;
> +	else
> +		return -1;
> +
> +	if (strcmp(vsync, "+vsync") == 0)
> +		mode->flags |= WESTON_DRM_BACKEND_MODELINE_FLAG_PVSYNC;
> +	else if (strcmp(vsync, "-vsync") == 0)
> +		mode->flags |= WESTON_DRM_BACKEND_MODELINE_FLAG_NVSYNC;
> +	else
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static void
> +drm_configure_output(struct weston_compositor *c, const char *name,
> +		     struct weston_drm_backend_output_config *config)

main.c doesn't seem like the proper location for these drm calls?

And there's no guarantee drm is even built in, so shouldn't these be
wrappered in '#if defined(BUILD_DRM_COMPOSITOR)'?

> +{
> +	struct weston_config *wc = weston_compositor_get_user_data(c);
> +	struct weston_config_section *section;
> +	char *s;
> +
> +	section = weston_config_get_section(wc, "output", "name", name);
> +	weston_config_section_get_string(section, "mode", &s, "preferred");
> +	if (strcmp(s, "off") == 0)
> +		config->type = WESTON_DRM_BACKEND_OUTPUT_TYPE_OFF;
> +	else if (strcmp(s, "preferred") == 0)
> +		config->type = WESTON_DRM_BACKEND_OUTPUT_TYPE_PREFERRED;
> +	else if (strcmp(s, "current") == 0)
> +		config->type = WESTON_DRM_BACKEND_OUTPUT_TYPE_CURRENT;
> +	else if (sscanf(s, "%dx%d", &config->base.width,
> +				    &config->base.height) == 2)
> +		config->type = WESTON_DRM_BACKEND_OUTPUT_TYPE_MODE;
> +	else if (parse_modeline(s, &config->modeline) == 0)
> +		config->type = WESTON_DRM_BACKEND_OUTPUT_TYPE_MODELINE;
> +	else {
> +		weston_log("Invalid mode \"%s\" for output %s\n",
> +			   s, name);
> +		config->type = WESTON_DRM_BACKEND_OUTPUT_TYPE_PREFERRED;
> +	}
> +	free(s);
> +
> +	weston_config_section_get_int(section, "scale", &config->base.scale, 1);
> +	weston_config_section_get_string(section, "transform", &s, "normal");
> +	if (weston_parse_transform(s, &config->base.transform) < 0)
> +		weston_log("Invalid transform \"%s\" for output %s\n",
> +			   s, name);
> +	free(s);
> +
> +	weston_config_section_get_string(section,
> +					 "gbm-format", &config->format, NULL);
> +	weston_config_section_get_string(section, "seat", &config->seat, "");
> +}
> +
> +static int
> +init_drm_backend(struct weston_compositor *c, const char *backend,
> +		 int *argc, char **argv, struct weston_config *wc)
> +{
> +	struct weston_drm_backend_config config = {
> +		.use_pixman = false,
> +		.connector = 0,
> +		.seat_id = NULL,
> +		.format = NULL,
> +		.tty = 0,
> +		.default_current_mode = false,
> +		.configure_output = drm_configure_output,
> +	};
> +	struct weston_config_section *section;
> +	char *format = NULL, *seat = NULL;
> +	int ret = 0;
> +
> +	const struct weston_option options[] = {
> +		{ WESTON_OPTION_INTEGER, "connector", 0, &config.connector },
> +		{ WESTON_OPTION_STRING, "seat", 0, &seat },
> +		{ WESTON_OPTION_INTEGER, "tty", 0, &config.tty },
> +		{ WESTON_OPTION_BOOLEAN, "current-mode", 0,
> +					 &config.default_current_mode },
> +		{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &config.use_pixman },
> +	};
> +
> +	parse_options(options, ARRAY_LENGTH(options), argc, argv);
> +
> +	section = weston_config_get_section(wc, "core", NULL, NULL);
> +	weston_config_section_get_string(section,
> +					 "gbm-format", &format,
> +					 format);
> +	config.format = format;
> +	config.seat_id = seat;
> +
> +	if (init_backend_new(c, backend, &config.base) < 0)
> +		ret = -1;
> +
> +	free(seat);
> +	free(format);
> +	return ret;
> +}
> +
> +static int
>  init_backend(struct weston_compositor *compositor, const char *backend,
>  	     int *argc, char **argv, struct weston_config *config)
>  {
> -#if 0
> +
>  	if (strstr(backend, "drm-backend.so"))
>  		return init_drm_backend(compositor, backend, argc, argv, config);
> +#if 0
>  	else if (strstr(backend, "wayland-backend.so"))
>  		return init_wayland_backend(compositor, backend, argc, argv, config);
>  	else if (strstr(backend, "x11-backend.so"))
> -- 
> 2.4.6
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Bryce


More information about the wayland-devel mailing list