blob: 0036894be4a421cd47ba858ac859e74df0904245 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001From 190e1349858bba7e103b03a0f242575425066300 Mon Sep 17 00:00:00 2001
2From: Jia Rong <jia.rong@mediatek.com>
3Date: Thu, 3 May 2018 08:35:18 +0800
4Subject: [PATCH] weston: add mtk test client
5
6add mtk test client
7Test: OK
8
9Change-Id: I89f50f00414c426b00424ab2dc298647330472a6
10Signed-off-by: Jia Rong <jia.rong@mediatek.com>
11CR-Id: AUTO00016576
12---
13 Makefile.am | 15 +
14 clients/simple-configure-mtk.c | 1230 ++++++++++++++++++++++++++++++++++++++++
15 configure.ac | 1 +
16 3 files changed, 1246 insertions(+)
17 create mode 100644 clients/simple-configure-mtk.c
18
19diff --git a/Makefile.am b/Makefile.am
20index e450b95..576b4a1 100644
21--- a/Makefile.am
22+++ b/Makefile.am
23@@ -657,6 +657,21 @@ nodist_weston_simple_screenshooter_mtk_SOURCES = \
24 weston_simple_screenshooter_mtk_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
25 weston_simple_screenshooter_mtk_LDADD = $(EGL_LIBS) $(LIBDRM_LIBS) libtoytoolkit.la
26
27+if BUILD_SIMPLE_CONFIGURE_MTK_CLIENT
28+demo_clients += weston-simple-configure-mtk
29+weston_simple_configure_mtk_SOURCES = clients/simple-configure-mtk.c
30+nodist_weston_simple_configure_mtk_SOURCES = \
31+ protocol/xdg-shell-unstable-v6-protocol.c \
32+ protocol/xdg-shell-unstable-v6-client-protocol.h \
33+ protocol/fullscreen-shell-unstable-v1-protocol.c \
34+ protocol/fullscreen-shell-unstable-v1-client-protocol.h \
35+ protocol/linux-dmabuf-unstable-v1-protocol.c \
36+ protocol/linux-dmabuf-unstable-v1-client-protocol.h
37+weston_simple_configure_mtk_CFLAGS = $(AM_CFLAGS) $(CLIENT_CFLAGS)
38+weston_simple_configure_mtk_LDADD = $(EGL_LIBS) $(LIBDRM_LIBS) libtoytoolkit.la
39+BUILT_SOURCES += protocol/linux-dmabuf-unstable-v1-client-protocol.h
40+endif
41+
42 noinst_LTLIBRARIES += libtoytoolkit.la
43
44 libtoytoolkit_la_SOURCES = \
45diff --git a/clients/simple-configure-mtk.c b/clients/simple-configure-mtk.c
46new file mode 100644
47index 0000000..f94497e
48--- /dev/null
49+++ b/clients/simple-configure-mtk.c
50@@ -0,0 +1,1230 @@
51+#include <stdio.h>
52+#include <stdlib.h>
53+#include <string.h>
54+#include <stdbool.h>
55+#include <math.h>
56+#include <assert.h>
57+#include <sys/mman.h>
58+#include <signal.h>
59+#include <fcntl.h>
60+#include <errno.h>
61+#include <linux/input.h>
62+
63+#include <wayland-client.h>
64+#include <wayland-cursor.h>
65+
66+#include <drm_fourcc.h>
67+#include <xf86drm.h>
68+#include <xf86drmMode.h>
69+
70+#include <sys/types.h>
71+#include <unistd.h>
72+
73+//#include "ivi-application-client-protocol.h"
74+#include "xdg-shell-unstable-v6-client-protocol.h"
75+#include "linux-dmabuf-unstable-v1-client-protocol.h"
76+#include "fullscreen-shell-unstable-v1-client-protocol.h"
77+
78+#include <shared/platform.h>
79+
80+//#define IVI_SURFACE_ID 9000
81+#define MAX_IMAGE 16
82+#define ALIGN(X,bit) ((X + bit-1) & (~(bit-1)))
83+#define MAX_DMABUF_PLANES 4
84+#define RES_NUM 4
85+#define MAX_LEN 60
86+
87+struct window;
88+struct seat;
89+
90+struct display {
91+ struct wl_display *display;
92+ struct wl_registry *registry;
93+ struct wl_compositor *compositor;
94+ struct zxdg_shell_v6 *shell;
95+ struct zwp_fullscreen_shell_v1 *fshell;
96+ //struct ivi_application *ivi_application;
97+ struct wl_seat *seat;
98+ struct wl_pointer *pointer;
99+ struct wl_touch *touch;
100+ struct wl_keyboard *keyboard;
101+ struct wl_shm *shm;
102+ struct zwp_linux_dmabuf_v1 *dmabuf;
103+ struct wl_list output_list; /* struct output_unit::link */
104+ struct wl_cursor_theme *cursor_theme;
105+ struct wl_cursor *default_cursor;
106+ struct wl_surface *cursor_surface;
107+ struct window *window;
108+};
109+
110+struct geometry {
111+ int width, height;
112+};
113+
114+struct buffer {
115+ struct wl_buffer *buffer;
116+ void *dma_map;
117+ int busy;
118+};
119+
120+struct file_arg{
121+ char filename[MAX_LEN];
122+ int width;
123+ int height;
124+ int format;
125+};
126+
127+struct window {
128+ struct display *display;
129+ struct geometry geometry, window_size;
130+ bool wait_for_configure;
131+ struct {
132+ struct file_arg fProp;
133+ struct buffer out_bufs[RES_NUM];
134+ } image;
135+ struct img_texture *tex;
136+ uint32_t benchmark_time, frames;
137+ struct wl_surface *surface;
138+ struct zxdg_surface_v6 *xdg_surface;
139+ struct zxdg_toplevel_v6 *xdg_toplevel;
140+ //struct ivi_surface *ivi_surface;
141+ struct wl_callback *callback;
142+ int fullscreen, opaque, buffer_size, overlay, format;
143+ enum wl_output_transform transform;
144+ int drm_card_fd;
145+};
146+
147+struct img_texture {
148+ struct context *ctx;
149+
150+ /* input */
151+ int width;
152+ int height;
153+ int drm_format;
154+ int bpp;
155+ int plane_nums;
156+
157+ int pitch[MAX_DMABUF_PLANES];
158+ int offset[MAX_DMABUF_PLANES];
159+ int fds[MAX_DMABUF_PLANES];
160+ int handle[MAX_DMABUF_PLANES];
161+
162+ void *texbuf;
163+ int size;
164+};
165+
166+typedef enum _IMG_FORMAT_E {
167+ IMG_FORMAT_RGB565 = 0,
168+ IMG_FORMAT_XRGB8888,
169+ IMG_FORMAT_ARGB8888,
170+ IMG_FORMAT_YUYV,
171+ IMG_FORMAT_NV12,
172+ IMG_FORMAT_NV16,
173+ IMG_FORMAT_YUV420,
174+ IMG_FORMAT_YVU420,
175+ IMG_FORMAT_LAST,
176+} IMG_FORMAT_T;
177+
178+struct drm_fourcc_info {
179+ unsigned int drm_format;
180+ int plane_cnt;
181+ int bpp;
182+};
183+
184+static struct drm_fourcc_info fourcc_tbl[] = {
185+ {DRM_FORMAT_RGB565, 1, 16},
186+ {DRM_FORMAT_RGBA5551, 1, 16},
187+ {DRM_FORMAT_RGBA4444, 1, 16},
188+ {DRM_FORMAT_XRGB8888, 1, 32},
189+ {DRM_FORMAT_XBGR8888, 1, 32},
190+ {DRM_FORMAT_RGBX8888, 1, 32},
191+ {DRM_FORMAT_BGRX8888, 1, 32},
192+ {DRM_FORMAT_ARGB8888, 1, 32},
193+ {DRM_FORMAT_ABGR8888, 1, 32},
194+ {DRM_FORMAT_RGBA8888, 1, 32},
195+ {DRM_FORMAT_BGRA8888, 1, 32},
196+ {DRM_FORMAT_YUYV, 1, 16},
197+ {DRM_FORMAT_VYUY, 1, 16},
198+ {DRM_FORMAT_NV12, 2, 12},
199+ {DRM_FORMAT_NV21, 2, 12},
200+ {DRM_FORMAT_NV16, 2, 16},
201+ {DRM_FORMAT_NV61, 2, 16},
202+ {DRM_FORMAT_YUV420, 3, 12},
203+ {DRM_FORMAT_YVU420, 3, 12},
204+ {0, 0, 0},
205+};
206+
207+static int running = 1;
208+static int debug = 0;
209+
210+static void
211+redraw(void *data, struct wl_callback *callback, uint32_t time);
212+
213+static int _format_transfer(int format, int *drm_format)
214+{
215+ int new_format;
216+
217+ if (!drm_format)
218+ return -1;
219+
220+ switch (format) {
221+ case IMG_FORMAT_RGB565:
222+ new_format = DRM_FORMAT_RGB565;
223+ break;
224+ case IMG_FORMAT_XRGB8888:
225+ new_format = DRM_FORMAT_XRGB8888;
226+ break;
227+ case IMG_FORMAT_ARGB8888:
228+ new_format = DRM_FORMAT_ARGB8888;
229+ break;
230+ case IMG_FORMAT_YUYV:
231+ new_format = DRM_FORMAT_YUYV;
232+ break;
233+ case IMG_FORMAT_NV12:
234+ new_format = DRM_FORMAT_NV12;
235+ break;
236+ case IMG_FORMAT_NV16:
237+ new_format = DRM_FORMAT_NV16;
238+ break;
239+ case IMG_FORMAT_YUV420:
240+ new_format = DRM_FORMAT_YUV420;
241+ break;
242+ case IMG_FORMAT_YVU420:
243+ new_format = DRM_FORMAT_YVU420;
244+ break;
245+ default:
246+ return -2;
247+ }
248+ *drm_format = new_format;
249+
250+ return 0;
251+}
252+
253+static struct drm_fourcc_info *
254+get_drm_format_info(unsigned int format)
255+{
256+ int i;
257+
258+ for (i = 0; ; i++) {
259+ if ( format == fourcc_tbl[i].drm_format){
260+ return &fourcc_tbl[i];
261+ }
262+ if ( fourcc_tbl[i].drm_format == 0)
263+ break;
264+ }
265+ return NULL;
266+}
267+
268+static char *
269+_get_tex_resource(int drifd, struct img_texture *tex)
270+{
271+ void *map = NULL;
272+ struct drm_mode_create_dumb create_arg;
273+ struct drm_mode_map_dumb map_arg;
274+ struct drm_prime_handle prime_arg;
275+ struct drm_fourcc_info *format_info;
276+ int i, ret;
277+ unsigned int alloc_size;
278+
279+ memset(&create_arg, 0, sizeof(create_arg));
280+ memset(&map_arg, 0, sizeof(map_arg));
281+ memset(&prime_arg, 0, sizeof(prime_arg));
282+
283+ for(i = 0; i < MAX_DMABUF_PLANES; i ++ )
284+ tex->fds[i] = -1;
285+
286+ format_info = get_drm_format_info(tex->drm_format);
287+ if (format_info == NULL)
288+ return NULL;
289+
290+ tex->bpp = format_info->bpp;
291+ if (format_info->plane_cnt == 3) {
292+ if (format_info->bpp == 12) {
293+ tex->pitch[0] = ALIGN(tex->width, 16);
294+ tex->pitch[1] = tex->pitch[0] / 2;
295+ tex->pitch[2] = tex->pitch[0] / 2;
296+ tex->offset[0] = 0;
297+ tex->offset[1] = tex->pitch[0] * tex->height;
298+ tex->offset[2] = tex->offset[1] + tex->pitch[1] * tex->height / 2;
299+ alloc_size = tex->offset[2] + tex->pitch[2] * tex->height / 2;
300+ } else {
301+ fprintf(stderr,"debug: please add new format 0x%x\n", tex->drm_format);
302+ return NULL;
303+ }
304+ } else if (format_info->plane_cnt == 2) {
305+ tex->pitch[0] = ALIGN(tex->width, 16);
306+ tex->offset[0] = 0;
307+ if (format_info->bpp == 16) {
308+ tex->pitch[1] = tex->pitch[0];
309+ tex->offset[1] = tex->pitch[0] * tex->height;
310+ alloc_size = tex->offset[1] + tex->pitch[1] * tex->height;
311+ fprintf(stderr,"debug: %s %d alloc_size = %d o/p [%d %d]\n",
312+ __FUNCTION__, __LINE__, alloc_size, tex->offset[1], tex->pitch[1]);
313+ }
314+ else if (format_info->bpp == 12) {
315+ tex->pitch[1] = tex->pitch[0] / 2;
316+ tex->offset[1] = tex->pitch[0] * tex->height;
317+ alloc_size = tex->offset[1] + tex->pitch[1] * tex->height;
318+ } else {
319+ fprintf(stderr,"debug: please add new format 0x%x\n", tex->drm_format);
320+ return NULL;
321+ }
322+ } else {
323+ tex->pitch[0] = ALIGN(tex->width * tex->bpp / 8, 16);
324+ tex->offset[0] = 0;
325+ alloc_size = tex->pitch[0] * tex->height;
326+ }
327+
328+ create_arg.bpp = 8;
329+ create_arg.width = alloc_size;
330+ create_arg.height = 1;
331+
332+ ret = drmIoctl(drifd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg);
333+ if (ret) {
334+ fprintf(stderr,"error: drmIoctl %d DRM_IOCTL_MODE_CREATE_DUMB fail %d\n", drifd, ret);
335+ return NULL;
336+ }
337+
338+ map_arg.handle = create_arg.handle;
339+
340+ ret = drmIoctl(drifd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg);
341+ if (ret) {
342+ fprintf(stderr,"error: drmIoctl DRM_IOCTL_MODE_MAP_DUMB fail %d\n", ret);
343+ return NULL;
344+ }
345+
346+ map = mmap(0, create_arg.size, PROT_WRITE|PROT_READ , MAP_SHARED, drifd, map_arg.offset);
347+ if (map == MAP_FAILED) {
348+ fprintf(stderr,"error: mmap fail : %p\n", map);
349+ return NULL;
350+ }
351+
352+ prime_arg.handle = create_arg.handle;
353+ prime_arg.flags = DRM_CLOEXEC;
354+ ret = drmIoctl(drifd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &prime_arg);
355+ if (ret || prime_arg.fd == -1) {
356+ fprintf(stderr,"error: drmIoctl DRM_IOCTL_PRIME_HANDLE_TO_FD fail %d fd=%d\n",ret,prime_arg.fd);
357+ return NULL;
358+ }
359+
360+ for (i = 0; i < format_info->plane_cnt; i++) {
361+ tex->fds[i] = prime_arg.fd;
362+ tex->handle[i] = create_arg.handle;
363+ }
364+ tex->plane_nums = format_info->plane_cnt;
365+ tex->texbuf = map;
366+ tex->size = create_arg.size;
367+
368+ return map;
369+}
370+
371+static int
372+init_img_texture(struct window *window)
373+{
374+ int ret;
375+ struct img_texture *tex;
376+ tex = malloc(sizeof *tex);
377+ if (tex == NULL)
378+ return -1;
379+
380+ ret = _format_transfer(window->image.fProp.format, &(tex->drm_format));
381+ if (ret < 0)
382+ return -1;
383+
384+ tex->width = window->image.fProp.width;
385+ tex->height= window->image.fProp.height;
386+
387+ window->tex = tex;
388+ return 0;
389+}
390+
391+static void
392+buffer_release(void *data, struct wl_buffer *buffer)
393+{
394+ struct buffer *mybuf = data;
395+
396+ mybuf->busy = 0;
397+}
398+
399+static const struct wl_buffer_listener buffer_listener = {
400+ buffer_release
401+};
402+
403+static void
404+create_succeeded(void *data,
405+ struct zwp_linux_buffer_params_v1 *params,
406+ struct wl_buffer *new_buffer)
407+{
408+ struct buffer *buffer = data;
409+
410+ buffer->buffer = new_buffer;
411+ wl_buffer_add_listener(buffer->buffer, &buffer_listener, buffer);
412+
413+ zwp_linux_buffer_params_v1_destroy(params);
414+}
415+
416+static void
417+create_failed(void *data, struct zwp_linux_buffer_params_v1 *params)
418+{
419+ struct buffer *buffer = data;
420+
421+ buffer->buffer = NULL;
422+
423+ zwp_linux_buffer_params_v1_destroy(params);
424+
425+ running = false;
426+
427+ fprintf(stderr, "Error: zwp_linux_buffer_params.create failed.\n");
428+}
429+
430+static const struct zwp_linux_buffer_params_v1_listener params_listener = {
431+ create_succeeded,
432+ create_failed
433+};
434+
435+static int
436+create_dmabuf_buffer(struct display *display, struct buffer *buffer)
437+{
438+ struct zwp_linux_buffer_params_v1 *params;
439+ struct img_texture *cbtex = display->window->tex;
440+ uint64_t modifier;
441+ uint32_t flags;
442+ int i;
443+ /* output */
444+ buffer->dma_map = _get_tex_resource(display->window->drm_card_fd, cbtex);
445+
446+ if (buffer->dma_map == NULL) {
447+ fprintf(stderr, "error: _get_tex_resource failed\n");
448+ return -1;
449+ }
450+
451+ modifier = 0;
452+ params = zwp_linux_dmabuf_v1_create_params(display->dmabuf);
453+
454+ for(i = 0; i < cbtex->plane_nums; i ++)
455+ {
456+ zwp_linux_buffer_params_v1_add(params,
457+ cbtex->fds[i],
458+ i, /* plane_idx */
459+ cbtex->offset[i],/* offset */
460+ cbtex->pitch[i],
461+ modifier >> 32,
462+ modifier & 0xffffffff);
463+ }
464+ zwp_linux_buffer_params_v1_add_listener(params, &params_listener, buffer);
465+ zwp_linux_buffer_params_v1_create(params,
466+ cbtex->width,
467+ cbtex->height,
468+ cbtex->drm_format,
469+ flags);
470+
471+ /* params is destroyed by the event handlers */
472+ wl_display_roundtrip(display->display);
473+ if (buffer->buffer == NULL) {
474+ return -1;
475+ }
476+
477+ return 0;
478+}
479+
480+static int
481+_load_file(void *buf, int len, const char *file_name)
482+{
483+ int ret, nread = 0;
484+
485+ FILE *fp = fopen(file_name, "rb");
486+ if (!fp)
487+ {
488+ fprintf(stderr,"debug: file %s open failed\n", file_name);
489+ return -1;
490+ }
491+
492+ while (nread < len) {
493+ ret = fread(buf + nread, 1, len - nread, fp);
494+ if (!ret)
495+ break;
496+ nread += ret;
497+ }
498+
499+ fclose(fp);
500+ return 0;
501+}
502+
503+static int
504+_kms_device_fd(void)
505+{
506+ int i;
507+ bool has_conn = false;
508+ for (i = 0; i < 8; ++i) {
509+ char path[99];
510+ sprintf(path, "/dev/dri/card%d", i);
511+ fprintf(stderr, "debug: trying %s\n", path);
512+ int fd = open(path, O_RDWR | O_CLOEXEC);
513+ if (fd >= 0) {
514+ drmModeResPtr mr = drmModeGetResources(fd);
515+ if (mr) {
516+ has_conn = mr->count_connectors > 0;
517+ drmModeFreeResources(mr);
518+ }
519+ if (has_conn) {
520+ fprintf(stderr, "debug: using %s\n", path);
521+ return fd;
522+ }
523+ close(fd);
524+ }
525+ }
526+ return -1;
527+}
528+
529+static void
530+handle_xdg_surface_configure(void *data, struct zxdg_surface_v6 *surface,
531+ uint32_t serial)
532+{
533+ struct window *window = data;
534+ fprintf(stderr, "handle_xdg_surface_configure\n");
535+
536+ zxdg_surface_v6_ack_configure(surface, serial);
537+
538+ if (window->wait_for_configure) {
539+ redraw(window, NULL, 0);
540+ window->wait_for_configure = false;
541+ }
542+}
543+
544+static const struct zxdg_surface_v6_listener xdg_surface_listener = {
545+ handle_xdg_surface_configure,
546+};
547+
548+
549+static void
550+handle_toplevel_configure(void *data, struct zxdg_toplevel_v6 *toplevel,
551+ int32_t width, int32_t height,
552+ struct wl_array *states)
553+{
554+ struct window *window = data;
555+ uint32_t *p;
556+
557+ window->fullscreen = 0;
558+ wl_array_for_each(p, states) {
559+ uint32_t state = *p;
560+ switch (state) {
561+ case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN:
562+ window->fullscreen = 1;
563+ break;
564+ }
565+ }
566+
567+ if (width > 0 && height > 0) {
568+ if (!window->fullscreen) {
569+ window->window_size.width = width;
570+ window->window_size.height = height;
571+ }
572+ window->geometry.width = width;
573+ window->geometry.height = height;
574+ } else if (!window->fullscreen) {
575+ window->geometry = window->window_size;
576+ }
577+
578+ /*if (window->native)
579+ wl_egl_window_resize(window->native,
580+ window->geometry.width,
581+ window->geometry.height, 0, 0);*/
582+}
583+
584+static void
585+handle_toplevel_close(void *data, struct zxdg_toplevel_v6 *xdg_toplevel)
586+{
587+ running = 0;
588+}
589+
590+static const struct zxdg_toplevel_v6_listener xdg_toplevel_listener = {
591+ handle_toplevel_configure,
592+ handle_toplevel_close,
593+};
594+/*
595+static void
596+handle_ivi_surface_configure(void *data, struct ivi_surface *ivi_surface,
597+ int32_t width, int32_t height)
598+{
599+
600+}
601+
602+static const struct ivi_surface_listener ivi_surface_listener = {
603+ handle_ivi_surface_configure,
604+};
605+*/
606+static struct buffer *
607+window_next_buffer(struct window *window)
608+{
609+ struct buffer *buffer = NULL;
610+ int i, ret = 0;
611+
612+ for(i = 0; i < RES_NUM; i++) {
613+ if (!window->image.out_bufs[i].busy) {
614+ buffer = &window->image.out_bufs[i];
615+ break;
616+ }
617+ }
618+
619+ if (!buffer)
620+ return NULL;
621+
622+ if (!buffer->buffer) {
623+ ret = create_dmabuf_buffer(window->display, buffer);
624+ if (ret < 0)
625+ return NULL;
626+ if(i%2)
627+ _load_file(buffer->dma_map, window->tex->size, window->image.fProp.filename);
628+ else
629+ memset(buffer->dma_map, 0, window->tex->size);
630+ }
631+
632+ return buffer;
633+}
634+
635+static void
636+create_surface(struct window *window)
637+{
638+ struct display *display = window->display;
639+
640+ window->surface = wl_compositor_create_surface(display->compositor);
641+ display->cursor_surface =
642+ wl_compositor_create_surface(display->compositor);
643+
644+ if (display->shell) {
645+ window->xdg_surface =
646+ zxdg_shell_v6_get_xdg_surface(display->shell,
647+ window->surface);
648+
649+ assert(window->xdg_surface);
650+
651+ zxdg_surface_v6_add_listener(window->xdg_surface,
652+ &xdg_surface_listener, window);
653+
654+ window->xdg_toplevel =
655+ zxdg_surface_v6_get_toplevel(window->xdg_surface);
656+ zxdg_toplevel_v6_add_listener(window->xdg_toplevel,
657+ &xdg_toplevel_listener, window);
658+
659+ zxdg_toplevel_v6_set_title(window->xdg_toplevel, "simple-configure-mtk");
660+ window->wait_for_configure = true;
661+ wl_surface_commit(window->surface);
662+ } else if (display->fshell) {
663+ zwp_fullscreen_shell_v1_present_surface(display->fshell,
664+ window->surface,
665+ ZWP_FULLSCREEN_SHELL_V1_PRESENT_METHOD_DEFAULT,
666+ NULL);
667+ //} else if (display->ivi_application ) {
668+ // uint32_t id_ivisurf = IVI_SURFACE_ID + (uint32_t)getpid();
669+ // window->ivi_surface =
670+ // ivi_application_surface_create(display->ivi_application,
671+ // id_ivisurf, window->surface);
672+ // if (window->ivi_surface == NULL) {
673+ // fprintf(stderr, "Failed to create ivi_client_surface\n");
674+ // abort();
675+ // }
676+//
677+ // ivi_surface_add_listener(window->ivi_surface,
678+ // &ivi_surface_listener, window);
679+
680+ } else {
681+ assert(0);
682+ }
683+
684+}
685+
686+static void
687+destroy_surface(struct window *window)
688+{
689+ if (window->xdg_toplevel)
690+ zxdg_toplevel_v6_destroy(window->xdg_toplevel);
691+ if (window->xdg_surface)
692+ zxdg_surface_v6_destroy(window->xdg_surface);
693+ //if (window->display->ivi_application)
694+ // ivi_surface_destroy(window->ivi_surface);
695+ if (window->display->fshell)
696+ zwp_fullscreen_shell_v1_release(window->display->fshell);
697+ wl_surface_destroy(window->surface);
698+
699+ if (window->callback)
700+ wl_callback_destroy(window->callback);
701+
702+ if (window->image.out_bufs[0].buffer)
703+ wl_buffer_destroy(window->image.out_bufs[0].buffer);
704+ if (window->image.out_bufs[1].buffer)
705+ wl_buffer_destroy(window->image.out_bufs[1].buffer);
706+ if (window->image.out_bufs[2].buffer)
707+ wl_buffer_destroy(window->image.out_bufs[2].buffer);
708+}
709+
710+static const struct wl_callback_listener frame_listener;
711+
712+static void
713+redraw(void *data, struct wl_callback *callback, uint32_t time)
714+{
715+ struct window *window = data;
716+ struct buffer *buffer;
717+ char filename[MAX_LEN] = {0};
718+ static const uint32_t benchmark_interval = 5;
719+ struct wl_region *region;
720+ struct timeval tv;
721+ int tmp;
722+
723+ buffer = window_next_buffer(window);
724+ if (!buffer) {
725+ fprintf(stderr,
726+ !callback ? "error: Failed to create the first buffer.\n" :
727+ "error: Both buffers busy at redraw(). Server bug?\n");
728+ abort();
729+ }
730+
731+ gettimeofday(&tv, NULL);
732+ time = tv.tv_sec * 1000 + tv.tv_usec / 1000;
733+ if (window->frames == 0)
734+ window->benchmark_time = time;
735+ if (time - window->benchmark_time > (benchmark_interval * 1000)) {
736+ printf("debug: %d frames in %d seconds: %f fps\n",
737+ window->frames,
738+ benchmark_interval,
739+ (float) window->frames / benchmark_interval);
740+ window->benchmark_time = time;
741+ window->frames = 0;
742+ }
743+
744+ if (window->opaque || window->fullscreen) {
745+ region = wl_compositor_create_region(window->display->compositor);
746+ wl_region_add(region, 0, 0,
747+ window->geometry.width,
748+ window->geometry.height);
749+ wl_surface_set_opaque_region(window->surface, region);
750+ wl_region_destroy(region);
751+ } else {
752+ wl_surface_set_opaque_region(window->surface, NULL);
753+ }
754+
755+ wl_surface_attach(window->surface, buffer->buffer, 0, 0);
756+ wl_surface_set_buffer_transform(window->surface,
757+ window->transform);
758+ wl_surface_damage(window->surface,
759+ 0, 0, window->geometry.width, window->geometry.height);
760+
761+ if (callback)
762+ wl_callback_destroy(callback);
763+
764+ window->callback = wl_surface_frame(window->surface);
765+ wl_callback_add_listener(window->callback, &frame_listener, window);
766+ wl_surface_commit(window->surface);
767+ buffer->busy = 1;
768+
769+ window->frames++;
770+}
771+
772+static const struct wl_callback_listener frame_listener = {
773+ redraw
774+};
775+
776+static void
777+pointer_handle_enter(void *data, struct wl_pointer *pointer,
778+ uint32_t serial, struct wl_surface *surface,
779+ wl_fixed_t sx, wl_fixed_t sy)
780+{
781+ struct display *display = data;
782+ struct wl_buffer *buffer;
783+ struct wl_cursor *cursor = display->default_cursor;
784+ struct wl_cursor_image *image;
785+
786+ if (display->window->fullscreen)
787+ wl_pointer_set_cursor(pointer, serial, NULL, 0, 0);
788+ else if (cursor) {
789+ image = display->default_cursor->images[0];
790+ buffer = wl_cursor_image_get_buffer(image);
791+ if (!buffer)
792+ return;
793+ wl_pointer_set_cursor(pointer, serial,
794+ display->cursor_surface,
795+ image->hotspot_x,
796+ image->hotspot_y);
797+ wl_surface_attach(display->cursor_surface, buffer, 0, 0);
798+ wl_surface_damage(display->cursor_surface, 0, 0,
799+ image->width, image->height);
800+ wl_surface_commit(display->cursor_surface);
801+ }
802+
803+}
804+
805+static void
806+pointer_handle_leave(void *data, struct wl_pointer *pointer,
807+ uint32_t serial, struct wl_surface *surface)
808+{
809+}
810+
811+static void
812+pointer_handle_motion(void *data, struct wl_pointer *pointer,
813+ uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
814+{
815+
816+}
817+
818+static void
819+pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
820+ uint32_t serial, uint32_t time, uint32_t button,
821+ uint32_t state)
822+{
823+ struct display *display = data;
824+
825+ if (!display->window->xdg_surface)
826+ return;
827+
828+ if (button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED)
829+ zxdg_toplevel_v6_move(display->window->xdg_toplevel,
830+ display->seat, serial);
831+}
832+
833+static void
834+pointer_handle_axis(void *data, struct wl_pointer *wl_pointer,
835+ uint32_t time, uint32_t axis, wl_fixed_t value)
836+{
837+}
838+
839+static const struct wl_pointer_listener pointer_listener = {
840+ pointer_handle_enter,
841+ pointer_handle_leave,
842+ pointer_handle_motion,
843+ pointer_handle_button,
844+ pointer_handle_axis,
845+};
846+
847+static void
848+touch_handle_down(void *data, struct wl_touch *wl_touch,
849+ uint32_t serial, uint32_t time, struct wl_surface *surface,
850+ int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
851+{
852+ struct display *d = (struct display *)data;
853+
854+ if (!d->shell)
855+ return;
856+
857+ zxdg_toplevel_v6_move(d->window->xdg_toplevel, d->seat, serial);
858+}
859+
860+static void
861+touch_handle_up(void *data, struct wl_touch *wl_touch,
862+ uint32_t serial, uint32_t time, int32_t id)
863+{
864+}
865+
866+static void
867+touch_handle_motion(void *data, struct wl_touch *wl_touch,
868+ uint32_t time, int32_t id, wl_fixed_t x_w, wl_fixed_t y_w)
869+{
870+}
871+
872+static void
873+touch_handle_frame(void *data, struct wl_touch *wl_touch)
874+{
875+}
876+
877+static void
878+touch_handle_cancel(void *data, struct wl_touch *wl_touch)
879+{
880+}
881+
882+static const struct wl_touch_listener touch_listener = {
883+ touch_handle_down,
884+ touch_handle_up,
885+ touch_handle_motion,
886+ touch_handle_frame,
887+ touch_handle_cancel,
888+};
889+
890+static void
891+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
892+ uint32_t format, int fd, uint32_t size)
893+{
894+}
895+
896+static void
897+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
898+ uint32_t serial, struct wl_surface *surface,
899+ struct wl_array *keys)
900+{
901+}
902+
903+static void
904+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
905+ uint32_t serial, struct wl_surface *surface)
906+{
907+}
908+
909+static void
910+keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
911+ uint32_t serial, uint32_t time, uint32_t key,
912+ uint32_t state)
913+{
914+ struct display *d = data;
915+
916+ if (!d->shell)
917+ return;
918+
919+ if (key == KEY_F11 && state) {
920+ if (d->window->fullscreen)
921+ zxdg_toplevel_v6_unset_fullscreen(d->window->xdg_toplevel);
922+ else
923+ zxdg_toplevel_v6_set_fullscreen(d->window->xdg_toplevel, NULL);
924+ } else if (key == KEY_ESC && state)
925+ running = 0;
926+}
927+
928+static void
929+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
930+ uint32_t serial, uint32_t mods_depressed,
931+ uint32_t mods_latched, uint32_t mods_locked,
932+ uint32_t group)
933+{
934+}
935+
936+static const struct wl_keyboard_listener keyboard_listener = {
937+ keyboard_handle_keymap,
938+ keyboard_handle_enter,
939+ keyboard_handle_leave,
940+ keyboard_handle_key,
941+ keyboard_handle_modifiers,
942+};
943+
944+static void
945+seat_handle_capabilities(void *data, struct wl_seat *seat,
946+ enum wl_seat_capability caps)
947+{
948+ struct display *d = data;
949+
950+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !d->pointer) {
951+ d->pointer = wl_seat_get_pointer(seat);
952+ wl_pointer_add_listener(d->pointer, &pointer_listener, d);
953+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && d->pointer) {
954+ wl_pointer_destroy(d->pointer);
955+ d->pointer = NULL;
956+ }
957+
958+ if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !d->keyboard) {
959+ d->keyboard = wl_seat_get_keyboard(seat);
960+ wl_keyboard_add_listener(d->keyboard, &keyboard_listener, d);
961+ } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && d->keyboard) {
962+ wl_keyboard_destroy(d->keyboard);
963+ d->keyboard = NULL;
964+ }
965+
966+ if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !d->touch) {
967+ d->touch = wl_seat_get_touch(seat);
968+ wl_touch_set_user_data(d->touch, d);
969+ wl_touch_add_listener(d->touch, &touch_listener, d);
970+ } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && d->touch) {
971+ wl_touch_destroy(d->touch);
972+ d->touch = NULL;
973+ }
974+}
975+
976+static const struct wl_seat_listener seat_listener = {
977+ seat_handle_capabilities,
978+};
979+
980+
981+static void
982+xdg_shell_ping(void *data, struct zxdg_shell_v6 *shell, uint32_t serial)
983+{
984+ zxdg_shell_v6_pong(shell, serial);
985+}
986+
987+static const struct zxdg_shell_v6_listener xdg_shell_listener = {
988+ xdg_shell_ping,
989+};
990+
991+static void
992+dmabuf_format(void *data, struct zwp_linux_dmabuf_v1 *zwp_linux_dmabuf, uint32_t format)
993+{
994+ fprintf(stderr, "debug: Support drm_format 0x%x \n", format);
995+}
996+
997+static const struct zwp_linux_dmabuf_v1_listener dmabuf_listener = {
998+ dmabuf_format
999+};
1000+
1001+static void
1002+registry_handle_global(void *data, struct wl_registry *registry,
1003+ uint32_t name, const char *interface, uint32_t version)
1004+{
1005+ struct display *d = data;
1006+
1007+ if (strcmp(interface, "wl_compositor") == 0) {
1008+ d->compositor =
1009+ wl_registry_bind(registry, name,
1010+ &wl_compositor_interface, 2);
1011+ } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
1012+ d->shell = wl_registry_bind(registry, name,
1013+ &zxdg_shell_v6_interface, 1);
1014+ zxdg_shell_v6_add_listener(d->shell, &xdg_shell_listener, d);
1015+ } else if (strcmp(interface, "wl_seat") == 0) {
1016+ d->seat = wl_registry_bind(registry, name,
1017+ &wl_seat_interface, 1);
1018+ wl_seat_add_listener(d->seat, &seat_listener, d);
1019+ } else if (strcmp(interface, "zwp_fullscreen_shell_v1") == 0) {
1020+ d->fshell = wl_registry_bind(registry, name,
1021+ &zwp_fullscreen_shell_v1_interface, 1);
1022+ } else if (strcmp(interface, "wl_shm") == 0) {
1023+ d->shm = wl_registry_bind(registry, name,
1024+ &wl_shm_interface, 1);
1025+ d->cursor_theme = wl_cursor_theme_load(NULL, 32, d->shm);
1026+ if (!d->cursor_theme) {
1027+ fprintf(stderr, "unable to load default theme\n");
1028+ return;
1029+ }
1030+ d->default_cursor =
1031+ wl_cursor_theme_get_cursor(d->cursor_theme, "grabbing");
1032+ if (!d->default_cursor) {
1033+ fprintf(stderr, "unable to load default grabbing pointer\n");
1034+ // TODO: abort ?
1035+ }
1036+ //} else if (strcmp(interface, "ivi_application") == 0) {
1037+ // d->ivi_application =
1038+ // wl_registry_bind(registry, name,
1039+ // &ivi_application_interface, 1);
1040+ } else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) {
1041+ d->dmabuf = wl_registry_bind(registry, name,
1042+ &zwp_linux_dmabuf_v1_interface, 1);
1043+ zwp_linux_dmabuf_v1_add_listener(d->dmabuf, &dmabuf_listener, d);
1044+ }
1045+}
1046+
1047+static void
1048+registry_handle_global_remove(void *data, struct wl_registry *registry,
1049+ uint32_t name)
1050+{
1051+}
1052+
1053+static const struct wl_registry_listener registry_listener = {
1054+ registry_handle_global,
1055+ registry_handle_global_remove
1056+};
1057+
1058+static void
1059+destroy_display(struct display *display)
1060+{
1061+ if (display->dmabuf)
1062+ zwp_linux_dmabuf_v1_destroy(display->dmabuf);
1063+
1064+ if (display->shell)
1065+ zxdg_shell_v6_destroy(display->shell);
1066+
1067+ if (display->fshell)
1068+ zwp_fullscreen_shell_v1_release(display->fshell);
1069+
1070+ if (display->compositor)
1071+ wl_compositor_destroy(display->compositor);
1072+
1073+ wl_surface_destroy(display->cursor_surface);
1074+ if (display->cursor_theme)
1075+ wl_cursor_theme_destroy(display->cursor_theme);
1076+
1077+ //if (display->ivi_application)
1078+ // ivi_application_destroy(display->ivi_application);
1079+
1080+ wl_registry_destroy(display->registry);
1081+ wl_display_flush(display->display);
1082+ wl_display_disconnect(display->display);
1083+ free(display);
1084+}
1085+
1086+static struct display *
1087+create_display(struct window *window)
1088+{
1089+ struct display *display;
1090+
1091+ display = malloc(sizeof *display);
1092+ if (display == NULL) {
1093+ fprintf(stderr, "out of memory\n");
1094+ exit(1);
1095+ }
1096+ display->display = wl_display_connect(NULL);
1097+ assert(display->display);
1098+ display->window = window;
1099+
1100+ display->registry = wl_display_get_registry(display->display);
1101+ wl_registry_add_listener(display->registry,
1102+ &registry_listener, display);
1103+ wl_display_roundtrip(display->display);
1104+ if (display->dmabuf == NULL) {
1105+ fprintf(stderr, "No zwp_linux_dmabuf_v1 global found\n");
1106+ exit(1);
1107+ }
1108+ wl_display_roundtrip(display->display);
1109+
1110+ return display;
1111+}
1112+
1113+static void
1114+signal_int(int signum)
1115+{
1116+ running = 0;
1117+}
1118+
1119+/*
1120+ * parse the message inputed for rawdata
1121+ * egg: -F /usr/share/weston/rawdata.nv16:720x480@5
1122+ * filename:widthxheight@format
1123+*/
1124+static int parse_file(struct file_arg *file, char *p)
1125+{
1126+ char *end;
1127+ char *pPos = p;
1128+ int len, i;
1129+
1130+ len = strlen(pPos) + 1;
1131+ for (i = 0; i < len; i++)
1132+ if(pPos[i] == ':')
1133+ pPos[i] = '\0';
1134+
1135+ memcpy(file->filename, pPos, strlen(pPos) + 1);
1136+ pPos = pPos + strlen(pPos) + 1;
1137+ file->width = strtoul(pPos, &end, 10);
1138+ if (*end != 'x')
1139+ return -EINVAL;
1140+ pPos = end + 1;
1141+ file->height = strtoul(pPos, &end, 10);
1142+ if (*end != '@')
1143+ return -EINVAL;
1144+ pPos = end + 1;
1145+ file->format = strtoul(pPos, &end, 10);
1146+ if (*end != '\0')
1147+ return -EINVAL;
1148+ return 0;
1149+}
1150+
1151+static void init_window(struct window *window)
1152+{
1153+ window->geometry.width = 0;
1154+ window->geometry.height = 0;
1155+ window->buffer_size = 32;
1156+ window->transform = WL_OUTPUT_TRANSFORM_NORMAL;
1157+ window->opaque = 1;
1158+ window->overlay = 0;
1159+ window->format = 0;
1160+ window->drm_card_fd = -1;
1161+}
1162+
1163+static void
1164+usage(int error_code)
1165+{
1166+ fprintf(stderr, "Usage: mtkdraw-dma [OPTIONS]\n\n"
1167+ " -f Run in fullscreen mode(only desktop-shell valid)\n"
1168+ " -o Create an opaque surface\n"
1169+ " -s Use a 16 bpp EGL config\n"
1170+ " -t Set display buffer transform(0~7)\n"
1171+ " -F rawdata message(rawdata size provided is 320x480)\n"
1172+ " eg:-F /usr/share/weston/rawdata.nv16:320x480@5\n"
1173+ " @14 stand for nv16 format, formats supported as follows\n"
1174+ " now only support 8 formats\n"
1175+ " 0 --> IMG_FORMAT_RGB565\n"
1176+ " 1 --> IMG_FORMAT_XRGB8888\n"
1177+ " 2 --> IMG_FORMAT_ARGB8888\n"
1178+ " 3 --> IMG_FORMAT_YUYV\n"
1179+ " 4 --> IMG_FORMAT_NV12\n"
1180+ " 5 --> IMG_FORMAT_NV16\n"
1181+ " 6 --> IMG_FORMAT_YUV420\n"
1182+ " 7 --> IMG_FORMAT_YVU420\n"
1183+ " -d Enable debug output\n"
1184+ " -overlay Enable overlay switch\n"
1185+ " -h This help text\n\n");
1186+
1187+ exit(error_code);
1188+}
1189+
1190+int
1191+main(int argc, char **argv)
1192+{
1193+ struct sigaction sigint;
1194+ struct display *display;
1195+ struct window window = { 0 };
1196+ int i, ret = 0;
1197+ struct file_arg *file;
1198+
1199+ init_window(&window);
1200+
1201+ for (i = 1; i < argc; i++) {
1202+ if (strcmp("-f", argv[i]) == 0)
1203+ window.fullscreen = 1;
1204+ else if (strcmp("-o", argv[i]) == 0)
1205+ window.opaque = 0;
1206+ else if (strcmp("-s", argv[i]) == 0)
1207+ window.buffer_size = 16;
1208+ else if (strcmp("-t", argv[i]) == 0)
1209+ window.transform = atoi(argv[++i]);
1210+ else if (strcmp("-F", argv[i]) == 0){
1211+ ret = parse_file(&window.image.fProp, argv[++i]);
1212+ if (ret < 0)
1213+ fprintf(stderr, "error: input error, like: -F "
1214+ "/usr/share/weston/rawdata.nv16:320x480@5\n");
1215+ }
1216+ else if (strcmp("-d", argv[i]) == 0)
1217+ debug = 1;
1218+ else if (strcmp("-overlay", argv[i]) == 0)
1219+ window.overlay = 1;
1220+ else if (strcmp("-h", argv[i]) == 0)
1221+ usage(EXIT_SUCCESS);
1222+ else
1223+ usage(EXIT_FAILURE);
1224+ }
1225+
1226+ file = &window.image.fProp;
1227+ if((file->width == 0) || (file->height ==0) || (file->filename == 0))
1228+ {
1229+ /*default sample*/
1230+ file->width = 320;
1231+ file->height = 480;
1232+ file->format = IMG_FORMAT_NV16;
1233+ snprintf(file->filename, MAX_LEN, "/usr/share/weston/rawdata.nv16");
1234+ fprintf(stderr, "debug: You have choose the default example!\n");
1235+ }
1236+
1237+ fprintf(stderr, "debug: The file is %s width/height/format[%d %d %d]\n",
1238+ file->filename, file->width, file->height, file->format);
1239+
1240+ window.geometry.width = file->width;
1241+ window.geometry.height = file->height;
1242+ window.window_size = window.geometry;
1243+
1244+ display = create_display(&window);
1245+ window.display = display;
1246+ //display->window = &window;
1247+
1248+ create_surface(&window);
1249+
1250+ ret = init_img_texture(&window);
1251+ if (ret < 0){
1252+ fprintf(stderr, "error: init_img_texture failed\n");
1253+ return -1;
1254+ }
1255+
1256+ window.drm_card_fd = _kms_device_fd();
1257+ if (window.drm_card_fd < 0) {
1258+ fprintf(stderr, "error: fail to get drm_card_fd !\n");
1259+ return -1;
1260+ }
1261+
1262+ sigint.sa_handler = signal_int;
1263+ sigemptyset(&sigint.sa_mask);
1264+ sigint.sa_flags = SA_RESETHAND;
1265+ sigaction(SIGINT, &sigint, NULL);
1266+
1267+ if (!window.wait_for_configure)
1268+ redraw(&window, NULL, 0);
1269+
1270+ while (running && ret != -1)
1271+ ret = wl_display_dispatch(display->display);
1272+
1273+ fprintf(stderr, "debug: simple-configure-mtk exiting\n");
1274+ destroy_surface(&window);
1275+ destroy_display(display);
1276+
1277+ return 0;
1278+}
1279+
1280+
1281diff --git a/configure.ac b/configure.ac
1282index 8b3e17e..e4bf195 100644
1283--- a/configure.ac
1284+++ b/configure.ac
1285@@ -411,6 +411,7 @@ if ! test "x$enable_simple_dmabuf_v4l_client" = "xno"; then
1286 enable_simple_dmabuf_v4l_client="$have_simple_dmabuf_v4l_client"
1287 fi
1288 AM_CONDITIONAL(BUILD_SIMPLE_DMABUF_V4L_CLIENT, test "x$enable_simple_dmabuf_v4l_client" = "xyes")
1289+AM_CONDITIONAL(BUILD_SIMPLE_CONFIGURE_MTK_CLIENT, test "x$enable_simple_dmabuf_v4l_client" = "xyes")
1290
1291 AC_ARG_ENABLE(clients, [ --enable-clients],, enable_clients=yes)
1292 AM_CONDITIONAL(BUILD_CLIENTS, test x$enable_clients = xyes)
1293--
12941.9.1
1295