X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=recipes-graphics%2Fwayland%2Fweston%2F0001-Add-virtual-output-support.patch;h=211fb732a6fde98b9f0a2c243827525bda2efe01;hb=376888887cb8ade94ceb4db0ac6cf80fb6cadb4a;hp=6373f94e372ca4795ef60c09e30ef1555ab56405;hpb=562c0c1bb2ef74ccbfda1bae4f84a61828119674;p=AGL%2Fmeta-agl-demo.git diff --git a/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch b/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch index 6373f94e3..211fb732a 100644 --- a/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch +++ b/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch @@ -1,27 +1,34 @@ -From c0bb07ba816524d69de22c22fcb7f7b9b95fbb11 Mon Sep 17 00:00:00 2001 -From: Damian Hobson-Garcia -Date: Thu, 27 Apr 2017 16:47:00 +0900 -Subject: [PATCH 1/3] Add virtual output support +From b6d084f68434fea7402d4989d4d8344523b1a939 Mon Sep 17 00:00:00 2001 +From: Harunobu Kurokawa +Date: Thu, 10 Aug 2017 15:42:38 +0900 +Subject: [PATCH 1/4] Add virtual output support + +This patch is ported to weston 2.0.0. -Following patch ported to Weston 1.11 with minor updates ---------- -Author: Grigory Kletsko -Date: Wed Nov 2 17:14:43 2016 +0300 +Author: Damian Hobson-Garcia +Date: Thu Apr 27 16:47:00 2017 +0900 -To enable virtual output set "virtual" property in core section -to desirable number of virtual outputs. Then add settings to -each virtual output in output sections. Name of the outputs -will be virtual1, virtual2... etc. ------------- +Following patch ported to Weston 1.11 with minor updates + ---------- + Author: Grigory Kletsko + Date: Wed Nov 2 17:14:43 2016 +0300 + + To enable virtual output set "virtual" property in core section + to desirable number of virtual outputs. Then add settings to + each virtual output in output sections. Name of the outputs + will be virtual1, virtual2... etc. + ------------ --- - src/compositor-drm.c | 310 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 310 insertions(+) + libweston/compositor-drm.c | 352 +++++++++++++++++++++++++++++++++++++++++++++ + libweston/compositor-drm.h | 1 + + 2 files changed, 353 insertions(+) -diff --git a/src/compositor-drm.c b/src/compositor-drm.c -index abc9408..fc5a2ff 100644 ---- a/src/compositor-drm.c -+++ b/src/compositor-drm.c -@@ -199,6 +199,11 @@ struct drm_output { +diff --git a/libweston/compositor-drm.c b/libweston/compositor-drm.c +index 1d38f05..d0f07e9 100644 +--- a/libweston/compositor-drm.c ++++ b/libweston/compositor-drm.c +@@ -182,6 +182,11 @@ struct drm_output { struct vaapi_recorder *recorder; struct wl_listener recorder_frame_listener; @@ -33,44 +40,168 @@ index abc9408..fc5a2ff 100644 }; /* -@@ -1474,6 +1479,33 @@ drm_output_destroy(struct weston_output *output_base) - free(output); +@@ -211,6 +216,9 @@ struct drm_sprite { + + static struct gl_renderer_interface *gl_renderer; + ++static int ++recorder_enable(struct drm_backend *b, struct drm_output *output); ++ + static const char default_seat[] = "seat0"; + + static inline struct drm_output * +@@ -2347,6 +2355,99 @@ connector_get_current_mode(drmModeConnector *connector, int drm_fd, } -+static void -+virtual_output_destroy(struct weston_output *output_base) + static int ++virtual_output_set_mode(struct weston_output *base, ++ enum weston_drm_backend_output_mode mode, ++ const char *modeline) +{ -+ struct drm_output *output = (struct drm_output *) output_base; -+ struct drm_backend *c = -+ (struct drm_backend *) output->base.compositor; ++ struct drm_output *output = to_drm_output(base); ++ struct drm_backend *b = to_drm_backend(base->compositor); ++ struct weston_config *config = wet_get_config(b->compositor); + -+ c->crtc_allocator &= ~(1 << output->crtc_id); -+ c->connector_allocator &= ~(1 << output->connector_id); ++ struct drm_mode *drm_mode, *next, *current; ++ char *s; ++ int valid_mode; ++ int recorded_output; ++ int width, height, scale, fps; ++ struct weston_config_section *section; ++ uint32_t transform; ++ drmModeModeInfo crtc_mode; + -+ if (c->use_pixman) { -+ drm_output_fini_pixman(output); ++ output->base.make = "CogentEmbedded,Inc"; ++ ++ section = weston_config_get_section(config, "output", "name", ++ output->base.name); ++ ++ weston_config_section_get_bool(section, "recorder", &recorded_output, 0); ++ ++ if (recorded_output) { ++ output->base.model = "Virtual RTP Display"; + } else { -+ gl_renderer->output_destroy(output_base); -+ gbm_surface_destroy(output->gbm_surface); ++ output->base.model = "Virtual Display"; + } + -+ weston_plane_release(&output->fb_plane); -+ weston_plane_release(&output->cursor_plane); ++ output->base.serial_number = ""; ++ wl_list_init(&output->base.mode_list); + -+ weston_output_destroy(&output->base); ++ if (mode == WESTON_DRM_BACKEND_OUTPUT_PREFERRED) { ++ if (modeline && sscanf(modeline, "%dx%d@%d", &width, &height, &fps) >= 3) ++ valid_mode = 1; ++ } + ++ 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); + -+ wl_event_source_remove(output->virtual_finish_frame_timer); -+ free(output); ++ weston_config_section_get_string(section, "seat", &s, ""); ++ free(s); ++ ++ output->original_crtc = NULL; ++ output->dpms_prop = NULL; ++ ++ /* set static mode */ ++ if (valid_mode) { ++ /* TODO: calculate proper mode settings to get desirable framerate */ ++ drmModeModeInfo static_drm_mode = { ++ width * height * fps, ++ width, 0, 0, width, width, ++ height, 0, 0, height, height, ++ fps * 1000, ++ 0, //flags ++ 0, //type ++ "virtual" ++ }; ++ drm_mode = drm_output_add_mode(output, &static_drm_mode); ++ if (!drm_mode) ++ goto err_free; ++ ++ drm_mode->base.refresh = fps * 1000; ++ } ++ ++ current = drm_output_choose_initial_mode(b, output, mode, &modeline, ++ &crtc_mode); ++ if (!current) ++ goto err_free; ++ output->base.current_mode = ¤t->base; ++ output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT; ++ ++ return 0; ++ ++err_free: ++ drmModeFreeCrtc(output->original_crtc); ++ output->original_crtc = NULL; ++ ++ wl_list_for_each_safe(drm_mode, next, &output->base.mode_list, ++ base.link) { ++ wl_list_remove(&drm_mode->base.link); ++ free(drm_mode); ++ } ++ ++ return -1; +} + - /** - * Find the closest-matching mode for a given target - * -@@ -2649,6 +2681,270 @@ err_free: ++static int + drm_output_set_mode(struct weston_output *base, + enum weston_drm_backend_output_mode mode, + const char *modeline) +@@ -2357,6 +2458,8 @@ drm_output_set_mode(struct weston_output *base, + struct drm_mode *drm_mode, *next, *current; + drmModeModeInfo crtc_mode; + int i; ++ if ( output->virtual == 1 ) ++ return virtual_output_set_mode(base, mode, modeline); + + output->base.make = "unknown"; + output->base.model = "unknown"; +@@ -2453,6 +2556,10 @@ drm_output_enable(struct weston_output *base) + weston_log("Failed to initialize backlight\n"); + } + ++ /* enable GST recording-streaming */ ++ if (b->enable_recorder) ++ recorder_enable(b, output); ++ + output->base.start_repaint_loop = drm_output_start_repaint_loop; + output->base.repaint = drm_output_repaint; + output->base.assign_planes = drm_assign_planes; +@@ -2630,6 +2737,227 @@ create_output_for_connector(struct drm_backend *b, } static void ++virtual_output_deinit(struct weston_output *base) ++{ ++ struct drm_output *output = to_drm_output(base); ++ struct drm_backend *b = to_drm_backend(base->compositor); ++ ++ if (b->use_pixman) ++ drm_output_fini_pixman(output); ++ else ++ drm_output_fini_egl(output); ++ ++ weston_plane_release(&output->fb_plane); ++ weston_plane_release(&output->cursor_plane); ++} ++ ++static void ++virtual_output_destroy(struct weston_output *base) ++{ ++ struct drm_output *output = to_drm_output(base); ++ ++ if (output->base.enabled) ++ virtual_output_deinit(&output->base); ++ ++ weston_output_destroy(&output->base); ++ ++ free(output); ++} ++ ++static void +virtual_output_start_repaint_loop(struct weston_output *output) +{ + struct timespec now; @@ -91,7 +222,7 @@ index abc9408..fc5a2ff 100644 + + msec_next = (output->base.frame_time + 1000000UL / output->base.current_mode->refresh) ; + -+ if (output->destroy_pending) ++ if (output->disable_pending || output->destroy_pending) + return -1; + + if (!output->next) @@ -150,160 +281,36 @@ index abc9408..fc5a2ff 100644 + return 1; +} + -+/* -+ * Virtual output connector that could be used for simulating output -+ * device for clients and/or streaming of video -+ */ +static int -+create_output_for_virtual_connector(struct drm_backend *b, -+ int x, int y, struct udev_device *drm_device) ++virtual_output_enable(struct weston_output *base) +{ -+ struct wl_event_loop *loop; -+ static int virtual_id = 1; /* as other outputs numbered */ -+ struct drm_output *output; -+ struct drm_mode *drm_mode, *next, *current; ++ struct drm_output *output = to_drm_output(base); ++ struct drm_backend *b = to_drm_backend(base->compositor); + struct weston_mode *m; -+ struct weston_config_section *section; -+ int width, height, scale, fps; -+ int recorded_output; -+ char name[32], *s; -+ enum weston_drm_backend_output_mode mode; -+ struct weston_drm_backend_output_config config = {{ 0 }}; -+ uint32_t transform; -+ int valid_mode; -+ drmModeModeInfo crtc_mode; -+ -+ output = zalloc(sizeof *output); -+ if (output == NULL) -+ return -1; -+ -+ output->base.subpixel = WL_OUTPUT_SUBPIXEL_NONE; //drm_subpixel_to_wayland(connector->subpixel); -+ output->base.make = "CogentEmbedded,Inc"; -+ output->base.serial_number = ""; -+ wl_list_init(&output->base.mode_list); -+ -+ snprintf(name, 32, "virtual%d", virtual_id++); -+ output->base.name = strdup(name); -+ -+ section = weston_config_get_section(b->compositor->config, "output", "name", -+ output->base.name); + -+ weston_config_section_get_bool(section, "recorder", &recorded_output, 0); -+ if (recorded_output) { -+ char model[64]; -+ char *ip; -+ int port; -+ -+ weston_config_section_get_string(section, "ip", &ip, ""); -+ weston_config_section_get_int(section, "port", &port, -1); -+ snprintf(model, 64, "Virtual RTP %s:%d", ip, port); -+ output->base.model = strdup(model); -+ } else { -+ output->base.model = "Virtual Display"; -+ } -+ -+ mode = b->configure_output(b->compositor, b->use_current_mode, -+ output->base.name, &config); -+ -+ if (mode == WESTON_DRM_BACKEND_OUTPUT_PREFERRED) { -+ if (config.modeline && sscanf(config.modeline, "%dx%d@%d", &width, &height, &fps) >= 3) -+ valid_mode = 1; -+ } -+ -+ 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 (parse_gbm_format(config.gbm_format, b->gbm_format, &output->gbm_format) == -1) -+ output->gbm_format = b->gbm_format; -+ -+ weston_config_section_get_string(section, "seat", &s, ""); -+ setup_output_seat_constraint(b, &output->base, s); -+ free(s); -+ -+ output->pipe = 0; -+ b->crtc_allocator |= (1 << output->crtc_id); -+ output->connector_id = 0; -+ b->connector_allocator |= (1 << output->connector_id); -+ -+ /* this is virtual output */ -+ output->virtual = 1; -+ -+ -+ output->original_crtc = NULL; -+ output->dpms_prop = NULL; -+ -+ /* set static mode */ -+ if (valid_mode) { -+ /* TODO: calculate proper mode settings to get desirable framerate */ -+ drmModeModeInfo static_drm_mode = { -+ width * height * fps, -+ width, 0, 0, width, width, -+ height, 0, 0, height, height, -+ fps * 1000, -+ 0, //flags -+ 0, //type -+ "virtual" -+ }; -+ -+ drm_mode = drm_output_add_mode(output, &static_drm_mode); -+ if (!drm_mode) -+ goto err_free; -+ -+ drm_mode->base.refresh = fps * 1000; -+ } -+ -+ 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(b, output, mode, &config, -+ &crtc_mode); -+ if (!current) -+ goto err_free; -+ output->base.current_mode = ¤t->base; -+ output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT; -+ -+ weston_output_init(&output->base, b->compositor, x, y, -+ 100, 100 * height / width, /* FIXME: calculate proper mm_width and mm_height */ -+ config.base.transform, config.base.scale); + if (b->use_pixman) { + if (drm_output_init_pixman(output, b) < 0) { + weston_log("Failed to init output pixman state\n"); -+ goto err_output; ++ goto err_free; + } + } else if (drm_output_init_egl(output, b) < 0) { + weston_log("Failed to init output gl state\n"); -+ goto err_output; ++ goto err_free; + } + -+ output->backlight = NULL; -+ -+ weston_compositor_add_output(b->compositor, &output->base); -+ -+ output->base.connection_internal = 1; -+ -+ loop = wl_display_get_event_loop(b->compositor->wl_display); -+ output->virtual_finish_frame_timer = wl_event_loop_add_timer(loop, virtual_finish_frame_handler, output); -+ + output->base.start_repaint_loop = virtual_output_start_repaint_loop; + output->base.repaint = virtual_output_repaint; -+ output->base.destroy = virtual_output_destroy; + output->base.assign_planes = NULL; -+ output->base.set_backlight = NULL; + output->base.set_dpms = NULL; + output->base.switch_mode = drm_output_switch_mode; + + output->base.gamma_size = 0; + output->base.set_gamma = drm_output_set_gamma; + -+ weston_plane_init(&output->cursor_plane, b->compositor, 0, 0); ++ output->base.subpixel = WL_OUTPUT_SUBPIXEL_NONE; //drm_subpixel_to_wayland(connector->subpixel); ++ ++ weston_plane_init(&output->cursor_plane, b->compositor, ++ INT32_MIN, INT32_MIN); + weston_plane_init(&output->fb_plane, b->compositor, 0, 0); + + weston_compositor_stack_plane(b->compositor, &output->cursor_plane, NULL); @@ -316,60 +323,148 @@ index abc9408..fc5a2ff 100644 + weston_log_continue(STAMP_SPACE "mode %dx%d@%.1f\n", + m->width, m->height, m->refresh / 1000.0); + ++ /* enable GST recording-streaming */ ++ if (b->enable_recorder) ++ recorder_enable(b, output); ++ + return 0; + -+err_output: -+ weston_output_destroy(&output->base); +err_free: -+ wl_list_for_each_safe(drm_mode, next, &output->base.mode_list, -+ base.link) { -+ wl_list_remove(&drm_mode->base.link); -+ free(drm_mode); -+ } -+ -+ b->crtc_allocator &= ~(1 << output->crtc_id); -+ b->connector_allocator &= ~(1 << output->connector_id); -+ free(output); + + return -1; +} + ++ ++static int ++virtual_output_disable(struct weston_output *base) ++{ ++ struct drm_output *output = to_drm_output(base); ++ ++ if (output->base.enabled) ++ virtual_output_deinit(&output->base); ++ ++ output->disable_pending = 0; ++ ++ weston_log("Disabling output %s\n", output->base.name); ++ ++ return 0; ++} ++ ++/* ++ * Virtual output connector that could be used for simulating output ++ * device for clients and/or streaming of video ++ */ ++static int ++create_output_for_virtual_connector(struct drm_backend *b, ++ struct udev_device *drm_device) ++{ ++ struct wl_event_loop *loop; ++ struct drm_output *output; ++ static int virtual_id = 1; /* as other outputs numbered */ ++ char name[32], *s; ++ ++ output = zalloc(sizeof *output); ++ if (output == NULL) ++ return -1; ++ ++ output->pipe = 0; ++ output->connector_id = 0; ++ ++ /* this is virtual output */ ++ output->virtual = 1; ++ ++ output->backlight = NULL; ++ ++ loop = wl_display_get_event_loop(b->compositor->wl_display); ++ output->virtual_finish_frame_timer = wl_event_loop_add_timer(loop, virtual_finish_frame_handler, output); ++ ++ output->base.enable = virtual_output_enable; ++ output->base.destroy = virtual_output_destroy; ++ output->base.disable = virtual_output_disable; ++ ++ output->destroy_pending = 0; ++ output->disable_pending = 0; ++ output->original_crtc = NULL; ++ snprintf(name, 32, "virtual%d", virtual_id++); ++ output->base.name = strdup(name); ++ ++ weston_output_init(&output->base, b->compositor); ++ weston_compositor_add_pending_output(&output->base, b->compositor); ++ ++ return 0; ++} ++ +static void create_sprites(struct drm_backend *b) { struct drm_sprite *sprite; -@@ -2721,10 +3017,12 @@ static int - create_outputs(struct drm_backend *b, uint32_t option_connector, - struct udev_device *drm_device) +@@ -2701,9 +3029,12 @@ destroy_sprites(struct drm_backend *backend) + static int + create_outputs(struct drm_backend *b, struct udev_device *drm_device) { + struct weston_config_section *section; ++ struct weston_config *config = wet_get_config(b->compositor); drmModeConnector *connector; drmModeRes *resources; int i; - int x = 0, y = 0; + int virtual; resources = drmModeGetResources(b->drm.fd); if (!resources) { -@@ -2770,6 +3068,18 @@ create_outputs(struct drm_backend *b, uint32_t option_connector, - drmModeFreeConnector(connector); +@@ -2735,6 +3066,14 @@ create_outputs(struct drm_backend *b, struct udev_device *drm_device) + } } -+ section = weston_config_get_section(b->compositor->config, "core", NULL, NULL); ++ section = weston_config_get_section(config, "core", NULL, NULL); + weston_config_section_get_int(section, "virtual", &virtual, 0); + + for (i = 0; i < virtual; i++) { -+ if (create_output_for_virtual_connector(b, x, y, -+ drm_device) < 0) ++ if (create_output_for_virtual_connector(b, drm_device) < 0) + continue; -+ x += container_of(b->compositor->output_list.prev, -+ struct weston_output, -+ link)->width; + } + - if (wl_list_empty(&b->compositor->output_list)) { + if (wl_list_empty(&b->compositor->output_list) && + wl_list_empty(&b->compositor->pending_output_list)) weston_log("No currently active connector found.\n"); - drmModeFreeResources(resources); +@@ -3181,6 +3520,12 @@ renderer_switch_binding(struct weston_keyboard *keyboard, uint32_t time, + switch_to_gl_renderer(b); + } + ++static const struct weston_drm_output_api virtual_api = { ++ virtual_output_set_mode, ++ drm_output_set_gbm_format, ++ drm_output_set_seat, ++}; ++ + static const struct weston_drm_output_api api = { + drm_output_set_mode, + drm_output_set_gbm_format, +@@ -3346,6 +3691,13 @@ drm_backend_create(struct weston_compositor *compositor, + goto err_udev_monitor; + } + ++ ret = weston_plugin_api_register(compositor, WESTON_DRM_VIRTUAL_OUTPUT_API_NAME, ++ &virtual_api, sizeof(virtual_api)); ++ ++ if (ret < 0) { ++ weston_log("Failed to register output API.\n"); ++ goto err_udev_monitor; ++ } + return b; + + err_udev_monitor: +diff --git a/libweston/compositor-drm.h b/libweston/compositor-drm.h +index 2e2995a..00171c8 100644 +--- a/libweston/compositor-drm.h ++++ b/libweston/compositor-drm.h +@@ -53,6 +53,7 @@ enum weston_drm_backend_output_mode { + }; + + #define WESTON_DRM_OUTPUT_API_NAME "weston_drm_output_api_v1" ++#define WESTON_DRM_VIRTUAL_OUTPUT_API_NAME "weston_virtual_output_api_v1" + + struct weston_drm_output_api { + /** The mode to be used by the output. Refer to the documentation -- -1.9.1 +2.9.2