2016-03-10 2:49 GMT+02:00 Bryce Harrington <br...@osg.samsung.com>: > From: Giulio Camuffo <giuliocamu...@gmail.com> > > Signed-off-by: Bryce Harrington <br...@osg.samsung.com> > Reviewed-by: Quentin Glidic <sardemff7+...@sardemff7.net> > Acked-by: Pekka Paalanen <pekka.paala...@collabora.co.uk> > --- > v4: Update to current trunk > - Add missing param doc for mode in drm_output_choose_initial_mode > - Rebase to account for code changes by 91880f1e to make vt > switching configurable. > > Makefile.am | 3 + > src/compositor-drm.c | 196 > ++++++++++++++++++--------------------------------- > src/compositor.h | 2 - > src/main.c | 94 +++++++++++++++++++++++- > 4 files changed, 165 insertions(+), 130 deletions(-)
Hi, thanks for keeping this going. I'll try to review it (for what is worth, since the code should be mine :P), but note that the compositor-drm.h file is missing. -- Giulio > > diff --git a/Makefile.am b/Makefile.am > index fe08d94..9330f0e 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 \ > @@ -207,6 +208,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 \ > @@ -276,6 +278,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 e01f6b9..111c882 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" > @@ -74,17 +75,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; > @@ -130,6 +120,8 @@ struct drm_backend { > > int32_t cursor_width; > int32_t cursor_height; > + > + struct weston_drm_backend_config *config; > }; > > struct drm_mode { > @@ -220,13 +212,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"; > @@ -2151,16 +2136,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) > @@ -2174,8 +2153,6 @@ get_gbm_format_from_section(struct > weston_config_section *section, > ret = -1; > } > > - free(s); > - > return ret; > } > > @@ -2185,30 +2162,45 @@ 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 mode Controls how to select the mode > + * @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; > struct drm_mode *configured = NULL; > 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; > > @@ -2222,24 +2214,15 @@ 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 == WESTON_DRM_BACKEND_OUTPUT_CURRENT) > configured = current; > > - if (option_current_mode && current) > - return current; > - > if (configured) > return configured; > > @@ -2303,12 +2286,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) { > @@ -2327,42 +2308,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) > + mode = b->config->configure_output(b->compositor, b->config, > + 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; > @@ -2382,16 +2335,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 = ¤t->base; > @@ -2399,7 +2351,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) { > @@ -2477,6 +2429,7 @@ err_free: > b->crtc_allocator &= ~(1 << output->crtc_id); > b->connector_allocator &= ~(1 << output->connector_id); > free(output); > + free(config.modeline); > > return -1; > } > @@ -2744,6 +2697,10 @@ drm_destroy(struct weston_compositor *ec) > > close(b->drm.fd); > > + free(b->config->format); > + free(b->config->seat_id); > + free(b->config); > + > free(b); > } > > @@ -3067,15 +3024,13 @@ 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; > + const char *seat_id = default_seat; > > weston_log("initializing drm backend\n"); > > @@ -3095,18 +3050,17 @@ 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->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"); > @@ -3122,7 +3076,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; > @@ -3148,6 +3102,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 +3112,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; > } > @@ -3237,32 +3192,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, ¶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 *config = > + (struct weston_drm_backend_config > *)config_base; > > - b = drm_backend_create(compositor, ¶m, argc, argv, config); > + b = drm_backend_create(compositor, config); > if (b == NULL) > return -1; > return 0; > diff --git a/src/compositor.h b/src/compositor.h > index 794a1b0..30462cf 100644 > --- a/src/compositor.h > +++ b/src/compositor.h > @@ -673,8 +673,6 @@ enum weston_capability { > */ > struct weston_backend_output_config { > uint32_t transform; > - uint32_t width; > - uint32_t height; > uint32_t scale; > }; > > diff --git a/src/main.c b/src/main.c > index 43de354..66c054e 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; > > @@ -670,13 +672,101 @@ load_backend_new(struct weston_compositor *compositor, > const char *backend, > return backend_init(compositor, NULL, NULL, NULL, config_base); > } > > +struct drm_config { > + struct weston_drm_backend_config base; > + bool use_current_mode; > +}; > + > +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 drm_config *drm_config = (struct drm_config *)backend_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 (drm_config->use_current_mode || strcmp(s, "current") == 0) { > + mode = WESTON_DRM_BACKEND_OUTPUT_CURRENT; > + } else if (strcmp(s, "preferred") != 0) { > + config->modeline = s; > + s = NULL; > + } > + free(s); > + > + weston_config_section_get_int(section, "scale", &scale, 1); > + config->base.scale = scale >= 1 ? 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, ""); > + return mode; > +} > + > +static int > +load_drm_backend(struct weston_compositor *c, const char *backend, > + int *argc, char **argv, struct weston_config *wc) > +{ > + struct drm_config *config; > + struct weston_config_section *section; > + int ret = 0; > + > + config = zalloc(sizeof *config); > + if (!config) > + return -1; > + > + const struct weston_option options[] = { > + { WESTON_OPTION_INTEGER, "connector", 0, > &config->base.connector }, > + { WESTON_OPTION_STRING, "seat", 0, &config->base.seat_id }, > + { WESTON_OPTION_INTEGER, "tty", 0, &config->base.tty }, > + { WESTON_OPTION_BOOLEAN, "current-mode", 0, > + &config->use_current_mode }, > + { WESTON_OPTION_BOOLEAN, "use-pixman", 0, > &config->base.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", &config->base.format, > + NULL); > + > + config->base.configure_output = drm_configure_output; > + > + if (load_backend_new(c, backend, &config->base.base) < 0) { > + ret = -1; > + free(config->base.format); > + free(config->base.seat_id); > + free(config); > + } > + > + 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")) > @@ -785,7 +875,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; > -- > 1.9.1 > _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/wayland-devel