Hello, I'm happy with this patch. This patch implement an hybrid option 2-3 that we previously discussed. compositor-drm.h provide the expected public API. The compositor-drm-static.h is a private header that define the opaque struct weston_drm_backend_config. The compositor-drm-static.c implement function that are always loaded. The compositor-drm.c is used for the loadable drm-backend.so -- as before the patch -- but libweston users are not expected to known or see it.
The patch also remove the configure_output callback, which is replaced by an internal function that take output configuration from a list passed in the struct weston_drm_backend_config.output_list. The libweston users are expected to implement a similar function to load_drm_backend in main.c. This function is the reference implementation about how to fill the opaque configuration structure for the drm back-end. Finally, I taken care of memory leak of previous draft, and this patch is ready for deep review. Best regards. --- Makefile.am | 3 + src/compositor-drm-static.c | 206 ++++++++++++++++++++++++++++++++++++++++++++ src/compositor-drm-static.h | 87 +++++++++++++++++++ src/compositor-drm.c | 179 +++++++++++++++++--------------------- src/compositor-drm.h | 140 ++++++++++++++++++++++++++++++ src/main.c | 127 ++++++++++++++++++++++++++- 6 files changed, 640 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..cb8329b --- /dev/null +++ b/src/compositor-drm-static.c @@ -0,0 +1,206 @@ +/* + * 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; + + wl_list_init(&ths->outputs_list); + + ths->connector = 0; + ths->tty = 0; + ths->seat_id = strdup("seat0"); + ths->format = strdup("xrgb8888"); + ths->use_pixman = false; + + return ths; + +} + +void +weston_drm_backend_config_clear_outputs_setup(struct weston_drm_backend_config * ths) { + struct weston_drm_backend_output_config * pos; + struct weston_drm_backend_output_config * tmp; + wl_list_for_each_safe(pos, tmp, &ths->outputs_list, link) { + wl_list_remove(&pos->link); + free(pos->name); + free(pos->format); + free(pos->seat); + free(pos->modeline); + free(pos); + } +} + +void +weston_drm_backend_config_destroy(struct weston_drm_backend_config * ths) { + if(!ths) + return; + + free(ths->seat_id); + free(ths->format); + + weston_drm_backend_config_clear_outputs_setup(ths); + + free(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) { + free(ths->seat_id); + 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) { + free(ths->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; +} + +void +weston_drm_backend_add_output_setup( + struct weston_drm_backend_config * ths, + char const * name, + int scale, + uint32_t transform, + char const * format, + char const * seat, + enum weston_drm_backend_output_mode mode, + char const * modeline +) { + + struct weston_drm_backend_output_config * output = + (__typeof__(output))zalloc(sizeof *output); + + wl_list_init(&output->link); + + output->name = strdup(name); + output->base.scale = scale; + output->base.transform = transform; + + if(format) + output->format = strdup(format); + + if(seat) + output->seat = strdup(seat); + + output->mode = mode; + + if(modeline) + output->modeline = strdup(modeline); + + wl_list_insert(&ths->outputs_list, &output->link); + +} + +/* 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_drm_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->base); +} + + + + diff --git a/src/compositor-drm-static.h b/src/compositor-drm-static.h new file mode 100644 index 0000000..7722b85 --- /dev/null +++ b/src/compositor-drm-static.h @@ -0,0 +1,87 @@ +/* + * 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_ + +#include <wayland-util.h> + +struct weston_drm_backend_output_config { + struct weston_backend_output_config base; + + struct wl_list link; /* link defined output from config file */ + + enum weston_drm_backend_output_mode mode; + + char *name; + char *format; + char *seat; + 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; + + /** possible outputs setup */ + struct wl_list outputs_list; + +}; + + +#endif /* SRC_COMPOSITOR_DRM_STATIC_H_ */ diff --git a/src/compositor-drm.c b/src/compositor-drm.c index 538e56e..0baa24c 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 { @@ -2151,16 +2156,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) @@ -2174,8 +2175,6 @@ get_gbm_format_from_section(struct weston_config_section *section, ret = -1; } - free(s); - return ret; } @@ -2185,20 +2184,16 @@ 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, + struct weston_drm_backend_output_config const *config, + const drmModeModeInfo *current_mode) { struct drm_mode *preferred = NULL; struct drm_mode *current = NULL; @@ -2206,9 +2201,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 (config->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; @@ -2222,19 +2234,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 (config->mode == WESTON_DRM_BACKEND_OUTPUT_CURRENT) configured = current; if (option_current_mode && current) @@ -2280,6 +2286,21 @@ connector_get_current_mode(drmModeConnector *connector, int drm_fd, return 0; } +static struct weston_drm_backend_output_config const * +drm_get_output_configuration(struct drm_backend *backend, const char *name) +{ + struct weston_drm_backend_output_config * output; + wl_list_for_each(output, &backend->config->outputs_list, link) { + if(strstr(name, output->name)) { + return output; + } + } + + /* if the output is not found use an ampty one */ + static struct weston_drm_backend_output_config def = { { 0 }, { 0 }, 0 }; + return &def; +} + /** * Create and configure a Weston output structure * @@ -2303,12 +2324,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 const * config; i = find_crtc_for_connector(b, resources, connector); if (i < 0) { @@ -2327,42 +2345,13 @@ 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); + config = drm_get_output_configuration(b, output->base.name); - 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 : ""); output->crtc_id = resources->crtcs[i]; output->pipe = i; @@ -2382,16 +2371,15 @@ create_output_for_connector(struct drm_backend *b, goto err_free; } - if (config == OUTPUT_CONFIG_OFF) { + if (config->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, config, + &crtc_mode); if (!current) goto err_free; output->base.current_mode = ¤t->base; @@ -2399,7 +2387,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) { @@ -2744,6 +2732,8 @@ drm_destroy(struct weston_compositor *ec) close(b->drm.fd); + weston_drm_backend_config_destroy(b->config); + free(b); } @@ -3067,12 +3057,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; @@ -3095,18 +3082,20 @@ drm_backend_create(struct weston_compositor *compositor, */ b->sprites_are_broken = 1; b->compositor = compositor; + b->use_pixman = config->use_pixman; + + /* the backend become the owner */ + 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"); @@ -3122,7 +3111,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; @@ -3148,6 +3137,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; @@ -3157,12 +3147,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; } @@ -3237,7 +3227,7 @@ err_udev: udev_unref(b->udev); err_compositor: weston_compositor_shutdown(compositor); -err_base: + free(b); return NULL; } @@ -3248,21 +3238,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, ¶m.connector }, - { WESTON_OPTION_STRING, "seat", 0, ¶m.seat_id }, - { WESTON_OPTION_INTEGER, "tty", 0, ¶m.tty }, - { WESTON_OPTION_BOOLEAN, "current-mode", 0, &option_current_mode }, - { WESTON_OPTION_BOOLEAN, "use-pixman", 0, ¶m.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, ¶m, 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..4ffaa34 --- /dev/null +++ b/src/compositor-drm.h @@ -0,0 +1,140 @@ +/* + * 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; + +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, +}; + +/** Create a new default drm backend configuration */ +WL_EXPORT struct weston_drm_backend_config * +weston_drm_backend_config_create(void); + +/** destroy drm backend configuration */ +WL_EXPORT void +weston_drm_backend_config_destroy(struct weston_drm_backend_config * ths); + +/** The connector id of the output to be initialized. + * default: enable all available outputs. */ +WL_EXPORT 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. */ +WL_EXPORT 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. */ +WL_EXPORT void +weston_drm_backend_config_set_use_pixman( + struct weston_drm_backend_config * ths, bool x); + +/** reuse the current output mode */ +WL_EXPORT void +weston_drm_backend_config_set_use_current_mode( + struct weston_drm_backend_config * ths, bool x); + +WL_EXPORT 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. */ +WL_EXPORT 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. */ +WL_EXPORT void +weston_drm_backend_config_set_format( + struct weston_drm_backend_config * ths, + char const * format); + +WL_EXPORT struct weston_backend_config * +weston_drm_backend_config_get_weston_backend_config( + struct weston_drm_backend_config *ths); + +WL_EXPORT void +weston_drm_backend_config_clear_outputs_setup( + struct weston_drm_backend_config * ths); + +WL_EXPORT void +weston_drm_backend_add_output_setup( + struct weston_drm_backend_config * ths, + char const * name, + int scale, + uint32_t transform, + char const * format, + char const * seat, + enum weston_drm_backend_output_mode mode, + char const * modeline +); + +WL_EXPORT int +weston_drm_backend_load(struct weston_compositor *compositor, + int *argc, char **argv, struct weston_config *wc, + struct weston_drm_backend_config *wbc); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/main.c b/src/main.c index 1850fa6..d9abe6e 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; @@ -654,12 +656,133 @@ load_backend_old(struct weston_compositor *compositor, const char *backend, } 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); + + /** + * find all output section and create settings for + * each of them. + **/ + char const * section_name = NULL; + section = NULL; + while(weston_config_next_section(wc, §ion, §ion_name)) { + + if(strcmp("output", section_name) == 0) { + char *cf_name = NULL; + char *cf_mode = NULL; + int cf_scale = 1; + char *cf_transform = NULL; + char *cf_gbm_format = NULL; + char *cf_seat = NULL; + + weston_config_section_get_string(section, "name", &cf_name, NULL); + if(!cf_name) + continue; + + /* output setup data */ + enum weston_drm_backend_output_mode mode; + char * modeline = NULL; + uint32_t transform = 0; + uint32_t scale = 0; + + weston_config_section_get_string(section, "mode", &cf_mode, "preferred"); + if (strcmp(cf_mode, "off") == 0) { + free(cf_mode); + weston_drm_backend_add_output_setup(config, cf_name, 0, 0, + NULL, NULL, WESTON_DRM_BACKEND_OUTPUT_OFF, NULL); + continue; + } + + if (cf_use_current_mode || strcmp(cf_mode, "current") == 0) { + mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT; + } else if (strcmp(cf_mode, "preferred") != 0) { + modeline = cf_mode; + modeline = NULL; + } + free(cf_mode); + + + weston_config_section_get_int(section, "scale", &cf_scale, 1); + scale = cf_scale >= 1 ? cf_scale : 1; + + weston_config_section_get_string(section, "transform", + &cf_transform, "normal"); + + if (weston_parse_transform(cf_transform, &transform) < 0) + weston_log("Invalid transform \"%s\" for output %s\n", + cf_transform, cf_name); + free(cf_transform); + + + weston_config_section_get_string(section, + "gbm-format", &cf_gbm_format, NULL); + + weston_config_section_get_string(section, "seat", &cf_seat, ""); + + weston_drm_backend_add_output_setup(config, cf_name, scale, + transform, cf_gbm_format, cf_seat, mode, modeline); + + free(cf_name); + free(cf_gbm_format); + free(cf_seat); + } + } + + /* load the actual drm backend and configure it */ + if (weston_drm_backend_load(c, argc, argv, wc, 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 +891,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 _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel