[Mesa-dev] [PATCH] add test for wayland drm, XRGB/YUYV is supported

Zhao, Halley halley.zhao at intel.com
Tue Jun 5 10:05:37 CEST 2012


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.nieminen at linux.intel.com]
> Sent: Monday, June 04, 2012 8:55 PM
> To: Zhao, Halley
> Cc: mesa-dev at 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.zhao at 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.zhao at 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 at lists.freedesktop.org
> > > Cc: eric at 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 at lists.freedesktop.org
> > > > Cc: eric at 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.zhao at 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 at lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list