summaryrefslogtreecommitdiffstats
path: root/meta-rcar-gen2/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch
diff options
context:
space:
mode:
authorGrigory Kletsko <grigory.kletsko@cogentembedded.com>2016-11-02 17:43:18 +0300
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2016-12-17 17:25:39 +0000
commit284877cb63856744f2af7145d722d2ce9c6d9cb8 (patch)
tree90654d5d6cb0e3f30c1e3b1f79e7ac41dbdae666 /meta-rcar-gen2/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch
parentbaeac5c376980853149a85eab528a60f28d74bcf (diff)
Add sharing screen support to Weston via h.264
This patch enables sharing screen support between IVI and meter cluster for CES2017 demo using weston. h264 streaming data on the surface can be sent to the different soc via rtp protocol. Change-Id: Ie4d00e369039e57a19940284a7d82aba684a4bf6 Signed-off-by: Grigory Kletsko <grigory.kletsko@cogentembedded.com>
Diffstat (limited to 'meta-rcar-gen2/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch')
-rw-r--r--meta-rcar-gen2/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch391
1 files changed, 391 insertions, 0 deletions
diff --git a/meta-rcar-gen2/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch b/meta-rcar-gen2/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch
new file mode 100644
index 0000000..51c2671
--- /dev/null
+++ b/meta-rcar-gen2/recipes-graphics/wayland/weston/0001-Add-virtual-output-support.patch
@@ -0,0 +1,391 @@
+From f26e3ef1f484319a6c803158af16050574363587 Mon Sep 17 00:00:00 2001
+From: Grigory Kletsko <grigory.kletsko@cogentembedded.com>
+Date: Wed, 2 Nov 2016 17:14:43 +0300
+Subject: [PATCH 1/2] Add virtual output support
+
+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.
+
+Signed-off-by: Grigory Kletsko <grigory.kletsko@cogentembedded.com>
+Signed-off-by: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
+---
+ src/compositor-drm.c | 329 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 329 insertions(+)
+
+diff --git a/src/compositor-drm.c b/src/compositor-drm.c
+index ab493ad..09611a4 100644
+--- a/src/compositor-drm.c
++++ b/src/compositor-drm.c
+@@ -193,6 +193,11 @@ struct drm_output {
+
+ struct vaapi_recorder *recorder;
+ struct wl_listener recorder_frame_listener;
++
++ /* not real output device */
++ int virtual;
++ /* Timer for updating frame */
++ struct wl_event_source *virtual_finish_frame_timer;
+ };
+
+ /*
+@@ -1337,6 +1342,33 @@ drm_output_destroy(struct weston_output *output_base)
+ free(output);
+ }
+
++static void
++virtual_output_destroy(struct weston_output *output_base)
++{
++ struct drm_output *output = (struct drm_output *) output_base;
++ struct drm_backend *c =
++ (struct drm_backend *) output->base.compositor;
++
++ c->crtc_allocator &= ~(1 << output->crtc_id);
++ c->connector_allocator &= ~(1 << output->connector_id);
++
++ if (c->use_pixman) {
++ drm_output_fini_pixman(output);
++ } else {
++ gl_renderer->output_destroy(output_base);
++ gbm_surface_destroy(output->surface);
++ }
++
++ weston_plane_release(&output->fb_plane);
++ weston_plane_release(&output->cursor_plane);
++
++ weston_output_destroy(&output->base);
++
++
++ wl_event_source_remove(output->virtual_finish_frame_timer);
++ free(output);
++}
++
+ /**
+ * Find the closest-matching mode for a given target
+ *
+@@ -2459,6 +2491,289 @@ err_free:
+ }
+
+ static void
++virtual_output_start_repaint_loop(struct weston_output *output)
++{
++ struct timespec now;
++
++ weston_compositor_read_presentation_clock(output->compositor, &now);
++ weston_output_finish_frame(output, &now, PRESENTATION_FEEDBACK_INVALID);
++}
++
++
++static int
++virtual_output_repaint(struct weston_output *output_base,
++ pixman_region32_t *damage)
++{
++ struct drm_output *output = (struct drm_output *) output_base;
++ struct timespec ts;
++ uint32_t msec_next;
++ uint32_t msec_current;
++
++ msec_next = (output->base.frame_time + 1000000UL / output->base.current_mode->refresh) ;
++
++ if (output->destroy_pending)
++ return -1;
++
++ if (!output->next)
++ drm_output_render(output, damage);
++ if (!output->next)
++ return -1;
++
++ drm_output_set_cursor(output);
++
++ output->page_flip_pending = 1;
++
++ weston_compositor_read_presentation_clock(output_base->compositor, &ts);
++
++ msec_current = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
++
++ /*
++ * If we somehow late with updating frame, then fireup timer immediately (1 msec)
++ */
++ wl_event_source_timer_update(output->virtual_finish_frame_timer, (msec_next > msec_current) ?
++ msec_next - msec_current : 1);
++
++ return 0;
++}
++
++static int
++virtual_finish_frame_handler(void *data)
++{
++ struct drm_output *output = (struct drm_output *) data;
++ struct timespec ts;
++
++ /* We don't set page_flip_pending on start_repaint_loop, in that case
++ * we just want to page flip to the current buffer to get an accurate
++ * timestamp */
++ if (output->page_flip_pending) {
++ drm_output_release_fb(output, output->current);
++ output->current = output->next;
++ output->next = NULL;
++ }
++
++ output->page_flip_pending = 0;
++
++ if (output->destroy_pending)
++ drm_output_destroy(&output->base);
++ else if (!output->vblank_pending) {
++ weston_compositor_read_presentation_clock(output->base.compositor, &ts);
++
++ weston_output_finish_frame(&output->base, &ts,
++ PRESENTATION_FEEDBACK_INVALID);
++
++ /* We can't call this from frame_notify, because the output's
++ * repaint needed flag is cleared just after that */
++ if (output->recorder)
++ weston_output_schedule_repaint(&output->base);
++ }
++
++ 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 *ec,
++ int x, int y, struct udev_device *drm_device)
++{
++ struct wl_event_loop *loop;
++ static int virtual_id = 1; /* as other outputs numbered */
++ struct drm_output *output;
++ struct drm_mode *drm_mode, *next, *configured;
++ struct weston_mode *m;
++ struct weston_config_section *section;
++ drmModeModeInfo modeline;
++ int i, width, height, scale, fps;
++ int recorded_output;
++ char name[32], *s;
++ enum output_config config;
++ uint32_t transform;
++
++ 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(ec->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, "<nil>");
++ 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";
++ }
++
++ weston_config_section_get_string(section, "mode", &s, "preferred");
++ if (strcmp(s, "off") == 0)
++ config = OUTPUT_CONFIG_OFF;
++ else if (sscanf(s, "%dx%d@%d", &width, &height, &fps) == 3)
++ 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);
++ width = 1280;
++ height = 720;
++ fps = 60;
++ config = OUTPUT_CONFIG_MODE;
++ }
++ 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,
++ ec->format,
++ &output->format) == -1)
++ output->format = ec->format;
++
++ weston_config_section_get_string(section, "seat", &s, "");
++ setup_output_seat_constraint(ec, &output->base, s);
++ free(s);
++
++ output->pipe = i;
++ ec->crtc_allocator |= (1 << output->crtc_id);
++ output->connector_id = 0;
++ ec->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 (1) {
++ /* 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 (config == OUTPUT_CONFIG_OFF) {
++ weston_log("Disabling output %s\n", output->base.name);
++ drmModeSetCrtc(ec->drm.fd, output->crtc_id,
++ 0, 0, 0, 0, 0, NULL);
++ goto err_free;
++ }
++
++ wl_list_for_each_reverse(drm_mode, &output->base.mode_list, base.link) {
++ if (config == OUTPUT_CONFIG_MODE &&
++ width == drm_mode->base.width &&
++ height == drm_mode->base.height)
++ configured = drm_mode;
++ }
++
++ output->base.current_mode = &configured->base;
++
++ if (output->base.current_mode == NULL) {
++ weston_log("no available modes for %s\n", output->base.name);
++ goto err_free;
++ }
++
++ output->base.current_mode->flags |= WL_OUTPUT_MODE_CURRENT;
++
++ weston_output_init(&output->base, ec->compositor, x, y,
++ 100, 100 * height / width, /* FIXME: calculate proper mm_width and mm_height */
++ transform, scale);
++
++ if (ec->use_pixman) {
++ if (drm_output_init_pixman(output, ec) < 0) {
++ weston_log("Failed to init output pixman state\n");
++ goto err_output;
++ }
++ } else if (drm_output_init_egl(output, ec) < 0) {
++ weston_log("Failed to init output gl state\n");
++ goto err_output;
++ }
++
++ output->backlight = NULL;
++
++ weston_compositor_add_output(ec->compositor, &output->base);
++
++ output->base.connection_internal = 1;
++
++ loop = wl_display_get_event_loop(ec->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, ec->compositor, 0, 0);
++ weston_plane_init(&output->fb_plane, ec->compositor, 0, 0);
++
++ weston_compositor_stack_plane(ec->compositor, &output->cursor_plane, NULL);
++ weston_compositor_stack_plane(ec->compositor, &output->fb_plane,
++ &ec->compositor->primary_plane);
++
++ weston_log("Output %s, ()\n",
++ output->base.name);
++ wl_list_for_each(m, &output->base.mode_list, link)
++ weston_log_continue(STAMP_SPACE "mode %dx%d@%.1f\n",
++ m->width, m->height, m->refresh / 1000.0);
++
++ 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);
++ }
++
++ ec->crtc_allocator &= ~(1 << output->crtc_id);
++ ec->connector_allocator &= ~(1 << output->connector_id);
++ free(output);
++
++ return -1;
++}
++
++static void
+ create_sprites(struct drm_backend *b)
+ {
+ struct drm_sprite *sprite;
+@@ -2531,10 +2846,12 @@ static int
+ create_outputs(struct drm_backend *b, uint32_t option_connector,
+ struct udev_device *drm_device)
+ {
++ struct weston_config_section *section;
+ drmModeConnector *connector;
+ drmModeRes *resources;
+ int i;
+ int x = 0, y = 0;
++ int virtual;
+
+ resources = drmModeGetResources(b->drm.fd);
+ if (!resources) {
+@@ -2580,6 +2897,18 @@ create_outputs(struct drm_backend *b, uint32_t option_connector,
+ drmModeFreeConnector(connector);
+ }
+
++ section = weston_config_get_section(b->compositor->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)
++ continue;
++ x += container_of(b->compositor->output_list.prev,
++ struct weston_output,
++ link)->width;
++ }
++
+ if (wl_list_empty(&b->compositor->output_list)) {
+ weston_log("No currently active connector found.\n");
+ drmModeFreeResources(resources);
+--
+2.7.4
+