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