small update following gbm change: gbm_bo_get_shared_handle()
From fb0e0eec5064f8af3e126a457fc23173a8bb6d49 Mon Sep 17 00:00:00 2001 From: Zhao Halley <halley.z...@intel.com> Date: Tue, 5 Jun 2012 14:59:56 +0800 Subject: [PATCH 09/10] test: test case drm-test-client in src/egl/wayland/wayland-drm - it shows how wayland-drm protocol works between server and client buffer are shared basing on dri image - XRGB and YUYV format are supported, it can render to overlay plane potentially --- configure.ac | 3 +- src/egl/wayland/wayland-drm/Makefile.am | 15 +- src/egl/wayland/wayland-drm/drm-test-client.c | 456 +++++++++++++++++++++++++ 3 files changed, 472 insertions(+), 2 deletions(-) mode change 100644 => 100755 configure.ac create mode 100755 src/egl/wayland/wayland-drm/drm-test-client.c mode change 100644 => 100755 tests/Makefile.am diff --git a/configure.ac b/configure.ac old mode 100644 new mode 100755 index 3bc59ca..044d19e --- a/configure.ac +++ b/configure.ac @@ -2033,7 +2033,8 @@ AC_CONFIG_FILES([configs/autoconf src/mesa/drivers/dri/radeon/Makefile src/mesa/drivers/dri/swrast/Makefile tests/Makefile - tests/glx/Makefile]) + tests/glx/Makefile + ]) dnl Replace the configs/current symlink AC_CONFIG_COMMANDS([configs],[ diff --git a/src/egl/wayland/wayland-drm/Makefile.am b/src/egl/wayland/wayland-drm/Makefile.am index cf15eda..dce9184 100644 --- a/src/egl/wayland/wayland-drm/Makefile.am +++ b/src/egl/wayland/wayland-drm/Makefile.am @@ -10,6 +10,19 @@ noinst_HEADERS = wayland-drm.h BUILT_SOURCES = wayland-drm-protocol.c \ wayland-drm-client-protocol.h \ wayland-drm-server-protocol.h -CLEANFILES = $(BUILT_SOURCES) + +noinst_PROGRAMS = drm_test_client +drm_test_client_CFLAGS = $(DEFINES) \ + -I$(top_srcdir)/src/gbm/main \ + $(WAYLAND_CFLAGS) \ + $(LIBDRM_CFLAGS) + +drm_test_client_LDADD = $(WAYLAND_LIBS) $(LIBDRM_LIBS) +drm_test_client_LDADD += $(top_srcdir)/src/gbm/libgbm.la + +drm_test_client_SOURCES = drm-test-client.c wayland-drm-protocol.c \ + wayland-drm-client-protocol.h + +CLEANFILES = $(BUILT_SOURCES) $(drm_test_client_SOURCES) @wayland_scanner_rules@ diff --git a/src/egl/wayland/wayland-drm/drm-test-client.c b/src/egl/wayland/wayland-drm/drm-test-client.c new file mode 100755 index 0000000..d396aee --- /dev/null +++ b/src/egl/wayland/wayland-drm/drm-test-client.c @@ -0,0 +1,456 @@ +/* + * Copyright © 2012 Halley Zhao + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: + * Halley Zhao <halley.z...@intel.com> + */ + + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <string.h> +#include <assert.h> +#include <xf86drm.h> +#include "gbm.h" +#include <wayland-client.h> +#include <wayland-client-protocol.h> +#include "wayland-drm-client-protocol.h" + +int win_width = 256, win_height = 256; +int drm_fd = -1; +int wayland_server_support_yuyv = 0; +struct wl_drm *wl_drm; + +struct display { + struct wl_display *display; + struct wl_compositor *compositor; + struct wl_shell *shell; + struct wl_input_device *input; + uint32_t mask; + struct gbm_device *gbm; +}; + +struct window { + struct display *display; + struct wl_surface *surface; + struct wl_shell_surface *shell_surface; + struct wl_callback *callback; + struct { + int width, height; + } geometry; + unsigned int format; + struct wl_buffer *buffer; + struct gbm_bo *gbm_bo; + unsigned int bo_pitch; +}; + +void fill_window_XRGB(struct window *win); +void fill_window_YUYV(struct window *win); +int wayland_drm_init(struct wl_display *wl_dpy); +void wayland_drm_destroy(void); +void redraw(void *data, struct wl_callback *callback, uint32_t time); + +void fill_window_XRGB(struct window *win) +{ + unsigned char *mem = malloc (win->bo_pitch * win_height); + static int color_index = 0; + static unsigned int color_arr[4] = {0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff}; + unsigned int color; + int i; + unsigned int *i_ptr; + unsigned char *c_ptr; + + color = color_arr[color_index]; + i_ptr = (unsigned int *)mem; + for (i=0; i<win_width/2; i++) { + *(i_ptr+i) = color; + } + color = color_arr[(color_index+1)%4]; + for (i=win_width/2+1; i<win_width; i++) { + *(i_ptr+i) = color; + } + + c_ptr = mem + win->bo_pitch; + for (i = 1; i<win_height/2; i++) { + memcpy (c_ptr, i_ptr, win_width*4); + c_ptr += win->bo_pitch; + } + + color = color_arr[(color_index+2)%4]; + i_ptr = (unsigned int *)c_ptr; + for (i=0; i<win_width/2; i++) { + *(i_ptr+i) = color; + } + color = color_arr[(color_index+3)%4]; + for (i=win_width/2+1; i<win_width; i++) { + *(i_ptr+i) = color; + } + + c_ptr += win->bo_pitch; + for (i = win_height/2+2; i<win_height; i++) { + memcpy (c_ptr, i_ptr, win_width*4); + c_ptr += win->bo_pitch; + } + + gbm_bo_write(win->gbm_bo, mem, win->bo_pitch * win_height); + free(mem); + color_index = (color_index+1) % 4; + +} + +void fill_window_YUYV(struct window *win) +{ + unsigned char *mem = malloc (win->bo_pitch * win_height); + + static unsigned int color_arr[4] = {0x00ff00ff, 0x80ff00ff, 0x00ff80ff, 0x80ff80ff}; + static int color_index = 0; + unsigned int color; + int i; + unsigned int *i_ptr; + unsigned char *c_ptr; + + i_ptr = (unsigned int *)mem; + color = color_arr[color_index]; + for (i=0; i<win_width/4; i++) { + *(i_ptr+i) = color; + } + color = color_arr[(color_index+1)%4]; + for (i=win_width/4+1; i<win_width/2; i++) { + *(i_ptr+i) = color; + } + + c_ptr = mem + win->bo_pitch; + for (i = 1; i<win_height/2; i++) { + memcpy (c_ptr, (unsigned char*)i_ptr, win_width*2); + c_ptr += win->bo_pitch; + } + + i_ptr = (unsigned int *) c_ptr; + color = color_arr[(color_index+2)%4]; + for (i=0; i<win_width/4; i++) { + *(i_ptr+i) = color; + } + color = color_arr[(color_index+3)%4]; + for (i=win_width/4+1; i<win_width/2; i++) { + *(i_ptr+i) = color; + } + + c_ptr += win->bo_pitch; + for (i = win_height/2+2; i<win_height; i++) { + memcpy (c_ptr, (unsigned char*)i_ptr, win_width*2); + c_ptr += win->bo_pitch; + } + + gbm_bo_write(win->gbm_bo, mem, win->bo_pitch * win_height); + free(mem); + + color_index = (color_index+1) % 4; +} + +static void +drm_handle_device(void *data, struct wl_drm *drm, const char *device) +{ + drm_magic_t magic; + struct stat st; + + if (stat(device, &st) < 0) { + printf("failed to identify %s (errno %d)", + device, errno); + return; + } + + if (!S_ISCHR(st.st_mode)) { + printf("%s is not a device", device); + return; + } + drm_fd = open(device, O_RDWR); + if (drm_fd < 0) { + printf("failed to open %s (errno %d)", + device, errno); + return; + } + + drmGetMagic(drm_fd, &magic); + wl_drm_authenticate(wl_drm, magic); +} + +static void +drm_handle_format(void *data, struct wl_drm *drm, uint32_t format) +{ + if (format == WL_DRM_FORMAT_YUYV) { + wayland_server_support_yuyv = 1; + } + +} + +static void +drm_handle_authenticated(void *data, struct wl_drm *drm) +{ + +} + +static const struct wl_drm_listener drm_listener = { + drm_handle_device, + drm_handle_format, + drm_handle_authenticated +}; + +static void +wayland_drm_finalize(void) +{ + + if (wl_drm) { + wl_drm_destroy(wl_drm); + wl_drm = NULL; + } + + if (drm_fd >= 0) { + close(drm_fd); + drm_fd = -1; + } +} + +int +wayland_drm_init(struct wl_display *wl_dpy) +{ + uint32_t id; + + assert(wl_dpy); + + id = wl_display_get_global(wl_dpy, "wl_drm", 1); + if (!id) { + wl_display_roundtrip(wl_dpy); + id = wl_display_get_global(wl_dpy, "wl_drm", 1); + if (!id) + return -1; + } + + wl_drm = wl_display_bind(wl_dpy, id, &wl_drm_interface); + if (!wl_drm) + return -1; + + wl_drm_add_listener(wl_drm, &drm_listener, NULL); + wl_display_roundtrip(wl_dpy); + if (drm_fd < 0) + return -1; + + wl_display_roundtrip(wl_dpy); + + return 0; +} + +static const struct wl_callback_listener frame_listener; + +void +redraw(void *data, struct wl_callback *callback, uint32_t time) +{ + struct window *window = data; + if (callback) + wl_callback_destroy(callback); + + if (window->format == WL_DRM_FORMAT_XRGB8888) { + fill_window_XRGB(window); + } + else { + fill_window_YUYV(window); + } + + // update + wl_surface_attach( + window->surface, + window->buffer, + 0, 0 + ); + wl_surface_damage( + window->surface, + 0, 0, win_width, win_height + ); + + window->callback = wl_surface_frame(window->surface); + wl_callback_add_listener(window->callback, &frame_listener, window); + sleep(1); +} + + +static const struct wl_callback_listener frame_listener = { + redraw +}; + +static void +display_handle_global(struct wl_display *display, uint32_t id, + const char *interface, uint32_t version, void *data) +{ + struct display *d = data; + + if (strcmp(interface, "wl_compositor") == 0) { + d->compositor = + wl_display_bind(display, id, &wl_compositor_interface); + } else if (strcmp(interface, "wl_shell") == 0) { + d->shell = wl_display_bind(display, id, &wl_shell_interface); + } else if (strcmp(interface, "wl_input_device") == 0) { + d->input = wl_display_bind(display, id, &wl_input_device_interface); + // wl_input_device_add_listener(d->input, &input_listener, d); + } +} + +static void +handle_ping(void *data, struct wl_shell_surface *shell_surface, + uint32_t serial) +{ + wl_shell_surface_pong(shell_surface, serial); +} + +static void +handle_configure(void *data, struct wl_shell_surface *shell_surface, + uint32_t edges, int32_t width, int32_t height) +{ + struct window *window = data; + + window->geometry.width = width; + window->geometry.height = height; +} + +static void +handle_popup_done(void *data, struct wl_shell_surface *shell_surface) +{ +} + +static const struct wl_shell_surface_listener shell_surface_listener = { + handle_ping, + handle_configure, + handle_popup_done +}; + +static int +event_mask_update(uint32_t mask, void *data) +{ + struct display *d = data; + + d->mask = mask; + + return 0; +} +int main(int argc, char **argv) +{ + + struct display dpy; + struct window win; + int running = 1; + win.format = WL_DRM_FORMAT_XRGB8888; + char c=0; + + while ((c =getopt(argc,argv,"c:w:h:?") ) != EOF) { + switch (c) { + case '?': + printf("./wayland_drm_test -c (XRGB/YUYV) -w window_width -h window_height\n"); + exit(0); + break; + case 'c': + if (!strcmp(optarg, "YUYV")) { + win.format = WL_DRM_FORMAT_YUYV; + } + break; + case 'w': + win_width = atoi(optarg); + break; + case 'h': + win_height = atoi(optarg); + break; + default: + printf("./wayland_drm_test -c (XRGB/YUYV) -w window_width -h window_height\n"); + exit(0); + break; + } + } + + win.geometry.width = win_width; + win.geometry.height = win_height; + + // wl_display connection + dpy.display = wl_display_connect(NULL); + assert(dpy.display); + + wl_display_add_global_listener(dpy.display, + display_handle_global, &dpy); + + wl_display_get_fd(dpy.display, event_mask_update, &dpy); + wl_display_iterate(dpy.display, WL_DISPLAY_READABLE); + + // create wl_surface + win.surface = wl_compositor_create_surface(dpy.compositor); + win.shell_surface = wl_shell_get_shell_surface(dpy.shell, + win.surface); + + wl_shell_surface_add_listener(win.shell_surface, &shell_surface_listener, &win); + + wl_shell_surface_set_toplevel(win.shell_surface); + + // wayland drm initialization + wayland_drm_init(dpy.display); + if(!wayland_server_support_yuyv) { + win.format = WL_DRM_FORMAT_XRGB8888; + } + + // create buffer object + dpy.gbm = gbm_create_device(drm_fd); + win.gbm_bo = gbm_bo_create(dpy.gbm, win_width, win_height, win.format, GBM_BO_USE_RENDERING|GBM_BO_USE_WRITE); + win.bo_pitch = gbm_bo_get_pitch(win.gbm_bo); + + unsigned int buf_name = gbm_bo_get_shared_handle(win.gbm_bo).u32; + + // create wl_buffer + struct wl_buffer *buffer = wl_drm_create_buffer(wl_drm, buf_name, win_width, win_height, win.bo_pitch, win.format); + win.buffer = buffer; + redraw (&win, NULL, 0); + + while (running) { + wl_display_iterate(dpy.display, dpy.mask); + sleep(0.3); + } + + wayland_drm_finalize(); + + gbm_bo_destroy(win.gbm_bo); + + wl_shell_surface_destroy(win.shell_surface); + wl_surface_destroy(win.surface); + + if (win.callback) + wl_callback_destroy(win.callback); + + if (dpy.shell) + wl_shell_destroy(dpy.shell); + + if (dpy.compositor) + wl_compositor_destroy(dpy.compositor); + + wl_display_flush(dpy.display); + wl_display_disconnect(dpy.display); + + return 0; +} + diff --git a/tests/Makefile.am b/tests/Makefile.am old mode 100644 new mode 100755 -- 1.7.5.4 On Thu, 2012-06-14 at 18:32 +0800, Zhao Halley wrote: > - it shows how wayland-drm protocol works between server and client > buffer are shared basing on dri image > - XRGB and YUYV format are supported, > it can render to overlay plane potentially > --- > configure.ac | 3 +- > src/egl/wayland/wayland-drm/Makefile.am | 14 +- > src/egl/wayland/wayland-drm/drm-test-client.c | 456 > +++++++++++++++++++++++++ > 3 files changed, 471 insertions(+), 2 deletions(-) > mode change 100644 => 100755 configure.ac > create mode 100755 src/egl/wayland/wayland-drm/drm-test-client.c > mode change 100644 => 100755 tests/Makefile.am > > diff --git a/configure.ac b/configure.ac > old mode 100644 > new mode 100755 > index 3bc59ca..044d19e > --- a/configure.ac > +++ b/configure.ac > @@ -2033,7 +2033,8 @@ AC_CONFIG_FILES([configs/autoconf > src/mesa/drivers/dri/radeon/Makefile > src/mesa/drivers/dri/swrast/Makefile > tests/Makefile > - tests/glx/Makefile]) > + tests/glx/Makefile > + ]) > > dnl Replace the configs/current symlink > AC_CONFIG_COMMANDS([configs],[ > diff --git a/src/egl/wayland/wayland-drm/Makefile.am > b/src/egl/wayland/wayland-drm/Makefile.am > index cf15eda..55ef063 100644 > --- a/src/egl/wayland/wayland-drm/Makefile.am > +++ b/src/egl/wayland/wayland-drm/Makefile.am > @@ -10,6 +10,18 @@ noinst_HEADERS = wayland-drm.h > BUILT_SOURCES = wayland-drm-protocol.c \ > wayland-drm-client-protocol.h \ > wayland-drm-server-protocol.h > -CLEANFILES = $(BUILT_SOURCES) > + > +noinst_PROGRAMS = drm_test_client > +drm_test_client_CFLAGS = $(DEFINES) \ > + $(WAYLAND_CFLAGS) \ > + $(LIBDRM_CFLAGS) > + > +drm_test_client_LDADD = $(WAYLAND_LIBS) $(LIBDRM_LIBS) > +drm_test_client_LDADD += $(top_srcdir)/src/gbm/libgbm.la > + > +drm_test_client_SOURCES = drm-test-client.c wayland-drm-protocol.c \ > + wayland-drm-client-protocol.h > + > +CLEANFILES = $(BUILT_SOURCES) $(drm_test_client_SOURCES) > > @wayland_scanner_rules@ > diff --git a/src/egl/wayland/wayland-drm/drm-test-client.c > b/src/egl/wayland/wayland-drm/drm-test-client.c > new file mode 100755 > index 0000000..05893ad > --- /dev/null > +++ b/src/egl/wayland/wayland-drm/drm-test-client.c > @@ -0,0 +1,456 @@ > +/* > + * Copyright © 2012 Halley Zhao > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, > + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF > + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND > + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT > + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, > + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > + * DEALINGS IN THE SOFTWARE. > + * > + * Authors: > + * Halley Zhao <halley.z...@intel.com> > + */ > + > + > +#include <stdlib.h> > +#include <stdio.h> > +#include <unistd.h> > +#include <errno.h> > +#include <fcntl.h> > +#include <sys/stat.h> > +#include <string.h> > +#include <assert.h> > +#include <xf86drm.h> > +#include <gbm.h> > +#include <wayland-client.h> > +#include <wayland-client-protocol.h> > +#include "wayland-drm-client-protocol.h" > + > +int win_width = 256, win_height = 256; > +int drm_fd = -1; > +int wayland_server_support_yuyv = 0; > +struct wl_drm *wl_drm; > + > +struct display { > + struct wl_display *display; > + struct wl_compositor *compositor; > + struct wl_shell *shell; > + struct wl_input_device *input; > + uint32_t mask; > + struct gbm_device *gbm; > +}; > + > +struct window { > + struct display *display; > + struct wl_surface *surface; > + struct wl_shell_surface *shell_surface; > + struct wl_callback *callback; > + struct { > + int width, height; > + } geometry; > + unsigned int format; > + struct wl_buffer *buffer; > + struct gbm_bo *gbm_bo; > + unsigned int bo_pitch; > +}; > + > +void fill_window_XRGB(struct window *win); > +void fill_window_YUYV(struct window *win); > +int wayland_drm_init(struct wl_display *wl_dpy); > +void wayland_drm_destroy(void); > +void redraw(void *data, struct wl_callback *callback, uint32_t time); > + > +void fill_window_XRGB(struct window *win) > +{ > + unsigned char *mem = malloc (win->bo_pitch * win_height); > + static int color_index = 0; > + static unsigned int color_arr[4] = {0xff000000, 0x00ff0000, 0x0000ff00, > 0x000000ff}; > + unsigned int color; > + int i; > + unsigned int *i_ptr; > + unsigned char *c_ptr; > + > + color = color_arr[color_index]; > + i_ptr = (unsigned int *)mem; > + for (i=0; i<win_width/2; i++) { > + *(i_ptr+i) = color; > + } > + color = color_arr[(color_index+1)%4]; > + for (i=win_width/2+1; i<win_width; i++) { > + *(i_ptr+i) = color; > + } > + > + c_ptr = mem + win->bo_pitch; > + for (i = 1; i<win_height/2; i++) { > + memcpy (c_ptr, i_ptr, win_width*4); > + c_ptr += win->bo_pitch; > + } > + > + color = color_arr[(color_index+2)%4]; > + i_ptr = (unsigned int *)c_ptr; > + for (i=0; i<win_width/2; i++) { > + *(i_ptr+i) = color; > + } > + color = color_arr[(color_index+3)%4]; > + for (i=win_width/2+1; i<win_width; i++) { > + *(i_ptr+i) = color; > + } > + > + c_ptr += win->bo_pitch; > + for (i = win_height/2+2; i<win_height; i++) { > + memcpy (c_ptr, i_ptr, win_width*4); > + c_ptr += win->bo_pitch; > + } > + > + gbm_bo_write(win->gbm_bo, mem, win->bo_pitch * win_height); > + free(mem); > + color_index = (color_index+1) % 4; > + > +} > + > +void fill_window_YUYV(struct window *win) > +{ > + unsigned char *mem = malloc (win->bo_pitch * win_height); > + > + static unsigned int color_arr[4] = {0x00ff00ff, 0x80ff00ff, 0x00ff80ff, > 0x80ff80ff}; > + static int color_index = 0; > + unsigned int color; > + int i; > + unsigned int *i_ptr; > + unsigned char *c_ptr; > + > + i_ptr = (unsigned int *)mem; > + color = color_arr[color_index]; > + for (i=0; i<win_width/4; i++) { > + *(i_ptr+i) = color; > + } > + color = color_arr[(color_index+1)%4]; > + for (i=win_width/4+1; i<win_width/2; i++) { > + *(i_ptr+i) = color; > + } > + > + c_ptr = mem + win->bo_pitch; > + for (i = 1; i<win_height/2; i++) { > + memcpy (c_ptr, (unsigned char*)i_ptr, win_width*2); > + c_ptr += win->bo_pitch; > + } > + > + i_ptr = (unsigned int *) c_ptr; > + color = color_arr[(color_index+2)%4]; > + for (i=0; i<win_width/4; i++) { > + *(i_ptr+i) = color; > + } > + color = color_arr[(color_index+3)%4]; > + for (i=win_width/4+1; i<win_width/2; i++) { > + *(i_ptr+i) = color; > + } > + > + c_ptr += win->bo_pitch; > + for (i = win_height/2+2; i<win_height; i++) { > + memcpy (c_ptr, (unsigned char*)i_ptr, win_width*2); > + c_ptr += win->bo_pitch; > + } > + > + gbm_bo_write(win->gbm_bo, mem, win->bo_pitch * win_height); > + free(mem); > + > + color_index = (color_index+1) % 4; > +} > + > +static void > +drm_handle_device(void *data, struct wl_drm *drm, const char *device) > +{ > + drm_magic_t magic; > + struct stat st; > + > + if (stat(device, &st) < 0) { > + printf("failed to identify %s (errno %d)", > + device, errno); > + return; > + } > + > + if (!S_ISCHR(st.st_mode)) { > + printf("%s is not a device", device); > + return; > + } > + drm_fd = open(device, O_RDWR); > + if (drm_fd < 0) { > + printf("failed to open %s (errno %d)", > + device, errno); > + return; > + } > + > + drmGetMagic(drm_fd, &magic); > + wl_drm_authenticate(wl_drm, magic); > +} > + > +static void > +drm_handle_format(void *data, struct wl_drm *drm, uint32_t format) > +{ > + if (format == WL_DRM_FORMAT_YUYV) { > + wayland_server_support_yuyv = 1; > + } > + > +} > + > +static void > +drm_handle_authenticated(void *data, struct wl_drm *drm) > +{ > + > +} > + > +static const struct wl_drm_listener drm_listener = { > + drm_handle_device, > + drm_handle_format, > + drm_handle_authenticated > +}; > + > +static void > +wayland_drm_finalize(void) > +{ > + > + if (wl_drm) { > + wl_drm_destroy(wl_drm); > + wl_drm = NULL; > + } > + > + if (drm_fd >= 0) { > + close(drm_fd); > + drm_fd = -1; > + } > +} > + > +int > +wayland_drm_init(struct wl_display *wl_dpy) > +{ > + uint32_t id; > + > + assert(wl_dpy); > + > + id = wl_display_get_global(wl_dpy, "wl_drm", 1); > + if (!id) { > + wl_display_roundtrip(wl_dpy); > + id = wl_display_get_global(wl_dpy, "wl_drm", 1); > + if (!id) > + return -1; > + } > + > + wl_drm = wl_display_bind(wl_dpy, id, &wl_drm_interface); > + if (!wl_drm) > + return -1; > + > + wl_drm_add_listener(wl_drm, &drm_listener, NULL); > + wl_display_roundtrip(wl_dpy); > + if (drm_fd < 0) > + return -1; > + > + wl_display_roundtrip(wl_dpy); > + > + return 0; > +} > + > +static const struct wl_callback_listener frame_listener; > + > +void > +redraw(void *data, struct wl_callback *callback, uint32_t time) > +{ > + struct window *window = data; > + if (callback) > + wl_callback_destroy(callback); > + > + if (window->format == WL_DRM_FORMAT_XRGB8888) { > + fill_window_XRGB(window); > + } > + else { > + fill_window_YUYV(window); > + } > + > + // update > + wl_surface_attach( > + window->surface, > + window->buffer, > + 0, 0 > + ); > + wl_surface_damage( > + window->surface, > + 0, 0, win_width, win_height > + ); > + > + window->callback = wl_surface_frame(window->surface); > + wl_callback_add_listener(window->callback, &frame_listener, window); > + sleep(1); > +} > + > + > +static const struct wl_callback_listener frame_listener = { > + redraw > +}; > + > +static void > +display_handle_global(struct wl_display *display, uint32_t id, > + const char *interface, uint32_t version, void *data) > +{ > + struct display *d = data; > + > + if (strcmp(interface, "wl_compositor") == 0) { > + d->compositor = > + wl_display_bind(display, id, &wl_compositor_interface); > + } else if (strcmp(interface, "wl_shell") == 0) { > + d->shell = wl_display_bind(display, id, &wl_shell_interface); > + } else if (strcmp(interface, "wl_input_device") == 0) { > + d->input = wl_display_bind(display, id, > &wl_input_device_interface); > + // wl_input_device_add_listener(d->input, &input_listener, d); > + } > +} > + > +static void > +handle_ping(void *data, struct wl_shell_surface *shell_surface, > + uint32_t serial) > +{ > + wl_shell_surface_pong(shell_surface, serial); > +} > + > +static void > +handle_configure(void *data, struct wl_shell_surface *shell_surface, > + uint32_t edges, int32_t width, int32_t height) > +{ > + struct window *window = data; > + > + window->geometry.width = width; > + window->geometry.height = height; > +} > + > +static void > +handle_popup_done(void *data, struct wl_shell_surface *shell_surface) > +{ > +} > + > +static const struct wl_shell_surface_listener shell_surface_listener = { > + handle_ping, > + handle_configure, > + handle_popup_done > +}; > + > +static int > +event_mask_update(uint32_t mask, void *data) > +{ > + struct display *d = data; > + > + d->mask = mask; > + > + return 0; > +} > +int main(int argc, char **argv) > +{ > + > + struct display dpy; > + struct window win; > + int running = 1; > + win.format = WL_DRM_FORMAT_XRGB8888; > + char c=0; > + > + while ((c =getopt(argc,argv,"c:w:h:?") ) != EOF) { > + switch (c) { > + case '?': > + printf("./wayland_drm_test -c (XRGB/YUYV) -w window_width -h > window_height\n"); > + exit(0); > + break; > + case 'c': > + if (!strcmp(optarg, "YUYV")) { > + win.format = WL_DRM_FORMAT_YUYV; > + } > + break; > + case 'w': > + win_width = atoi(optarg); > + break; > + case 'h': > + win_height = atoi(optarg); > + break; > + default: > + printf("./wayland_drm_test -c (XRGB/YUYV) -w window_width -h > window_height\n"); > + exit(0); > + break; > + } > + } > + > + win.geometry.width = win_width; > + win.geometry.height = win_height; > + > + // wl_display connection > + dpy.display = wl_display_connect(NULL); > + assert(dpy.display); > + > + wl_display_add_global_listener(dpy.display, > + display_handle_global, &dpy); > + > + wl_display_get_fd(dpy.display, event_mask_update, &dpy); > + wl_display_iterate(dpy.display, WL_DISPLAY_READABLE); > + > + // create wl_surface > + win.surface = wl_compositor_create_surface(dpy.compositor); > + win.shell_surface = wl_shell_get_shell_surface(dpy.shell, > + win.surface); > + > + wl_shell_surface_add_listener(win.shell_surface, > &shell_surface_listener, &win); > + > + wl_shell_surface_set_toplevel(win.shell_surface); > + > + // wayland drm initialization > + wayland_drm_init(dpy.display); > + if(!wayland_server_support_yuyv) { > + win.format = WL_DRM_FORMAT_XRGB8888; > + } > + > + // create buffer object > + dpy.gbm = gbm_create_device(drm_fd); > + win.gbm_bo = gbm_bo_create(dpy.gbm, win_width, win_height, win.format, > GBM_BO_USE_RENDERING|GBM_BO_USE_WRITE); > + win.bo_pitch = gbm_bo_get_pitch(win.gbm_bo); > + > + unsigned int buf_name = gbm_bo_get_handle2(win.gbm_bo).u32; > + > + // create wl_buffer > + struct wl_buffer *buffer = wl_drm_create_buffer(wl_drm, buf_name, > win_width, win_height, win.bo_pitch, win.format); > + win.buffer = buffer; > + redraw (&win, NULL, 0); > + > + while (running) { > + wl_display_iterate(dpy.display, dpy.mask); > + sleep(0.3); > + } > + > + wayland_drm_finalize(); > + > + gbm_bo_destroy(win.gbm_bo); > + > + wl_shell_surface_destroy(win.shell_surface); > + wl_surface_destroy(win.surface); > + > + if (win.callback) > + wl_callback_destroy(win.callback); > + > + if (dpy.shell) > + wl_shell_destroy(dpy.shell); > + > + if (dpy.compositor) > + wl_compositor_destroy(dpy.compositor); > + > + wl_display_flush(dpy.display); > + wl_display_disconnect(dpy.display); > + > + return 0; > +} > + > diff --git a/tests/Makefile.am b/tests/Makefile.am > old mode 100644 > new mode 100755 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev