[PATCH] drm-backend-refactor-draft

gschwind at gnu-log.net gschwind at gnu-log.net
Tue Feb 9 12:27:13 UTC 2016


From: Benoit Gschwind (blocage) <gschwind at gnu-log.net>

Hello,

To feed the discution here is my proposal, mostly derivated from giucam work. it's not intend to be merged as-is (several memory leak). 

It illustrate a specific configuration API and a generic backend load.

Best regards

---
 Makefile.am                 |   3 +
 src/compositor-drm-static.c | 188 ++++++++++++++++++++++++++++++++++++++++++++
 src/compositor-drm-static.h |  93 ++++++++++++++++++++++
 src/compositor-drm.c        | 166 ++++++++++++++++----------------------
 src/compositor-drm.h        | 161 +++++++++++++++++++++++++++++++++++++
 src/main.c                  | 119 +++++++++++++++++++++++++++-
 6 files changed, 628 insertions(+), 102 deletions(-)
 create mode 100644 src/compositor-drm-static.c
 create mode 100644 src/compositor-drm-static.h
 create mode 100644 src/compositor-drm.h

diff --git a/Makefile.am b/Makefile.am
index 623621d..fca1d38 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -72,6 +72,9 @@ weston_SOURCES =					\
 	src/log.c					\
 	src/compositor.c				\
 	src/compositor.h				\
+	src/compositor-drm-static.c			\
+	src/compositor-drm-static.h			\
+	src/compositor-drm.h			\
 	src/input.c					\
 	src/data-device.c				\
 	src/screenshooter.c				\
diff --git a/src/compositor-drm-static.c b/src/compositor-drm-static.c
new file mode 100644
index 0000000..b165560
--- /dev/null
+++ b/src/compositor-drm-static.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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.
+ */
+
+#include <string.h>
+
+#include "compositor-drm.h"
+#include "compositor-drm-static.h"
+
+struct weston_drm_backend_config *
+weston_drm_backend_config_create() {
+	struct weston_drm_backend_config * ths =
+			(__typeof__(ths))malloc(sizeof *ths);
+
+	if(!ths)
+		return 0;
+
+	ths->connector = 0;
+	ths->tty = 0;
+	ths->seat_id = "seat0";
+	ths->format = 0;
+	ths->configure_output = 0;
+	ths->use_pixman = false;
+
+	return ths;
+
+}
+
+void
+weston_drm_backend_config_set_connector(
+		struct weston_drm_backend_config * ths,
+		int connector) {
+	ths->connector = connector;
+}
+
+/** The tty to be used. default: use the current tty. */
+void
+weston_drm_backend_config_set_tty(
+		struct weston_drm_backend_config * ths,
+		int tty) {
+	ths->tty = tty;
+}
+
+/** If true the pixman renderer will be used instead of the OpenGL ES
+ * renderer. */
+void weston_drm_backend_config_set_use_pixman(
+		struct weston_drm_backend_config * ths,
+		bool x) {
+	ths->use_pixman = x;
+}
+
+/** The seat to be used for input and output. If NULL the default "seat0"
+ * will be used.
+ * The backend will take ownership of the seat_id pointer and will free
+ * it on backend destruction. */
+void
+weston_drm_backend_config_set_seat_id(
+		struct weston_drm_backend_config * ths,
+		char const * seat_id) {
+	weston_log("XXXX\n");
+	if(seat_id)
+		ths->seat_id = strdup(seat_id);
+	else
+		ths->seat_id = strdup("seat0");
+}
+
+/** The pixel format of the framebuffer to be used. Valid values are:
+ * - NULL - The default format ("xrgb8888") will be used;
+ * - "xrgb8888";
+ * - "rgb565"
+ * - "xrgb2101010"
+ * The backend will take ownership of the format pointer and will free
+ * it on backend destruction. */
+/* TODO: enums ? */
+void
+weston_drm_backend_config_set_format(
+		struct weston_drm_backend_config * ths,
+		char const * format) {
+	if(ths->format)
+		ths->format = strdup(format);
+	else
+		ths->format = strdup("xrgb8888");
+}
+
+void
+weston_drm_backend_config_set_use_current_mode(
+		struct weston_drm_backend_config * ths,
+		bool x) {
+	ths->use_current_mode = x;
+}
+
+bool
+weston_drm_backend_config_get_use_current_mode(
+		struct weston_drm_backend_config * ths) {
+	return ths->use_current_mode;
+}
+
+/** Callback used to configure the outputs. This function will be called
+ * by the backend when a new DRM output needs to be configured. */
+void
+weston_drm_backend_config_set_configure_output_func(
+		struct weston_drm_backend_config * ths,
+		weston_drm_backend_configure_output_func func) {
+	ths->configure_output = func;
+}
+
+struct weston_backend_config *
+weston_drm_backend_config_get_weston_backend_config(
+		struct weston_drm_backend_config *ths) {
+	return &ths->base;
+}
+
+void
+weston_drm_backend_output_config_set_scale(
+		struct weston_drm_backend_output_config *ths,
+		uint32_t scale) {
+	ths->base.scale = scale;
+}
+
+void
+weston_drm_backend_output_config_set_transform(
+		struct weston_drm_backend_output_config *ths,
+		uint32_t transform) {
+	ths->base.transform = transform;
+}
+
+void
+weston_drm_backend_output_config_set_format(
+		struct weston_drm_backend_output_config *ths,
+		char const * format) {
+	ths->format = strdup(format);
+}
+
+void
+weston_drm_backend_output_config_set_seat(
+		struct weston_drm_backend_output_config *ths,
+		char const * seat) {
+	ths->seat = strdup(seat);
+}
+
+void
+weston_drm_backend_output_config_set_modeline(
+		struct weston_drm_backend_output_config *ths,
+		char const * modeline) {
+	ths->modeline = strdup(modeline);
+}
+
+/* new load function that need weston_backend_config */
+int
+weston_drm_backend_load(struct weston_compositor *compositor,
+		 int *argc, char **argv, struct weston_config *wc,
+		 struct weston_backend_config *wbc)
+{
+	int (*backend_init)(struct weston_compositor *c,
+			    int *argc, char *argv[],
+			    struct weston_config *config,
+			    struct weston_backend_config *config_base);
+
+	backend_init = weston_load_module("drm-backend.so", "backend_init");
+	if (!backend_init)
+		return -1;
+
+	return backend_init(compositor, argc, argv, wc, wbc);
+}
+
+
diff --git a/src/compositor-drm-static.h b/src/compositor-drm-static.h
new file mode 100644
index 0000000..de71327
--- /dev/null
+++ b/src/compositor-drm-static.h
@@ -0,0 +1,93 @@
+/*
+ * 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 SRC_COMPOSITOR_DRM_STATIC_H_
+#define SRC_COMPOSITOR_DRM_STATIC_H_
+
+struct weston_drm_backend_output_config {
+	struct weston_backend_output_config base;
+
+	/** The pixel format to be used by the output. Valid values are:
+	 * - NULL - The format set at backend creation time will be used;
+	 * - "xrgb8888";
+	 * - "rgb565"
+	 * - "xrgb2101010"
+	 */
+	char *format;
+	/** The seat to be used by the output. Set to NULL to use the
+	 * default seat. */
+	char *seat;
+	/** The modeline to be used by the output. Refer to the documentation
+	 * of WESTON_DRM_BACKEND_OUTPUT_PREFERRED for details. */
+	char *modeline;
+};
+
+/** The backend configuration struct.
+ *
+ * weston_drm_backend_config contains the configuration used by a DRM
+ * backend. The backend will take ownership of the weston_backend_config
+ * object passed to it on initialization and will free it on destruction. */
+struct weston_drm_backend_config {
+	struct weston_backend_config base;
+
+	/** The connector id of the output to be initialized. A value of 0 will
+	 * enable all available outputs. */
+	int connector;
+	/** The tty to be used. Set to 0 to use the current tty. */
+	int tty;
+	/** If true the pixman renderer will be used instead of the OpenGL ES
+	 * renderer. */
+	bool use_pixman;
+
+	/** reuse the current output mode */
+	bool use_current_mode;
+
+	/** The seat to be used for input and output. If NULL the default "seat0"
+	 * will be used.
+	 * The backend will take ownership of the seat_id pointer and will free
+	 * it on backend destruction. */
+	char *seat_id;
+	/** The pixel format of the framebuffer to be used. Valid values are:
+	 * - NULL - The default format ("xrgb8888") will be used;
+	 * - "xrgb8888";
+	 * - "rgb565"
+	 * - "xrgb2101010"
+	 * The backend will take ownership of the format pointer and will free
+	 * it on backend destruction. */
+	char *format;
+
+	/** Callback used to configure the outputs. This function will be called
+	 * by the backend when a new DRM output needs to be configured. */
+	enum weston_drm_backend_output_mode
+		(*configure_output)(struct weston_compositor *compositor,
+				    struct weston_drm_backend_config *backend_config,
+				    const char *name,
+				    struct weston_drm_backend_output_config *output_config);
+};
+
+
+#endif /* SRC_COMPOSITOR_DRM_STATIC_H_ */
diff --git a/src/compositor-drm.c b/src/compositor-drm.c
index 8b9882e..5cc81b4 100644
--- a/src/compositor-drm.c
+++ b/src/compositor-drm.c
@@ -50,6 +50,8 @@
 #include "shared/timespec-util.h"
 #include "libbacklight.h"
 #include "compositor.h"
+#include "compositor-drm.h"
+#include "compositor-drm-static.h"
 #include "gl-renderer.h"
 #include "pixman-renderer.h"
 #include "libinput-seat.h"
@@ -130,6 +132,9 @@ struct drm_backend {
 
 	int32_t cursor_width;
 	int32_t cursor_height;
+
+	struct weston_drm_backend_config config;
+
 };
 
 struct drm_mode {
@@ -2143,16 +2148,12 @@ setup_output_seat_constraint(struct drm_backend *b,
 }
 
 static int
-get_gbm_format_from_section(struct weston_config_section *section,
+parse_gbm_format(char const *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)
@@ -2166,8 +2167,6 @@ get_gbm_format_from_section(struct weston_config_section *section,
 		ret = -1;
 	}
 
-	free(s);
-
 	return ret;
 }
 
@@ -2177,20 +2176,17 @@ 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 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 backend The DRM backend object
+ * @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,
+				   enum weston_drm_backend_output_mode mode,
+				   struct weston_drm_backend_output_config *config,
+			       const drmModeModeInfo *current_mode)
 {
 	struct drm_mode *preferred = NULL;
 	struct drm_mode *current = NULL;
@@ -2198,9 +2194,26 @@ drm_output_choose_initial_mode(struct drm_output *output,
 	struct drm_mode *best = NULL;
 	struct drm_mode *drm_mode;
 
+	drmModeModeInfo modeline;
+	int32_t width, height;
+
+	if (mode == WESTON_DRM_BACKEND_OUTPUT_PREFERRED && config->modeline) {
+		if (sscanf(config->modeline, "%dx%d", &width, &height) != 2) {
+			width = -1;
+
+			if (parse_modeline(config->modeline, &modeline) == 0) {
+				configured = drm_output_add_mode(output, &modeline);
+				if (!configured)
+					return NULL;
+			} else {
+				weston_log("Invalid modeline \"%s\" for output %s\n",
+					   config->modeline, output->base.name);
+			}
+		}
+	}
+
 	wl_list_for_each_reverse(drm_mode, &output->base.mode_list, base.link) {
-		if (kind == OUTPUT_CONFIG_MODE &&
-		    width == drm_mode->base.width &&
+		if (width == drm_mode->base.width &&
 		    height == drm_mode->base.height)
 			configured = drm_mode;
 
@@ -2214,19 +2227,13 @@ 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 (!configured)
-			return NULL;
-	}
-
 	if (current == NULL && current_mode->clock != 0) {
 		current = drm_output_add_mode(output, current_mode);
 		if (!current)
 			return NULL;
 	}
 
-	if (kind == OUTPUT_CONFIG_CURRENT)
+	if (mode == OUTPUT_CONFIG_CURRENT)
 		configured = current;
 
 	if (option_current_mode && current)
@@ -2295,12 +2302,10 @@ 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;
+	enum weston_drm_backend_output_mode mode;
+	struct weston_drm_backend_output_config config = { 0 };
 
 	i = find_crtc_for_connector(b, resources, connector);
 	if (i < 0) {
@@ -2319,42 +2324,16 @@ 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);
+	mode = b->config.configure_output(b->compositor, &b->config,
+					   output->base.name, &config);
 
-	if (get_gbm_format_from_section(section,
-					b->format,
-					&output->format) == -1)
+	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;
@@ -2374,16 +2353,15 @@ create_output_for_connector(struct drm_backend *b,
 			goto err_free;
 	}
 
-	if (config == OUTPUT_CONFIG_OFF) {
+	if (mode == WESTON_DRM_BACKEND_OUTPUT_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, mode, &config,
+						 &crtc_mode);
 	if (!current)
 		goto err_free;
 	output->base.current_mode = &current->base;
@@ -2391,7 +2369,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) {
@@ -2468,6 +2446,7 @@ err_free:
 	b->crtc_allocator &= ~(1 << output->crtc_id);
 	b->connector_allocator &= ~(1 << output->connector_id);
 	free(output);
+	free(config.modeline);
 
 	return -1;
 }
@@ -3058,12 +3037,9 @@ 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;
@@ -3086,18 +3062,18 @@ drm_backend_create(struct weston_compositor *compositor,
 	 */
 	b->sprites_are_broken = 1;
 	b->compositor = compositor;
+	b->use_pixman = config->use_pixman;
+	b->config = *config;
 
-	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->config.seat_id = strdup(config->seat_id);
+	b->config.format = 0;
 
-	b->use_pixman = param->use_pixman;
+	if (parse_gbm_format(config->format, GBM_FORMAT_XRGB8888, &b->format) < 0)
+		goto err_compositor;
 
 	/* 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,
+						       config->seat_id, true);
 	if (compositor->launcher == NULL) {
 		weston_log("fatal: drm backend should be run "
 			   "using weston-launch binary or as root\n");
@@ -3113,7 +3089,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, config->seat_id);
 	if (drm_device == NULL) {
 		weston_log("no drm device found\n");
 		goto err_udev;
@@ -3139,6 +3115,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;
 
@@ -3148,12 +3125,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, config->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;
 	}
@@ -3228,7 +3205,7 @@ err_udev:
 	udev_unref(b->udev);
 err_compositor:
 	weston_compositor_shutdown(compositor);
-err_base:
+
 	free(b);
 	return NULL;
 }
@@ -3239,21 +3216,10 @@ backend_init(struct weston_compositor *compositor, int *argc, char *argv[],
 	     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 *drm_config =
+			(struct weston_drm_backend_config *)config_base;
 
-	b = drm_backend_create(compositor, &param, argc, argv, config);
+	b = drm_backend_create(compositor, drm_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..ce832f4
--- /dev/null
+++ b/src/compositor-drm.h
@@ -0,0 +1,161 @@
+/*
+ * 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_config;
+struct weston_drm_backend_output_config;
+
+enum weston_drm_backend_output_mode {
+	/** The output is disabled */
+	WESTON_DRM_BACKEND_OUTPUT_OFF,
+	/** The output will use the current active mode */
+	WESTON_DRM_BACKEND_OUTPUT_CURRENT,
+	/** The output will use the preferred mode. A modeline can be provided
+	 * by setting weston_backend_output_config::modeline in the form of
+	 * "WIDTHxHEIGHT" or in the form of an explicit modeline calculated
+	 * using e.g. the cvt tool. If a valid modeline is supplied it will be
+	 * used, if invalid or NULL the preferred available mode will be used. */
+	WESTON_DRM_BACKEND_OUTPUT_PREFERRED,
+};
+
+/** Callback used to configure the outputs. This function will be called
+ * by the backend when a new DRM output needs to be configured. */
+typedef enum weston_drm_backend_output_mode
+	(*weston_drm_backend_configure_output_func)(struct weston_compositor *compositor,
+			    struct weston_drm_backend_config *backend_config,
+			    const char *name,
+			    struct weston_drm_backend_output_config *output_config);
+
+/** Create a new default drm backend configuration */
+struct weston_drm_backend_config *
+weston_drm_backend_config_create(void);
+
+/** The connector id of the output to be initialized.
+ * default: enable all available outputs. */
+void
+weston_drm_backend_config_set_connector(
+		struct weston_drm_backend_config * ths,
+		int connector);
+
+/** The tty to be used. default: use the current tty. */
+void
+weston_drm_backend_config_set_tty(
+		struct weston_drm_backend_config * ths,
+		int tty);
+
+/** If true the pixman renderer will be used instead of the OpenGL ES
+ * renderer. */
+void weston_drm_backend_config_set_use_pixman(
+		struct weston_drm_backend_config * ths,
+		bool x);
+
+/** reuse the current output mode */
+void
+weston_drm_backend_config_set_use_current_mode(
+		struct weston_drm_backend_config * ths,
+		bool x);
+
+bool
+weston_drm_backend_config_get_use_current_mode(
+		struct weston_drm_backend_config * ths);
+
+/** The seat to be used for input and output. If NULL the default "seat0"
+ * will be used.
+ * The backend will take ownership of the seat_id pointer and will free
+ * it on backend destruction. */
+void
+weston_drm_backend_config_set_seat_id(
+		struct weston_drm_backend_config * ths,
+		char const * seat_id);
+
+/** The pixel format of the framebuffer to be used. Valid values are:
+ * - NULL - The default format ("xrgb8888") will be used;
+ * - "xrgb8888";
+ * - "rgb565"
+ * - "xrgb2101010"
+ * The backend will take ownership of the format pointer and will free
+ * it on backend destruction. */
+/* TODO: enums ? */
+void
+weston_drm_backend_config_set_format(
+		struct weston_drm_backend_config * ths,
+		char const * format);
+
+/** Callback used to configure the outputs. This function will be called
+ * by the backend when a new DRM output needs to be configured. */
+void
+weston_drm_backend_config_set_configure_output_func(
+		struct weston_drm_backend_config * ths,
+		weston_drm_backend_configure_output_func func);
+
+struct weston_backend_config *
+weston_drm_backend_config_get_weston_backend_config(
+		struct weston_drm_backend_config *ths);
+
+void
+weston_drm_backend_output_config_set_scale(
+		struct weston_drm_backend_output_config *ths,
+		uint32_t scale);
+
+void
+weston_drm_backend_output_config_set_transform(
+		struct weston_drm_backend_output_config *ths,
+		uint32_t transform);
+
+void
+weston_drm_backend_output_config_set_format(
+		struct weston_drm_backend_output_config *ths,
+		char const * format);
+
+void
+weston_drm_backend_output_config_set_seat(
+		struct weston_drm_backend_output_config *ths,
+		char const * seat);
+
+void
+weston_drm_backend_output_config_set_modeline(
+		struct weston_drm_backend_output_config *ths,
+		char const * modeline);
+
+int
+weston_drm_backend_load(struct weston_compositor *compositor,
+		 int *argc, char **argv, struct weston_config *wc,
+		 struct weston_backend_config *wbc);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/main.c b/src/main.c
index 1850fa6..7e96e64 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;
 
@@ -653,13 +655,126 @@ load_backend_old(struct weston_compositor *compositor, const char *backend,
 	return backend_init(compositor, argc, argv, wc, NULL);
 }
 
+static enum weston_drm_backend_output_mode
+drm_configure_output(struct weston_compositor *c,
+		     struct weston_drm_backend_config *backend_config,
+		     const char *name,
+		     struct weston_drm_backend_output_config *config)
+{
+	struct weston_config *wc = weston_compositor_get_user_data(c);
+	struct weston_config_section *section;
+	char *s;
+	int scale;
+	enum weston_drm_backend_output_mode mode =
+				WESTON_DRM_BACKEND_OUTPUT_PREFERRED;
+
+	section = weston_config_get_section(wc, "output", "name", name);
+	weston_config_section_get_string(section, "mode", &s, "preferred");
+	if (strcmp(s, "off") == 0) {
+		free(s);
+		return WESTON_DRM_BACKEND_OUTPUT_OFF;
+	}
+
+	if (weston_drm_backend_config_get_use_current_mode(backend_config)
+			|| strcmp(s, "current") == 0) {
+		mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT;
+	} else if (strcmp(s, "preferred") != 0) {
+		weston_drm_backend_output_config_set_modeline(config, s);
+		s = NULL;
+	}
+	free(s);
+
+	weston_config_section_get_int(section, "scale", &scale, 1);
+	weston_drm_backend_output_config_set_scale(config, scale >= 1 ? scale : 1);
+	weston_config_section_get_string(section, "transform", &s, "normal");
+
+	uint32_t transform;
+	if (weston_parse_transform(s, &transform) < 0)
+		weston_log("Invalid transform \"%s\" for output %s\n",
+			   s, name);
+	else
+		weston_drm_backend_output_config_set_transform(config, transform);
+
+	free(s);
+
+
+	char * format;
+	weston_config_section_get_string(section,
+					 "gbm-format", &format, NULL);
+	if(format)
+		weston_drm_backend_output_config_set_format(config, format);
+
+	char * seat;
+	weston_config_section_get_string(section, "seat", &seat, "");
+	weston_drm_backend_output_config_set_seat(config, seat);
+
+	return mode;
+}
+
+static int
+load_drm_backend(struct weston_compositor *c, char const * backend,
+		 int *argc, char **argv, struct weston_config *wc)
+{
+	struct weston_drm_backend_config *config;
+
+	struct weston_config_section *section;
+	int ret = 0;
+
+	config = weston_drm_backend_config_create();
+	if (!config)
+		return -1;
+
+	int cf_connector = 0;
+	int cf_tty = 0;
+	bool cf_use_pixman = false;
+	bool cf_use_current_mode = true;
+	char *cf_seat_id = NULL;
+	char *cf_format = NULL;
+
+	const struct weston_option options[] = {
+		{ WESTON_OPTION_INTEGER, "connector", 0, &cf_connector },
+		{ WESTON_OPTION_STRING, "seat", 0, &cf_seat_id },
+		{ WESTON_OPTION_INTEGER, "tty", 0, &cf_tty },
+		{ WESTON_OPTION_BOOLEAN, "current-mode", 0, &cf_use_current_mode },
+		{ WESTON_OPTION_BOOLEAN, "use-pixman", 0, &cf_use_pixman },
+	};
+
+	parse_options(options, ARRAY_LENGTH(options), argc, argv);
+
+	/* get format */
+	section = weston_config_get_section(wc, "core", NULL, NULL);
+	weston_config_section_get_string(section, "gbm-format", &cf_format, NULL);
+
+	/* fill the config structure */
+	weston_drm_backend_config_set_connector(config, cf_connector);
+	weston_drm_backend_config_set_seat_id(config, cf_seat_id);
+	weston_drm_backend_config_set_tty(config, cf_tty);
+	weston_drm_backend_config_set_use_current_mode(config, cf_use_current_mode);
+	weston_drm_backend_config_set_use_pixman(config, cf_use_pixman);
+
+	if(cf_format)
+		weston_drm_backend_config_set_format(config, cf_format);
+
+	weston_drm_backend_config_set_configure_output_func(config,
+			drm_configure_output);
+
+	/* load the actual drm backend and configure it */
+	if (weston_drm_backend_load(c, argc, argv, wc,
+			weston_drm_backend_config_get_weston_backend_config(config)) < 0) {
+		ret = -1;
+	}
+
+	return ret;
+}
+
+
 static int
 load_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 load_drm_backend(compositor, backend, argc, argv, config);
+#if 0
 	else if (strstr(backend, "wayland-backend.so"))
 		return load_wayland_backend(compositor, backend, argc, argv, config);
 	else if (strstr(backend, "x11-backend.so"))
@@ -768,7 +883,7 @@ int main(int argc, char *argv[])
 			backend = weston_choose_default_backend();
 	}
 
-	ec = weston_compositor_create(display, NULL);
+	ec = weston_compositor_create(display, config);
 	if (ec == NULL) {
 		weston_log("fatal: failed to create compositor\n");
 		goto out;
-- 
2.4.10



More information about the wayland-devel mailing list