Hi Pauli: Thanks for your suggestion. gbm doesn't support: - Buffer name which is used by wayland-drm protocol (since buffer is shared across processes) - tiling (overlay required I915_TILING_X, though intel 3D use TILING_X as default, media pipeline uses TILING_Y as default) - buffer update: intel_image_write() (only cursor image is supported now)
anyway, I will update gbm/intel-driver to fill the above gaps, and make the test case basing on gbm. > -----Original Message----- > From: Pauli Nieminen [mailto:pauli.niemi...@linux.intel.com] > Sent: Monday, June 04, 2012 8:55 PM > To: Zhao, Halley > Cc: mesa-dev@lists.freedesktop.org; Barnes, Jesse > Subject: Re: [Mesa-dev] [PATCH] add test for wayland drm, XRGB/YUYV is > supported > > This test is using intel specific interfaces. Is there something missing from > libgbm that prevents you from using it? > > In any case I think this test should be using gdm for memory management. see > src/gbm/main/gbm.h > > On Mon, Jun 04, 2012 at 09:43:06AM +0000, Zhao, Halley wrote: > > Move the test case to $mesa/test/wayland-drm. > > > > > > From f8843a118e9d7f41b5acedcb396c82adae36841d Mon Sep 17 00:00:00 > 2001 > > From: Zhao halley <halley.z...@intel.com> > > Date: Mon, 4 Jun 2012 15:58:24 +0800 > > Subject: [PATCH] add test for wayland drm, XRGB/YUYV is supported > > > > when I sent patches for YUYV support of dri image, a test case is > > required to make sure the patches can work well. so it is created. > > > > it also shows how wayland-drm protocol works between wayland client > > and server -- they communicate data in buffer/drm level. > > --- > > configure.ac | 4 +- > > src/egl/wayland/Makefile.am | 2 +- > > tests/Makefile.am | 2 +- > > tests/wayland-drm/Makefile.am | 12 + > > tests/wayland-drm/wayland-drm-test.c | 462 > > ++++++++++++++++++++++++++++++++++ > > 5 files changed, 479 insertions(+), 3 deletions(-) create mode > > 100644 tests/wayland-drm/Makefile.am create mode 100644 > > tests/wayland-drm/wayland-drm-test.c > > > > diff --git a/configure.ac b/configure.ac index 3bc59ca..58c05bc 100644 > > --- a/configure.ac > > +++ b/configure.ac > > @@ -2033,7 +2033,9 @@ 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 > > + tests/wayland-drm/Makefile > > + ]) > > > > dnl Replace the configs/current symlink > > AC_CONFIG_COMMANDS([configs],[ diff --git > > a/src/egl/wayland/Makefile.am b/src/egl/wayland/Makefile.am index > > ca7207c..526d64f 100644 > > --- a/src/egl/wayland/Makefile.am > > +++ b/src/egl/wayland/Makefile.am > > @@ -1 +1 @@ > > -SUBDIRS = wayland-drm wayland-egl > > +SUBDIRS = wayland-drm wayland-egl > > diff --git a/tests/Makefile.am b/tests/Makefile.am index > > 4079bb9..f6125f1 100644 > > --- a/tests/Makefile.am > > +++ b/tests/Makefile.am > > @@ -1 +1 @@ > > -SUBDIRS=glx > > +SUBDIRS=glx wayland-drm > > diff --git a/tests/wayland-drm/Makefile.am > > b/tests/wayland-drm/Makefile.am new file mode 100644 index > > 0000000..526acde > > --- /dev/null > > +++ b/tests/wayland-drm/Makefile.am > > @@ -0,0 +1,12 @@ > > +bin_PROGRAMS = wayland_drm_test > > +wayland_drm_test_CFLAGS = -I$(top_srcdir)/src/egl/main \ > > + -I$(top_srcdir)/include \ > > + $(DEFINES) \ > > + $(WAYLAND_CFLAGS) \ > > + $(LIBDRM_CFLAGS) > > + > > +wayland_drm_test_LDADD = $(WAYLAND_LIBS) $(LIBDRM_LIBS) -ldrm_intel > > +wayland_drm_test_LDADD += $(top_srcdir)/src/egl/main/libEGL.la > > + > > +wayland_drm_test_SOURCES = wayland-drm-test.c \ > > + > > +$(top_srcdir)/src/egl/wayland/wayland-drm//wayland-drm-client-protoco > > +l.h > > diff --git a/tests/wayland-drm/wayland-drm-test.c > > b/tests/wayland-drm/wayland-drm-test.c > > new file mode 100644 > > index 0000000..ea2e230 > > --- /dev/null > > +++ b/tests/wayland-drm/wayland-drm-test.c > > @@ -0,0 +1,462 @@ > > +/* > > + * Copyright (c) 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 <unistd.h> > > +#include <errno.h> > > +#include <fcntl.h> > > +#include <sys/stat.h> > > +#include <string.h> > > +#include <assert.h> > > +#include <xf86drm.h> > > +#include <i915_drm.h> > > +#include "libdrm/intel_bufmgr.h" > > +#include <drm.h> > > +#include "gbm.h" > > +#include <wayland-client.h> > > +#include <wayland-client-protocol.h> > > +#include > "../../src/egl/wayland/wayland-drm/wayland-drm-client-protocol.h" > > + > > +void fill_bo_XRGB(dri_bo *bo, int width, int height, int pitch); void > > +fill_bo_YUYV(dri_bo *bo, int width, int height, int pitch); int > > +wayland_drm_init(struct wl_display *wl_dpy); > > + > > +int win_width = 1024, win_height = 512; int drm_fd = -1; 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 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; > > + dri_bo *bo; > > + unsigned int bo_pitch; > > +}; > > + > > +void fill_bo_XRGB(dri_bo *bo, int width, int height, int pitch) { > > + unsigned int tiling, swizzle; > > + dri_bo_get_tiling(bo, &tiling, &swizzle); > > + > > + if (tiling != I915_TILING_NONE) > > + drm_intel_gem_bo_map_gtt(bo); > > + else > > + dri_bo_map(bo, 1); > > + > > + static int color_index = 0; > > + unsigned int color = 0; > > + int i; > > + switch (color_index) { > > + case 0: > > + color = 0xff000000; > > + break; > > + case 1: > > + color = 0x00ff0000; > > + break; > > + case 2: > > + color = 0x0000ff00; > > + break; > > + case 3: > > + color = 0x000000ff; > > + break; > > + default: > > + break; > > + } > > + color_index = (color_index+1) % 4; > > + > > + unsigned int *i_ptr = bo->virtual; > > + for (i=0; i<width; i++) { > > + *i_ptr++ = color; > > + } > > + > > + unsigned char *c_ptr = bo->virtual + pitch; > > + for (i = 1; i<height; i++) { > > + memcpy (c_ptr, bo->virtual, width*4); > > + c_ptr += pitch; > > + } > > + > > + if (tiling != I915_TILING_NONE) > > + drm_intel_gem_bo_unmap_gtt(bo); > > + else > > + dri_bo_unmap(bo); > > +} > > + > > +void fill_bo_YUYV(dri_bo *bo, int width, int height, int pitch) { > > + unsigned int tiling, swizzle; > > + dri_bo_get_tiling(bo, &tiling, &swizzle); > > + > > + if (tiling != I915_TILING_NONE) > > + drm_intel_gem_bo_map_gtt(bo); > > + else > > + dri_bo_map(bo, 1); > > + > > + static int color_index = 0; > > + unsigned int color = 0; > > + int i; > > + switch (color_index) { > > + case 0: > > + color = 0x00ff00ff; > > + break; > > + case 1: > > + color = 0x80ff00ff; > > + break; > > + case 2: > > + color = 0x00ff80ff; > > + break; > > + case 3: > > + color = 0x80ff80ff; > > + break; > > + default: > > + break; > > + } > > + color_index = (color_index+1) % 4; > > + > > + unsigned int *i_ptr = bo->virtual; > > + for (i=0; i<width/2; i++) { > > + *i_ptr++ = color; > > + } > > + > > + unsigned char *c_ptr = bo->virtual + pitch; > > + for (i = 1; i<height; i++) { > > + memcpy (c_ptr, bo->virtual, width*2); > > + c_ptr += pitch; > > + } > > + > > + if (tiling != I915_TILING_NONE) > > + drm_intel_gem_bo_unmap_gtt(bo); > > + else > > + dri_bo_unmap(bo); > > +} > > + > > + > > +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) { > > + > > +} > > + > > +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() > > +{ > > + > > + 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; > > + > > +static void > > +redraw(void *data, struct wl_callback *callback, int time) { > > + struct window *window = data; > > + if (callback) > > + wl_callback_destroy(callback); > > + > > + if (window->format == WL_DRM_FORMAT_XRGB8888) { > > + fill_bo_XRGB(window->bo, win_width, win_height, > window->bo_pitch); > > + } > > + else { > > + fill_bo_YUYV(window->bo, win_width, win_height, > window->bo_pitch); > > + } > > + > > + // 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; > > + } > > + } > > + > > + > > + // 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); > > + > > + // gem buf mgr > > + drm_intel_bufmgr *gem_bufmgr; > > + gem_bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 16 * 4096); > > + drm_intel_bufmgr_gem_enable_reuse(gem_bufmgr); > > + drm_intel_bufmgr_gem_enable_fenced_relocs(gem_bufmgr); > > + > > + // create drm bo > > + dri_bo *bo; > > + int cpp = (win.format == WL_DRM_FORMAT_XRGB8888 ? 4:2); > > + uint32_t tiling_mode = I915_TILING_X; > > + unsigned long alloc_pitch; > > + > > + bo = drm_intel_bo_alloc_tiled(gem_bufmgr, > > + "sprite buffer", > > + win_width, win_height, > > + cpp, > > + &tiling_mode, &alloc_pitch, > > + BO_ALLOC_FOR_RENDER); > > + win.bo = bo; > > + win.bo_pitch = alloc_pitch; > > + > > + unsigned int buf_name; > > + dri_bo_flink(bo, &buf_name); > > + > > + // create wl_buffer > > + struct wl_buffer *buffer = wl_drm_create_buffer(wl_drm, buf_name, > win_width, win_height, alloc_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(); > > + > > + 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); > > + > > +} > > + > > -- > > 1.7.5.4 > > > > > > > -----Original Message----- > > > From: Zhao, Halley > > > Sent: Monday, June 04, 2012 4:31 PM > > > To: Zhao, Halley; mesa-dev@lists.freedesktop.org > > > Cc: e...@anholt.net; Barnes, Jesse > > > Subject: RE: [PATCH] add test for wayland drm, XRGB/YUYV is > > > supported > > > > > > Some "^M" in copyright section, resend it. > > > Thanks. > > > > > > > -----Original Message----- > > > > From: Zhao, Halley > > > > Sent: Monday, June 04, 2012 4:29 PM > > > > To: mesa-dev@lists.freedesktop.org > > > > Cc: e...@anholt.net; Barnes, Jesse; Zhao, Halley > > > > Subject: [PATCH] add test for wayland drm, XRGB/YUYV is supported > > > > > > > > when I sent patches for YUYV support of dri image, a test case is > > > > required to make sure the patches can work well. so it is created. > > > > > > > > it also shows how wayland-drm protocol works between wayland > > > > client and server -- they communicate data in buffer/drm level. > > > > > > > > --- > > > > configure.ac | 1 + > > > > src/egl/wayland/Makefile.am | 2 +- > > > > src/egl/wayland/wayland-drm/Makefile.am | 1 + > > > > src/egl/wayland/wayland-drm/tests/Makefile.am | 12 + > > > > .../wayland/wayland-drm/tests/wayland-drm-test.c | 463 > > > > ++++++++++++++++++++ > > > > 5 files changed, 478 insertions(+), 1 deletions(-) create mode > > > > 100644 src/egl/wayland/wayland-drm/tests/Makefile.am > > > > create mode 100644 src/egl/wayland/wayland-drm/tests/wayland-drm- > > > > test.c > > > > > > > > diff --git a/configure.ac b/configure.ac index 3bc59ca..83bf637 > > > > 100644 > > > > --- a/configure.ac > > > > +++ b/configure.ac > > > > @@ -2019,6 +2019,7 @@ AC_CONFIG_FILES([configs/autoconf > > > > src/egl/wayland/wayland-egl/Makefile > > > > src/egl/wayland/wayland-egl/wayland-egl.pc > > > > src/egl/wayland/wayland-drm/Makefile > > > > + src/egl/wayland/wayland-drm/tests/Makefile > > > > src/glsl/tests/Makefile > > > > src/glx/Makefile > > > > src/mapi/shared-glapi/Makefile > > > > diff --git a/src/egl/wayland/Makefile.am > > > > b/src/egl/wayland/Makefile.am index ca7207c..526d64f 100644 > > > > --- a/src/egl/wayland/Makefile.am > > > > +++ b/src/egl/wayland/Makefile.am > > > > @@ -1 +1 @@ > > > > -SUBDIRS = wayland-drm wayland-egl > > > > +SUBDIRS = wayland-drm wayland-egl > > > > diff --git a/src/egl/wayland/wayland-drm/Makefile.am > > > > b/src/egl/wayland/wayland-drm/Makefile.am > > > > index cf15eda..4a7c6eb 100644 > > > > --- a/src/egl/wayland/wayland-drm/Makefile.am > > > > +++ b/src/egl/wayland/wayland-drm/Makefile.am > > > > @@ -1,3 +1,4 @@ > > > > +SUBDIRS = tests > > > > AM_CFLAGS = -I$(top_srcdir)/src/egl/main \ > > > > -I$(top_srcdir)/include \ > > > > $(DEFINES) \ > > > > diff --git a/src/egl/wayland/wayland-drm/tests/Makefile.am > > > > b/src/egl/wayland/wayland-drm/tests/Makefile.am > > > > new file mode 100644 > > > > index 0000000..d489c74 > > > > --- /dev/null > > > > +++ b/src/egl/wayland/wayland-drm/tests/Makefile.am > > > > @@ -0,0 +1,12 @@ > > > > +bin_PROGRAMS = wayland_drm_test > > > > +wayland_drm_test_CFLAGS = -I$(top_srcdir)/src/egl/main \ > > > > + -I$(top_srcdir)/include \ > > > > + $(DEFINES) \ > > > > + $(WAYLAND_CFLAGS) \ > > > > + $(LIBDRM_CFLAGS) > > > > + > > > > +wayland_drm_test_LDADD = $(WAYLAND_LIBS) $(LIBDRM_LIBS) > > > > +-ldrm_intel wayland_drm_test_LDADD += > > > > +$(top_srcdir)/src/egl/main/libEGL.la > > > > + > > > > +wayland_drm_test_SOURCES = wayland-drm-test.c \ > > > > + > > > > ../wayland-drm-client-protocol.h > > > > diff --git a/src/egl/wayland/wayland-drm/tests/wayland-drm-test.c > > > > b/src/egl/wayland/wayland-drm/tests/wayland-drm-test.c > > > > new file mode 100644 > > > > index 0000000..04c23d4 > > > > --- /dev/null > > > > +++ b/src/egl/wayland/wayland-drm/tests/wayland-drm-test.c > > > > @@ -0,0 +1,463 @@ > > > > +/* > > > > + * Copyright (c) 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 <unistd.h> > > > > +#include <errno.h> > > > > +#include <fcntl.h> > > > > +#include <sys/stat.h> > > > > +#include <string.h> > > > > +#include <assert.h> > > > > +#include <xf86drm.h> > > > > +#include <i915_drm.h> > > > > +#include "libdrm/intel_bufmgr.h" > > > > +#include <drm.h> > > > > +#include "gbm.h" > > > > +#include <wayland-client.h> > > > > +#include <wayland-client-protocol.h> #include > > > > +"../wayland-drm-client-protocol.h" > > > > + > > > > +void fill_bo_XRGB(dri_bo *bo, int width, int height, int pitch); > > > > +void fill_bo_YUYV(dri_bo *bo, int width, int height, int pitch); > > > > +int wayland_drm_init(struct wl_display *wl_dpy); > > > > + > > > > +int win_width = 1024, win_height = 512; int drm_fd = -1; 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 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; > > > > + dri_bo *bo; > > > > + unsigned int bo_pitch; > > > > +}; > > > > + > > > > +void fill_bo_XRGB(dri_bo *bo, int width, int height, int pitch) { > > > > + unsigned int tiling, swizzle; > > > > + dri_bo_get_tiling(bo, &tiling, &swizzle); > > > > + > > > > + if (tiling != I915_TILING_NONE) > > > > + drm_intel_gem_bo_map_gtt(bo); > > > > + else > > > > + dri_bo_map(bo, 1); > > > > + > > > > + static int color_index = 0; > > > > + unsigned int color = 0; > > > > + int i; > > > > + switch (color_index) { > > > > + case 0: > > > > + color = 0xff000000; > > > > + break; > > > > + case 1: > > > > + color = 0x00ff0000; > > > > + break; > > > > + case 2: > > > > + color = 0x0000ff00; > > > > + break; > > > > + case 3: > > > > + color = 0x000000ff; > > > > + break; > > > > + default: > > > > + break; > > > > + } > > > > + color_index = (color_index+1) % 4; > > > > + > > > > + unsigned int *i_ptr = bo->virtual; > > > > + for (i=0; i<width; i++) { > > > > + *i_ptr++ = color; > > > > + } > > > > + > > > > + unsigned char *c_ptr = bo->virtual + pitch; > > > > + for (i = 1; i<height; i++) { > > > > + memcpy (c_ptr, bo->virtual, width*4); > > > > + c_ptr += pitch; > > > > + } > > > > + > > > > + if (tiling != I915_TILING_NONE) > > > > + drm_intel_gem_bo_unmap_gtt(bo); > > > > + else > > > > + dri_bo_unmap(bo); > > > > +} > > > > + > > > > +void fill_bo_YUYV(dri_bo *bo, int width, int height, int pitch) { > > > > + unsigned int tiling, swizzle; > > > > + dri_bo_get_tiling(bo, &tiling, &swizzle); > > > > + > > > > + if (tiling != I915_TILING_NONE) > > > > + drm_intel_gem_bo_map_gtt(bo); > > > > + else > > > > + dri_bo_map(bo, 1); > > > > + > > > > + static int color_index = 0; > > > > + unsigned int color = 0; > > > > + int i; > > > > + switch (color_index) { > > > > + case 0: > > > > + color = 0x00ff00ff; > > > > + break; > > > > + case 1: > > > > + color = 0x80ff00ff; > > > > + break; > > > > + case 2: > > > > + color = 0x00ff80ff; > > > > + break; > > > > + case 3: > > > > + color = 0x80ff80ff; > > > > + break; > > > > + default: > > > > + break; > > > > + } > > > > + color_index = (color_index+1) % 4; > > > > + > > > > + unsigned int *i_ptr = bo->virtual; > > > > + for (i=0; i<width/2; i++) { > > > > + *i_ptr++ = color; > > > > + } > > > > + > > > > + unsigned char *c_ptr = bo->virtual + pitch; > > > > + for (i = 1; i<height; i++) { > > > > + memcpy (c_ptr, bo->virtual, width*2); > > > > + c_ptr += pitch; > > > > + } > > > > + > > > > + if (tiling != I915_TILING_NONE) > > > > + drm_intel_gem_bo_unmap_gtt(bo); > > > > + else > > > > + dri_bo_unmap(bo); > > > > +} > > > > + > > > > + > > > > +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) { > > > > + > > > > +} > > > > + > > > > +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() > > > > +{ > > > > + > > > > + 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; > > > > + > > > > +static void > > > > +redraw(void *data, struct wl_callback *callback, int time) { > > > > + struct window *window = data; > > > > + if (callback) > > > > + wl_callback_destroy(callback); > > > > + > > > > + if (window->format == WL_DRM_FORMAT_XRGB8888) { > > > > + fill_bo_XRGB(window->bo, win_width, win_height, window- > > > > >bo_pitch); > > > > + } > > > > + else { > > > > + fill_bo_YUYV(window->bo, win_width, win_height, window- > > > > >bo_pitch); > > > > + } > > > > + > > > > + // 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) > > > > +{ > > > > + > > > > +PRINT_MARK; > > > > + 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; > > > > + } > > > > + } > > > > + > > > > + > > > > + // 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); > > > > + > > > > + // gem buf mgr > > > > + drm_intel_bufmgr *gem_bufmgr; > > > > + gem_bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 16 * 4096); > > > > + drm_intel_bufmgr_gem_enable_reuse(gem_bufmgr); > > > > + drm_intel_bufmgr_gem_enable_fenced_relocs(gem_bufmgr); > > > > + > > > > + // create drm bo > > > > + dri_bo *bo; > > > > + int cpp = (win.format == WL_DRM_FORMAT_XRGB8888 ? 4:2); > > > > + uint32_t tiling_mode = I915_TILING_X; > > > > + unsigned long alloc_pitch; > > > > + > > > > + bo = drm_intel_bo_alloc_tiled(gem_bufmgr, > > > > + "sprite buffer", > > > > + win_width, win_height, > > > > + cpp, > > > > + &tiling_mode, &alloc_pitch, > > > > + BO_ALLOC_FOR_RENDER); > > > > + win.bo = bo; > > > > + win.bo_pitch = alloc_pitch; > > > > + > > > > + unsigned int buf_name; > > > > + dri_bo_flink(bo, &buf_name); > > > > + > > > > + // create wl_buffer > > > > + struct wl_buffer *buffer = wl_drm_create_buffer(wl_drm, > > > > + buf_name, > > > > win_width, win_height, alloc_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(); > > > > + > > > > + 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); > > > > + > > > > +} > > > > + > > > > -- > > > > 1.7.5.4 > > > > _______________________________________________ > > mesa-dev mailing list > > mesa-dev@lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev