diff options
author | Tom Hochstein <tom.hochstein@nxp.com> | 2016-10-07 17:36:56 -0500 |
---|---|---|
committer | Otavio Salvador <otavio@ossystems.com.br> | 2016-10-18 16:26:14 -0200 |
commit | c76cf5043d47778a2bddc317df43403634f099d3 (patch) | |
tree | 09ee7ca1b6c39f2c964ec66d34b43a110a3446e7 /recipes-graphics/wayland | |
parent | e141909e97556aa9a3028f06543751643a35cc58 (diff) | |
download | meta-freescale-c76cf5043d47778a2bddc317df43403634f099d3.tar.gz |
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 <tom.hochstein@nxp.com>
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
Diffstat (limited to 'recipes-graphics/wayland')
-rw-r--r-- | recipes-graphics/wayland/weston/0012-MGS-1783-xwld-Add-clone-mode-support-for-multi-displ.patch | 421 | ||||
-rw-r--r-- | recipes-graphics/wayland/weston_%.bbappend | 1 |
2 files changed, 422 insertions, 0 deletions
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 @@ | |||
1 | From f2025a7e8c178b8c52c2ca553459a7fea6caf5c8 Mon Sep 17 00:00:00 2001 | ||
2 | From: "yong.gan" <yong.gan@nxp.com> | ||
3 | Date: Tue, 17 May 2016 09:10:50 +0800 | ||
4 | Subject: [PATCH 1/2] MGS-1783: xwld: Add clone mode support for multi display | ||
5 | MIME-Version: 1.0 | ||
6 | Content-Type: text/plain; charset=UTF-8 | ||
7 | Content-Transfer-Encoding: 8bit | ||
8 | |||
9 | Support showing the same contents on multiple displays. | ||
10 | Use the following command to enable multi-display: | ||
11 | openvt -v -- weston-launch -- --idle-time=0 --use-g2d=1 --device=/dev/fb0,/dev/fb4 --clone-mode --log=/var/log/weston.log | ||
12 | |||
13 | Upstream-Status: Inappropriate [i.MX specific] | ||
14 | Date: May 16, 2016 | ||
15 | Signed-off-by: Yong Gan <yong.gan@nxp.com> | ||
16 | --- | ||
17 | src/compositor-fbdev.c | 33 +++++++--- | ||
18 | src/g2d-renderer.c | 171 ++++++++++++++++++++++++++++++++++++++++--------- | ||
19 | src/g2d-renderer.h | 4 +- | ||
20 | 3 files changed, 167 insertions(+), 41 deletions(-) | ||
21 | |||
22 | Index: weston-1.11.0/src/compositor-fbdev.c | ||
23 | =================================================================== | ||
24 | --- weston-1.11.0.orig/src/compositor-fbdev.c 2016-10-06 13:17:41.738142236 -0500 | ||
25 | +++ weston-1.11.0/src/compositor-fbdev.c 2016-10-06 13:28:22.000000000 -0500 | ||
26 | @@ -61,6 +61,8 @@ | ||
27 | struct udev_input input; | ||
28 | int use_pixman; | ||
29 | int use_g2d; | ||
30 | + int clone_mode; | ||
31 | + char *clone_device; | ||
32 | uint32_t output_transform; | ||
33 | struct wl_listener session_listener; | ||
34 | #ifdef ENABLE_EGL | ||
35 | @@ -525,12 +527,15 @@ | ||
36 | if (pixman_renderer_output_create(&output->base) < 0) | ||
37 | goto out_hw_surface; | ||
38 | } else if(backend->use_g2d) { | ||
39 | + const char *g2d_device = device; | ||
40 | + if (backend->clone_mode) | ||
41 | + g2d_device = backend->clone_device; | ||
42 | + | ||
43 | if (g2d_renderer->output_create(&output->base, | ||
44 | - backend->compositor->wl_display, device) < 0) { | ||
45 | + backend->compositor->wl_display, g2d_device) < 0) { | ||
46 | weston_log("g2d_renderer_output_create failed.\n"); | ||
47 | goto out_hw_surface; | ||
48 | } | ||
49 | - | ||
50 | } else { | ||
51 | #ifdef ENABLE_EGL | ||
52 | setenv("HYBRIS_EGLPLATFORM", "wayland", 1); | ||
53 | @@ -803,6 +808,8 @@ | ||
54 | backend->prev_state = WESTON_COMPOSITOR_ACTIVE; | ||
55 | backend->use_pixman = !(param->use_gl || param->use_g2d); | ||
56 | backend->use_g2d = param->use_g2d; | ||
57 | + backend->clone_mode = param->clone_mode; | ||
58 | + backend->clone_device = param->device; | ||
59 | backend->output_transform = param->output_transform; | ||
60 | |||
61 | weston_setup_vt_switch_bindings(compositor); | ||
62 | @@ -844,16 +851,21 @@ | ||
63 | displays[dispCount][k] = '\0'; | ||
64 | dispCount++; | ||
65 | |||
66 | - for(i=0; i<dispCount; i++) | ||
67 | - { | ||
68 | - if (fbdev_output_create(backend, x, y, displays[i]) < 0) | ||
69 | + if(backend->clone_mode){ | ||
70 | + if (fbdev_output_create(backend, x, y, displays[0]) < 0) | ||
71 | goto out_launcher; | ||
72 | - x += container_of(backend->compositor->output_list.prev, | ||
73 | - struct weston_output, | ||
74 | - link)->width; | ||
75 | + } | ||
76 | + else{ | ||
77 | + for(i= 0; i < dispCount; i++){ | ||
78 | + if (fbdev_output_create(backend, x, y, displays[i]) < 0) | ||
79 | + goto out_launcher; | ||
80 | + x += container_of(backend->compositor->output_list.prev, | ||
81 | + struct weston_output, | ||
82 | + link)->width; | ||
83 | + } | ||
84 | } | ||
85 | } | ||
86 | - else { | ||
87 | + else { | ||
88 | #ifdef ENABLE_EGL | ||
89 | gl_renderer = weston_load_module("gl-renderer.so", | ||
90 | "gl_renderer_interface"); | ||
91 | Index: weston-1.11.0/src/g2d-renderer.c | ||
92 | =================================================================== | ||
93 | --- weston-1.11.0.orig/src/g2d-renderer.c 2016-10-06 13:17:41.738142236 -0500 | ||
94 | +++ weston-1.11.0/src/g2d-renderer.c 2016-10-06 13:17:41.734142216 -0500 | ||
95 | @@ -37,15 +37,16 @@ | ||
96 | #include <sys/ioctl.h> | ||
97 | #include <fcntl.h> | ||
98 | #include <unistd.h> | ||
99 | +#include <g2dExt.h> | ||
100 | +#include <HAL/gc_hal_eglplatform.h> | ||
101 | |||
102 | #include "compositor.h" | ||
103 | #include "g2d-renderer.h" | ||
104 | #include "vertex-clipping.h" | ||
105 | #include "shared/helpers.h" | ||
106 | -#include "HAL/gc_hal_eglplatform.h" | ||
107 | -#include "g2dExt.h" | ||
108 | |||
109 | #define BUFFER_DAMAGE_COUNT 2 | ||
110 | +extern struct wl_global* gcoOS_WaylandCreateVivGlobal(struct wl_display* display); | ||
111 | |||
112 | typedef struct _g2dRECT | ||
113 | { | ||
114 | @@ -63,6 +64,7 @@ | ||
115 | size_t buffer_length; /* length of frame buffer memory in bytes */ | ||
116 | size_t physical; | ||
117 | enum g2d_format pixel_format; /* frame buffer pixel format */ | ||
118 | + int fb_fd; | ||
119 | }; | ||
120 | |||
121 | struct g2d_output_state { | ||
122 | @@ -74,10 +76,12 @@ | ||
123 | struct g2d_surfaceEx offscreenSurface; | ||
124 | struct g2d_buf *offscreen_buf; | ||
125 | struct fb_screeninfo fb_info; | ||
126 | + struct fb_screeninfo *mirror_fb_info; | ||
127 | + struct g2d_surfaceEx *mirrorSurf; | ||
128 | int directBlit; | ||
129 | + int clone_display_num; | ||
130 | int width; | ||
131 | int height; | ||
132 | - int fb_fd; | ||
133 | }; | ||
134 | |||
135 | struct g2d_surface_state { | ||
136 | @@ -366,7 +370,7 @@ | ||
137 | struct g2d_output_state *go = get_output_state(output); | ||
138 | go->fb_info.varinfo.yoffset = go->activebuffer * go->fb_info.y_resolution; | ||
139 | |||
140 | - if(ioctl(go->fb_fd, FBIOPAN_DISPLAY, &(go->fb_info.varinfo)) < 0) | ||
141 | + if(ioctl(go->fb_info.fb_fd, FBIOPAN_DISPLAY, &(go->fb_info.varinfo)) < 0) | ||
142 | { | ||
143 | weston_log("FBIOPAN_DISPLAY Failed\n"); | ||
144 | } | ||
145 | @@ -388,6 +392,28 @@ | ||
146 | &go->renderSurf[go->activebuffer], &srcRect, &dstrect); | ||
147 | } | ||
148 | |||
149 | + if(go->clone_display_num) | ||
150 | + { | ||
151 | + int i = 0; | ||
152 | + for(i = 0; i < go->clone_display_num; i++) | ||
153 | + { | ||
154 | + g2dRECT srcRect = {0, 0, go->renderSurf[go->activebuffer].base.width, go->renderSurf[go->activebuffer].base.height}; | ||
155 | + g2dRECT dstrect = {0, 0, go->mirrorSurf[i].base.width, go->mirrorSurf[i].base.height}; | ||
156 | + g2dRECT clipRect = srcRect; | ||
157 | + g2d_set_clipping(gr->handle, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); | ||
158 | + if(go->directBlit || go->nNumBuffers > 1) | ||
159 | + { | ||
160 | + g2d_blitSurface(gr->handle, &go->renderSurf[go->activebuffer], | ||
161 | + &go->mirrorSurf[i], &srcRect, &dstrect); | ||
162 | + } | ||
163 | + else | ||
164 | + { | ||
165 | + g2d_blitSurface(gr->handle, &go->offscreenSurface, | ||
166 | + &go->mirrorSurf[i], &srcRect, &dstrect); | ||
167 | + } | ||
168 | + } | ||
169 | + } | ||
170 | + | ||
171 | g2d_finish(gr->handle); | ||
172 | |||
173 | if(go->nNumBuffers > 1) | ||
174 | @@ -940,10 +966,10 @@ | ||
175 | go->offscreen_buf = NULL; | ||
176 | } | ||
177 | |||
178 | - if(go->fb_fd) | ||
179 | + if(go->fb_info.fb_fd) | ||
180 | { | ||
181 | - close(go->fb_fd); | ||
182 | - go->fb_fd = 0; | ||
183 | + close(go->fb_info.fb_fd); | ||
184 | + go->fb_info.fb_fd = 0; | ||
185 | } | ||
186 | |||
187 | if(go->renderSurf) | ||
188 | @@ -951,6 +977,24 @@ | ||
189 | free(go->renderSurf); | ||
190 | go->renderSurf = NULL; | ||
191 | } | ||
192 | + for (i = 0; i < go->clone_display_num; i++) | ||
193 | + { | ||
194 | + if(go->mirror_fb_info[i].fb_fd) | ||
195 | + { | ||
196 | + close(go->mirror_fb_info[i].fb_fd); | ||
197 | + go->mirror_fb_info[i].fb_fd = 0; | ||
198 | + } | ||
199 | + } | ||
200 | + if(go->mirrorSurf) | ||
201 | + { | ||
202 | + free(go->mirrorSurf); | ||
203 | + go->mirrorSurf = NULL; | ||
204 | + } | ||
205 | + if(go->mirror_fb_info) | ||
206 | + { | ||
207 | + free(go->mirror_fb_info); | ||
208 | + go->mirror_fb_info = NULL; | ||
209 | + } | ||
210 | |||
211 | free(go); | ||
212 | } | ||
213 | @@ -1085,39 +1129,27 @@ | ||
214 | struct fb_screeninfo *screen_info) | ||
215 | { | ||
216 | /* Open the frame buffer device. */ | ||
217 | - output->fb_fd = open(fb_dev, O_RDWR | O_CLOEXEC); | ||
218 | - if (output->fb_fd < 0) { | ||
219 | + screen_info->fb_fd = open(fb_dev, O_RDWR | O_CLOEXEC); | ||
220 | + if (screen_info->fb_fd < 0) { | ||
221 | weston_log("Failed to open frame buffer device%s \n", fb_dev); | ||
222 | return -1; | ||
223 | } | ||
224 | |||
225 | /* Grab the screen info. */ | ||
226 | - if (fb_query_screen_info(output, output->fb_fd, screen_info) < 0) { | ||
227 | + if (fb_query_screen_info(output, screen_info->fb_fd, screen_info) < 0) { | ||
228 | weston_log("Failed to get frame buffer info \n"); | ||
229 | |||
230 | - close(output->fb_fd); | ||
231 | + close(screen_info->fb_fd); | ||
232 | return -1; | ||
233 | } | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | -static int | ||
239 | -g2d_renderer_output_create(struct weston_output *output, struct wl_display *wl_display, const char *device) | ||
240 | - | ||
241 | - { | ||
242 | - struct g2d_renderer *gr = get_renderer(output->compositor); | ||
243 | - struct g2d_output_state *go; | ||
244 | - int i = 0; | ||
245 | - int offset = 0; | ||
246 | +static void | ||
247 | +getBufferNumber(struct g2d_output_state *go) | ||
248 | +{ | ||
249 | char *p = NULL; | ||
250 | - go = zalloc(sizeof *go); | ||
251 | - if (go == NULL) | ||
252 | - return -1; | ||
253 | - | ||
254 | - output->renderer_state = go; | ||
255 | - gr->viv_global = gcoOS_WaylandCreateVivGlobal(wl_display); | ||
256 | - | ||
257 | p = getenv("FB_MULTI_BUFFER"); | ||
258 | if (p == gcvNULL) | ||
259 | { | ||
260 | @@ -1126,7 +1158,7 @@ | ||
261 | else | ||
262 | { | ||
263 | go->nNumBuffers = atoi(p); | ||
264 | - if (go->nNumBuffers < 1) | ||
265 | + if (go->nNumBuffers < 2) | ||
266 | { | ||
267 | go->nNumBuffers = 1; | ||
268 | } | ||
269 | @@ -1137,13 +1169,19 @@ | ||
270 | } | ||
271 | } | ||
272 | weston_log("FB_MULTI_BUFFER = %d\n", go->nNumBuffers); | ||
273 | +} | ||
274 | |||
275 | +static int | ||
276 | +g2d_renderer_surface_create(struct g2d_output_state *go, struct g2d_renderer *gr, const char *device) | ||
277 | +{ | ||
278 | + int i = 0; | ||
279 | + int offset = 0; | ||
280 | + weston_log("Opend device=%s\n", device); | ||
281 | if(fb_frame_buffer_open(go, device, &go->fb_info) < 0) | ||
282 | { | ||
283 | weston_log("Open frame buffer failed.\n"); | ||
284 | return -1; | ||
285 | } | ||
286 | - | ||
287 | go->renderSurf = zalloc(sizeof(struct g2d_surfaceEx) * go->nNumBuffers); | ||
288 | offset = go->fb_info.buffer_length/go->nNumBuffers; | ||
289 | for(i = 0; i < go->nNumBuffers; i++) | ||
290 | @@ -1161,9 +1199,84 @@ | ||
291 | go->offscreenSurface.base.planes[0] = go->offscreen_buf->buf_paddr; | ||
292 | g2d_clear(gr->handle, &go->offscreenSurface.base); | ||
293 | } | ||
294 | + return 0; | ||
295 | +} | ||
296 | + | ||
297 | +static int | ||
298 | +g2d_renderer_output_create(struct weston_output *output, struct wl_display *wl_display, const char *device) | ||
299 | |||
300 | + { | ||
301 | + struct g2d_renderer *gr = get_renderer(output->compositor); | ||
302 | + struct g2d_output_state *go; | ||
303 | + int i; | ||
304 | + int clone_display_num = 0; | ||
305 | + int count = 0; | ||
306 | + int k=0, dispCount = 0; | ||
307 | + char displays[5][32]; | ||
308 | + weston_log("g2d_renderer_output_create device=%s\n", device); | ||
309 | + count = strlen(device); | ||
310 | + | ||
311 | + if(count > 0) | ||
312 | + { | ||
313 | + for(i= 0; i < count; i++) | ||
314 | + { | ||
315 | + if(device[i] == ',') | ||
316 | + { | ||
317 | + displays[dispCount][k] = '\0'; | ||
318 | + dispCount++; | ||
319 | + k = 0; | ||
320 | + continue; | ||
321 | + } | ||
322 | + else if(device[i] != ' ') | ||
323 | + { | ||
324 | + displays[dispCount][k++] = device[i]; | ||
325 | + } | ||
326 | + } | ||
327 | + displays[dispCount][k] = '\0'; | ||
328 | + clone_display_num = dispCount++; | ||
329 | + weston_log("clone_display_num = %d\n", clone_display_num); | ||
330 | + } | ||
331 | + else | ||
332 | + { | ||
333 | + weston_log("Invalid device name\n"); | ||
334 | + return -1; | ||
335 | + } | ||
336 | + | ||
337 | + go = zalloc(sizeof *go); | ||
338 | + if (go == NULL) | ||
339 | + return -1; | ||
340 | + go->clone_display_num = clone_display_num; | ||
341 | + output->renderer_state = go; | ||
342 | + gr->viv_global = gcoOS_WaylandCreateVivGlobal(wl_display); | ||
343 | + getBufferNumber(go); | ||
344 | + | ||
345 | + if(g2d_renderer_surface_create(go, gr, displays[0]) < 0) | ||
346 | + { | ||
347 | + weston_log("Create Render surface failed.\n"); | ||
348 | + return -1; | ||
349 | + } | ||
350 | + | ||
351 | + if(go->clone_display_num) | ||
352 | + { | ||
353 | + go->mirrorSurf = zalloc(sizeof(struct g2d_surfaceEx) * clone_display_num); | ||
354 | + go->mirror_fb_info = zalloc(sizeof(struct fb_screeninfo) * clone_display_num); | ||
355 | + if(go->mirrorSurf == NULL || go->mirror_fb_info == NULL) | ||
356 | + return -1; | ||
357 | + | ||
358 | + for(i = 0; i < clone_display_num; i++) | ||
359 | + { | ||
360 | + if(fb_frame_buffer_open(go, displays[i + 1], &go->mirror_fb_info[i]) < 0) | ||
361 | + { | ||
362 | + weston_log("Open frame buffer failed.\n"); | ||
363 | + return -1; | ||
364 | + } | ||
365 | + get_G2dSurface_from_screeninfo(&go->mirror_fb_info[i], &go->mirrorSurf[i]); | ||
366 | + go->mirrorSurf[i].base.planes[0] = go->mirror_fb_info[i].physical; | ||
367 | + g2d_clear(gr->handle, &go->mirrorSurf[i].base); | ||
368 | + } | ||
369 | + } | ||
370 | g2d_finish(gr->handle); | ||
371 | - for (i = 0; i < 2; i++) | ||
372 | + for (i = 0; i < BUFFER_DAMAGE_COUNT; i++) | ||
373 | pixman_region32_init(&go->buffer_damage[i]); | ||
374 | return 0; | ||
375 | } | ||
376 | Index: weston-1.11.0/src/g2d-renderer.h | ||
377 | =================================================================== | ||
378 | --- weston-1.11.0.orig/src/g2d-renderer.h 2016-10-06 13:17:41.738142236 -0500 | ||
379 | +++ weston-1.11.0/src/g2d-renderer.h 2016-10-06 13:17:41.734142216 -0500 | ||
380 | @@ -27,13 +27,11 @@ | ||
381 | #define __g2d_renderer_h_ | ||
382 | |||
383 | #include "compositor.h" | ||
384 | + | ||
385 | #ifdef ENABLE_EGL | ||
386 | #include <EGL/egl.h> | ||
387 | -#else | ||
388 | -#include <HAL/gc_hal_eglplatform.h> | ||
389 | #endif | ||
390 | |||
391 | - | ||
392 | struct g2d_renderer_interface { | ||
393 | |||
394 | int (*create)(struct weston_compositor *ec); | ||
395 | Index: weston-1.11.0/src/main.c | ||
396 | =================================================================== | ||
397 | --- weston-1.11.0.orig/src/main.c 2016-10-06 13:39:13.000000000 -0500 | ||
398 | +++ weston-1.11.0/src/main.c 2016-10-06 13:39:39.000000000 -0500 | ||
399 | @@ -287,11 +287,12 @@ | ||
400 | " --device=DEVICE\tThe framebuffer device to use\n" | ||
401 | #if defined ENABLE_EGL | ||
402 | " --no-use-gl\t\tDo not use the GL renderer\n" | ||
403 | - " --use-g2d\t\tUse the G2D renderer\n\n"); | ||
404 | + " --use-g2d\t\tUse the G2D renderer\n" | ||
405 | #else | ||
406 | " --use-gl\t\tUse the GL renderer\n" | ||
407 | - " --no-use-g2d\t\tDo not use the G2D renderer\n\n"); | ||
408 | + " --no-use-g2d\t\tDo not use the G2D renderer\n" | ||
409 | #endif | ||
410 | + " --clone-mode\t\tClone display to multiple devices\n\n"); | ||
411 | #endif | ||
412 | |||
413 | #if defined(BUILD_HEADLESS_COMPOSITOR) | ||
414 | @@ -888,6 +889,7 @@ | ||
415 | { WESTON_OPTION_BOOLEAN, "use-gl", 0, &config.use_gl }, | ||
416 | { WESTON_OPTION_BOOLEAN, "no-use-g2d", 0, &no_use_g2d }, | ||
417 | #endif | ||
418 | + { WESTON_OPTION_BOOLEAN, "clone-mode", 0, &config.clone_mode }, | ||
419 | }; | ||
420 | |||
421 | 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 = " \ | |||
10 | file://0009-MGS-1284-xwld-Re-implement-weston-2d-renderer-with-p.patch \ | 10 | file://0009-MGS-1284-xwld-Re-implement-weston-2d-renderer-with-p.patch \ |
11 | file://0010-MGS-1284-1-xwld-Re-implement-weston-2d-renderer-with.patch \ | 11 | file://0010-MGS-1284-1-xwld-Re-implement-weston-2d-renderer-with.patch \ |
12 | file://0011-MGS-1724-xwld-G2D-compositor-build-failed-in-slevk-b.patch \ | 12 | file://0011-MGS-1724-xwld-G2D-compositor-build-failed-in-slevk-b.patch \ |
13 | file://0012-MGS-1783-xwld-Add-clone-mode-support-for-multi-displ.patch \ | ||
13 | " | 14 | " |
14 | 15 | ||
15 | PACKAGECONFIG_IMX_TO_APPEND = "" | 16 | PACKAGECONFIG_IMX_TO_APPEND = "" |