From: Tom Hochstein Date: Fri, 7 Oct 2016 22:36:56 +0000 (-0500) Subject: weston: Add clone mode support for multi display X-Git-Tag: 2.2~231 X-Git-Url: https://code.ossystems.io/gitweb?a=commitdiff_plain;h=c76cf5043d47778a2bddc317df43403634f099d3;p=meta-freescale.git weston: Add clone mode support for multi display 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 Signed-off-by: Otavio Salvador --- 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 index 00000000..10bae4d1 --- /dev/null +++ b/recipes-graphics/wayland/weston/0012-MGS-1783-xwld-Add-clone-mode-support-for-multi-displ.patch @@ -0,0 +1,421 @@ +From f2025a7e8c178b8c52c2ca553459a7fea6caf5c8 Mon Sep 17 00:00:00 2001 +From: "yong.gan" +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 +--- + 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; iclone_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 + #include + #include ++#include ++#include + + #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 +-#else +-#include + #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); diff --git a/recipes-graphics/wayland/weston_%.bbappend b/recipes-graphics/wayland/weston_%.bbappend index bb2e51a6..abf188b5 100644 --- a/recipes-graphics/wayland/weston_%.bbappend +++ b/recipes-graphics/wayland/weston_%.bbappend @@ -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 = ""