]> code.ossystems Code Review - meta-freescale.git/commitdiff
weston: Add clone mode support for multi display
authorTom Hochstein <tom.hochstein@nxp.com>
Fri, 7 Oct 2016 22:36:56 +0000 (17:36 -0500)
committerOtavio Salvador <otavio@ossystems.com.br>
Tue, 18 Oct 2016 18:26:14 +0000 (16:26 -0200)
Support showing the same contents on multiple displays.
Use the following command to enable multi-display:
    openvt -v -- weston-launch -- --idle-time=0 --use-g2d=1 --device=/dev/fb0,/dev/fb4 --clone-mode --log=/var/log/weston.log

Signed-off-by: Tom Hochstein <tom.hochstein@nxp.com>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
recipes-graphics/wayland/weston/0012-MGS-1783-xwld-Add-clone-mode-support-for-multi-displ.patch [new file with mode: 0644]
recipes-graphics/wayland/weston_%.bbappend

diff --git a/recipes-graphics/wayland/weston/0012-MGS-1783-xwld-Add-clone-mode-support-for-multi-displ.patch b/recipes-graphics/wayland/weston/0012-MGS-1783-xwld-Add-clone-mode-support-for-multi-displ.patch
new file mode 100644 (file)
index 0000000..10bae4d
--- /dev/null
@@ -0,0 +1,421 @@
+From f2025a7e8c178b8c52c2ca553459a7fea6caf5c8 Mon Sep 17 00:00:00 2001
+From: "yong.gan" <yong.gan@nxp.com>
+Date: Tue, 17 May 2016 09:10:50 +0800
+Subject: [PATCH 1/2] MGS-1783: xwld: Add clone mode support for multi display
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Support showing the same contents on multiple displays.
+Use the following command to enable multi-display:
+    openvt -v -- weston-launch -- --idle-time=0 --use-g2d=1 --device=/dev/fb0,/dev/fb4 --clone-mode --log=/var/log/weston.log
+
+Upstream-Status: Inappropriate [i.MX specific]
+Date: May 16, 2016
+Signed-off-by: Yong Gan <yong.gan@nxp.com>
+---
+ src/compositor-fbdev.c |  33 +++++++---
+ src/g2d-renderer.c     | 171 ++++++++++++++++++++++++++++++++++++++++---------
+ src/g2d-renderer.h     |   4 +-
+ 3 files changed, 167 insertions(+), 41 deletions(-)
+
+Index: weston-1.11.0/src/compositor-fbdev.c
+===================================================================
+--- weston-1.11.0.orig/src/compositor-fbdev.c  2016-10-06 13:17:41.738142236 -0500
++++ weston-1.11.0/src/compositor-fbdev.c       2016-10-06 13:28:22.000000000 -0500
+@@ -61,6 +61,8 @@
+       struct udev_input input;
+       int use_pixman;
+       int use_g2d;
++      int clone_mode;
++      char *clone_device;
+       uint32_t output_transform;
+       struct wl_listener session_listener;
+ #ifdef ENABLE_EGL
+@@ -525,12 +527,15 @@
+               if (pixman_renderer_output_create(&output->base) < 0)
+                       goto out_hw_surface;
+       } else if(backend->use_g2d) {
++              const char *g2d_device = device;
++              if (backend->clone_mode)
++                      g2d_device = backend->clone_device;
++
+               if (g2d_renderer->output_create(&output->base,
+-                                      backend->compositor->wl_display, device) < 0) {
++                                      backend->compositor->wl_display, g2d_device) < 0) {
+                       weston_log("g2d_renderer_output_create failed.\n");
+                       goto out_hw_surface;
+               }
+-
+       } else {
+ #ifdef ENABLE_EGL
+               setenv("HYBRIS_EGLPLATFORM", "wayland", 1);
+@@ -803,6 +808,8 @@
+       backend->prev_state = WESTON_COMPOSITOR_ACTIVE;
+       backend->use_pixman = !(param->use_gl || param->use_g2d);
+       backend->use_g2d = param->use_g2d;
++      backend->clone_mode = param->clone_mode;
++      backend->clone_device = param->device;
+       backend->output_transform = param->output_transform;
+       weston_setup_vt_switch_bindings(compositor);
+@@ -844,16 +851,21 @@
+               displays[dispCount][k] = '\0';
+               dispCount++;
+-              for(i=0; i<dispCount; i++)
+-              {
+-                      if (fbdev_output_create(backend, x, y, displays[i]) < 0)
++              if(backend->clone_mode){
++                      if (fbdev_output_create(backend, x, y, displays[0]) < 0)
+                               goto out_launcher;
+-                      x += container_of(backend->compositor->output_list.prev,
+-                                                                struct weston_output,
+-                                                                link)->width;
++              }
++              else{
++                      for(i= 0; i < dispCount; i++){
++                              if (fbdev_output_create(backend, x, y, displays[i]) < 0)
++                                      goto out_launcher;
++                              x += container_of(backend->compositor->output_list.prev,
++                                              struct weston_output,
++                                              link)->width;
++                      }
+               }
+       }
+-       else {
++      else {
+ #ifdef ENABLE_EGL
+               gl_renderer = weston_load_module("gl-renderer.so",
+                                                "gl_renderer_interface");
+Index: weston-1.11.0/src/g2d-renderer.c
+===================================================================
+--- weston-1.11.0.orig/src/g2d-renderer.c      2016-10-06 13:17:41.738142236 -0500
++++ weston-1.11.0/src/g2d-renderer.c   2016-10-06 13:17:41.734142216 -0500
+@@ -37,15 +37,16 @@
+ #include <sys/ioctl.h>
+ #include <fcntl.h>
+ #include <unistd.h>
++#include <g2dExt.h>
++#include <HAL/gc_hal_eglplatform.h>
+ #include "compositor.h"
+ #include "g2d-renderer.h"
+ #include "vertex-clipping.h"
+ #include "shared/helpers.h"
+-#include "HAL/gc_hal_eglplatform.h"
+-#include "g2dExt.h"
+ #define BUFFER_DAMAGE_COUNT 2
++extern struct wl_global* gcoOS_WaylandCreateVivGlobal(struct wl_display* display);
+ typedef struct _g2dRECT
+ {
+@@ -63,6 +64,7 @@
+       size_t buffer_length; /* length of frame buffer memory in bytes */
+       size_t physical;
+       enum g2d_format pixel_format; /* frame buffer pixel format */
++      int fb_fd;
+ };
+ struct g2d_output_state {
+@@ -74,10 +76,12 @@
+       struct g2d_surfaceEx offscreenSurface;
+       struct g2d_buf *offscreen_buf;
+       struct fb_screeninfo fb_info;
++      struct fb_screeninfo *mirror_fb_info;
++      struct g2d_surfaceEx *mirrorSurf;
+       int directBlit;
++      int clone_display_num;
+       int width;
+       int height;
+-      int fb_fd;
+ };
+ struct g2d_surface_state {
+@@ -366,7 +370,7 @@
+       struct g2d_output_state *go = get_output_state(output);
+       go->fb_info.varinfo.yoffset  = go->activebuffer * go->fb_info.y_resolution;
+-      if(ioctl(go->fb_fd, FBIOPAN_DISPLAY, &(go->fb_info.varinfo)) < 0)
++      if(ioctl(go->fb_info.fb_fd, FBIOPAN_DISPLAY, &(go->fb_info.varinfo)) < 0)
+       {
+               weston_log("FBIOPAN_DISPLAY Failed\n");
+       }
+@@ -388,6 +392,28 @@
+                       &go->renderSurf[go->activebuffer], &srcRect, &dstrect);
+       }
++      if(go->clone_display_num)
++      {
++              int i = 0;
++              for(i = 0; i < go->clone_display_num; i++)
++              {
++                      g2dRECT srcRect  = {0, 0, go->renderSurf[go->activebuffer].base.width, go->renderSurf[go->activebuffer].base.height};
++                      g2dRECT dstrect  = {0, 0, go->mirrorSurf[i].base.width, go->mirrorSurf[i].base.height};
++                      g2dRECT clipRect = srcRect;
++                      g2d_set_clipping(gr->handle, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
++                      if(go->directBlit || go->nNumBuffers > 1)
++                      {
++                              g2d_blitSurface(gr->handle, &go->renderSurf[go->activebuffer],
++                              &go->mirrorSurf[i], &srcRect, &dstrect);
++                      }
++                      else
++                      {
++                              g2d_blitSurface(gr->handle, &go->offscreenSurface,
++                                      &go->mirrorSurf[i], &srcRect, &dstrect);
++                      }
++              }
++      }
++
+       g2d_finish(gr->handle);
+       if(go->nNumBuffers > 1)
+@@ -940,10 +966,10 @@
+               go->offscreen_buf = NULL;
+       }
+-      if(go->fb_fd)
++      if(go->fb_info.fb_fd)
+       {
+-              close(go->fb_fd);
+-              go->fb_fd = 0;
++              close(go->fb_info.fb_fd);
++              go->fb_info.fb_fd = 0;
+       }
+       if(go->renderSurf)
+@@ -951,6 +977,24 @@
+               free(go->renderSurf);
+               go->renderSurf = NULL;
+       }
++      for (i = 0; i < go->clone_display_num; i++)
++      {
++              if(go->mirror_fb_info[i].fb_fd)
++              {
++                      close(go->mirror_fb_info[i].fb_fd);
++                      go->mirror_fb_info[i].fb_fd = 0;
++              }
++      }
++      if(go->mirrorSurf)
++      {
++              free(go->mirrorSurf);
++              go->mirrorSurf = NULL;
++      }
++      if(go->mirror_fb_info)
++      {
++              free(go->mirror_fb_info);
++              go->mirror_fb_info = NULL;
++      }
+       free(go);
+ }
+@@ -1085,39 +1129,27 @@
+                         struct fb_screeninfo *screen_info)
+ {
+       /* Open the frame buffer device. */
+-      output->fb_fd = open(fb_dev, O_RDWR | O_CLOEXEC);
+-      if (output->fb_fd < 0) {
++      screen_info->fb_fd = open(fb_dev, O_RDWR | O_CLOEXEC);
++      if (screen_info->fb_fd < 0) {
+               weston_log("Failed to open frame buffer device%s \n", fb_dev);
+               return -1;
+       }
+       /* Grab the screen info. */
+-      if (fb_query_screen_info(output, output->fb_fd, screen_info) < 0) {
++      if (fb_query_screen_info(output, screen_info->fb_fd, screen_info) < 0) {
+               weston_log("Failed to get frame buffer info \n");
+-              close(output->fb_fd);
++              close(screen_info->fb_fd);
+               return -1;
+       }
+       return 0;
+ }
+-static int
+-g2d_renderer_output_create(struct weston_output *output, struct wl_display *wl_display, const char *device)
+-
+- {
+-      struct g2d_renderer *gr = get_renderer(output->compositor);
+-      struct g2d_output_state *go;
+-      int i = 0;
+-      int offset = 0;
++static void
++getBufferNumber(struct g2d_output_state *go)
++{
+       char *p = NULL;
+-      go = zalloc(sizeof *go);
+-      if (go == NULL)
+-              return -1;
+-
+-      output->renderer_state = go;
+-      gr->viv_global = gcoOS_WaylandCreateVivGlobal(wl_display);
+-
+       p = getenv("FB_MULTI_BUFFER");
+       if (p == gcvNULL)
+       {
+@@ -1126,7 +1158,7 @@
+       else
+       {
+               go->nNumBuffers = atoi(p);
+-              if (go->nNumBuffers < 1)
++              if (go->nNumBuffers < 2)
+               {
+                       go->nNumBuffers  = 1;
+               }
+@@ -1137,13 +1169,19 @@
+               }
+       }
+       weston_log("FB_MULTI_BUFFER = %d\n", go->nNumBuffers);
++}
++static int
++g2d_renderer_surface_create(struct g2d_output_state *go, struct g2d_renderer *gr, const char *device)
++{
++      int i = 0;
++      int offset = 0;
++      weston_log("Opend device=%s\n", device);
+       if(fb_frame_buffer_open(go, device, &go->fb_info) < 0)
+       {
+               weston_log("Open frame buffer failed.\n");
+               return -1;
+       }
+-
+       go->renderSurf = zalloc(sizeof(struct g2d_surfaceEx) * go->nNumBuffers);
+       offset = go->fb_info.buffer_length/go->nNumBuffers;
+       for(i = 0; i < go->nNumBuffers; i++)
+@@ -1161,9 +1199,84 @@
+               go->offscreenSurface.base.planes[0] = go->offscreen_buf->buf_paddr;
+               g2d_clear(gr->handle, &go->offscreenSurface.base);
+       }
++      return 0;
++}
++
++static int
++g2d_renderer_output_create(struct weston_output *output, struct wl_display *wl_display, const char *device)
++ {
++      struct g2d_renderer *gr = get_renderer(output->compositor);
++      struct g2d_output_state *go;
++      int i;
++      int clone_display_num = 0;
++      int count = 0;
++      int k=0, dispCount = 0;
++      char displays[5][32];
++      weston_log("g2d_renderer_output_create device=%s\n", device);
++      count = strlen(device);
++
++      if(count > 0)
++      {
++              for(i= 0; i < count; i++)
++              {
++                      if(device[i] == ',')
++                      {
++                              displays[dispCount][k] = '\0';
++                              dispCount++;
++                              k = 0;
++                              continue;
++                      }
++                      else if(device[i] != ' ')
++                      {
++                              displays[dispCount][k++] = device[i];
++                      }
++              }
++              displays[dispCount][k] = '\0';
++              clone_display_num = dispCount++;
++              weston_log("clone_display_num = %d\n", clone_display_num);
++      }
++      else
++      {
++              weston_log("Invalid device name\n");
++              return -1;
++      }
++
++      go = zalloc(sizeof *go);
++      if (go == NULL)
++              return -1;
++      go->clone_display_num  = clone_display_num;
++      output->renderer_state = go;
++      gr->viv_global = gcoOS_WaylandCreateVivGlobal(wl_display);
++      getBufferNumber(go);
++
++      if(g2d_renderer_surface_create(go, gr, displays[0]) < 0)
++      {
++              weston_log("Create Render surface failed.\n");
++              return -1;
++      }
++
++      if(go->clone_display_num)
++      {
++              go->mirrorSurf = zalloc(sizeof(struct g2d_surfaceEx) * clone_display_num);
++              go->mirror_fb_info = zalloc(sizeof(struct fb_screeninfo) * clone_display_num);
++              if(go->mirrorSurf == NULL || go->mirror_fb_info == NULL)
++                      return -1;
++
++              for(i = 0; i < clone_display_num; i++)
++              {
++                      if(fb_frame_buffer_open(go, displays[i + 1], &go->mirror_fb_info[i]) < 0)
++                      {
++                              weston_log("Open frame buffer failed.\n");
++                              return -1;
++                      }
++                      get_G2dSurface_from_screeninfo(&go->mirror_fb_info[i], &go->mirrorSurf[i]);
++                      go->mirrorSurf[i].base.planes[0] = go->mirror_fb_info[i].physical;
++                      g2d_clear(gr->handle, &go->mirrorSurf[i].base);
++              }
++      }
+       g2d_finish(gr->handle);
+-      for (i = 0; i < 2; i++)
++      for (i = 0; i < BUFFER_DAMAGE_COUNT; i++)
+               pixman_region32_init(&go->buffer_damage[i]);
+     return 0;
+  }
+Index: weston-1.11.0/src/g2d-renderer.h
+===================================================================
+--- weston-1.11.0.orig/src/g2d-renderer.h      2016-10-06 13:17:41.738142236 -0500
++++ weston-1.11.0/src/g2d-renderer.h   2016-10-06 13:17:41.734142216 -0500
+@@ -27,13 +27,11 @@
+ #define __g2d_renderer_h_
+ #include  "compositor.h"
++
+ #ifdef ENABLE_EGL
+ #include <EGL/egl.h>
+-#else
+-#include <HAL/gc_hal_eglplatform.h>
+ #endif
+-
+ struct g2d_renderer_interface {
+       int (*create)(struct weston_compositor *ec);
+Index: weston-1.11.0/src/main.c
+===================================================================
+--- weston-1.11.0.orig/src/main.c      2016-10-06 13:39:13.000000000 -0500
++++ weston-1.11.0/src/main.c   2016-10-06 13:39:39.000000000 -0500
+@@ -287,11 +287,12 @@
+               "  --device=DEVICE\tThe framebuffer device to use\n"
+ #if defined ENABLE_EGL
+               "  --no-use-gl\t\tDo not use the GL renderer\n"
+-              "  --use-g2d\t\tUse the G2D renderer\n\n");
++              "  --use-g2d\t\tUse the G2D renderer\n"
+ #else
+               "  --use-gl\t\tUse the GL renderer\n"
+-              "  --no-use-g2d\t\tDo not use the G2D renderer\n\n");
++              "  --no-use-g2d\t\tDo not use the G2D renderer\n"
+ #endif
++              "  --clone-mode\t\tClone display to multiple devices\n\n");
+ #endif
+ #if defined(BUILD_HEADLESS_COMPOSITOR)
+@@ -888,6 +889,7 @@
+               { WESTON_OPTION_BOOLEAN, "use-gl", 0, &config.use_gl },
+               { WESTON_OPTION_BOOLEAN, "no-use-g2d", 0, &no_use_g2d },
+ #endif
++              { WESTON_OPTION_BOOLEAN, "clone-mode", 0, &config.clone_mode },
+       };
+       parse_options(fbdev_options, ARRAY_LENGTH(fbdev_options), argc, argv);
index bb2e51a6ff9e1ae9f24d076465c2d7271d251bd5..abf188b5cd80bc59ebc0e47e6d998e6b0eaf2bb8 100644 (file)
@@ -10,6 +10,7 @@ SRC_URI_append_imxgpu2d = " \
     file://0009-MGS-1284-xwld-Re-implement-weston-2d-renderer-with-p.patch \
     file://0010-MGS-1284-1-xwld-Re-implement-weston-2d-renderer-with.patch \
     file://0011-MGS-1724-xwld-G2D-compositor-build-failed-in-slevk-b.patch \
+    file://0012-MGS-1783-xwld-Add-clone-mode-support-for-multi-displ.patch \
 "
 
 PACKAGECONFIG_IMX_TO_APPEND = ""