Fix most for kernel 4.14
[AGL/meta-agl-demo.git] / recipes-graphics / wayland / weston / 0001-Add-virtual-output-support.patch
index 6373f94..211fb73 100644 (file)
@@ -1,27 +1,34 @@
-From c0bb07ba816524d69de22c22fcb7f7b9b95fbb11 Mon Sep 17 00:00:00 2001
-From: Damian Hobson-Garcia <dhobsong@igel.co.jp>
-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 <harunobu.kurokawa.dn@renesas.com>
+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 <grigory.kletsko@cogentembedded.com>
-Date:   Wed Nov 2 17:14:43 2016 +0300
+Author: Damian Hobson-Garcia <dhobsong@igel.co.jp>
+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 <grigory.kletsko@cogentembedded.com>
+  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 = &current->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, "<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";
-+      }
-+
-+      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 = &current->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