[Libva] [PATCH 09/16] Add PutSurface test for wayland

Zhao Halley halley.zhao at intel.com
Tue Jun 5 02:06:57 PDT 2012


From: Benjamin Franzke <benjaminfranzke at googlemail.com>

---
 configure.ac                         |    1 +
 test/putsurface/Makefile.am          |   27 +++-
 test/putsurface/putsurface_wayland.c |  332 ++++++++++++++++++++++++++++++++++
 3 files changed, 356 insertions(+), 4 deletions(-)
 mode change 100644 => 100755 test/putsurface/Makefile.am
 create mode 100644 test/putsurface/putsurface_wayland.c

diff --git a/configure.ac b/configure.ac
index c58f923..309fc5d 100755
--- a/configure.ac
+++ b/configure.ac
@@ -219,6 +219,7 @@ WAYLAND_DRM_CFLAGS=""
 WAYLAND_DRM_LIBS=""
 if test "$enable_wayland" = "yes"; then
     PKG_CHECK_MODULES([WAYLAND], [wayland-client], [USE_WAYLAND=1], [])
+    PKG_CHECK_MODULES([WAYLAND_SERVER], [wayland-server], [], [])
         USE_WAYLAND_DRM=1
         WAYLAND_DRM_CFLAGS="$DRM_CFLAGS"
 	WAYLAND_DRM_LIBS="$DRM_LIBS $EGL_DEPS_LIBS"
diff --git a/test/putsurface/Makefile.am b/test/putsurface/Makefile.am
old mode 100644
new mode 100755
index fbf23d3..9cf843c
--- a/test/putsurface/Makefile.am
+++ b/test/putsurface/Makefile.am
@@ -22,12 +22,31 @@
 
 bin_PROGRAMS = putsurface
 
-INCLUDES = -I$(top_srcdir)
+INCLUDES = \
+	-I$(top_srcdir)		\
+	-I$(top_builddir)	\
+	$(NULL)
 
-TEST_LIBS = $(top_builddir)/va/$(libvabackendlib) $(top_builddir)/va/$(libvacorelib) -lpthread -lX11
+TEST_LIBS = \
+	$(top_builddir)/va/$(libvacorelib)	\
+	-lpthread				\
+	$(NULL)
 
-putsurface_LDADD = $(TEST_LIBS)
-putsurface_SOURCES = putsurface_x11.c
+putsurface_SOURCES		= putsurface_x11.c
+putsurface_CFLAGS		= $(X11_CFLAGS)
+putsurface_LDADD		= $(X11_LIBS) $(TEST_LIBS)	\
+	$(top_builddir)/va/$(libvabackendlib)			\
+	$(NULL)
+
+if USE_WAYLAND
+bin_PROGRAMS			+= putsurface_wayland
+putsurface_wayland_SOURCES	= putsurface_wayland.c
+putsurface_wayland_CFLAGS	= $(WAYLAND_CFLAGS)
+putsurface_wayland_LDADD	= $(WAYLAND_LIBS) $(TEST_LIBS)	\
+	$(WAYLAND_SERVER_LIBS)					\
+	$(top_builddir)/va/libva-wayland.la			\
+	$(NULL)
+endif
 
 EXTRA_DIST = putsurface_common.c
 
diff --git a/test/putsurface/putsurface_wayland.c b/test/putsurface/putsurface_wayland.c
new file mode 100644
index 0000000..aeb8d40
--- /dev/null
+++ b/test/putsurface/putsurface_wayland.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
+ *
+ * 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, sub license, 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 NON-INFRINGEMENT.
+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+ */
+
+#include <stddef.h>
+#include <errno.h>
+#include <sys/select.h>
+#include <va/va_wayland.h>
+#include <wayland-server.h>
+
+static void *open_display(void);
+static void close_display(void *win_display);
+static int create_window(void *win_display,
+             int x, int y, int width, int height);
+static int check_window_event(void *win_display, void *drawable,
+                  int *width, int *height, int *quit);
+
+struct display;
+struct drawable;
+
+static VAStatus
+va_put_surface(
+    VADisplay           dpy,
+    struct drawable    *wl_drawable,
+    VASurfaceID         va_surface,
+    const VARectangle  *src_rect,
+    const VARectangle  *dst_rect,
+    const VARectangle  *cliprects,
+    unsigned int        num_cliprects,
+    unsigned int        flags
+);
+
+/* Glue code for the current PutSurface test design */
+#define CAST_DRAWABLE(a)  (struct drawable *)(a)
+
+static inline VADisplay
+vaGetDisplay(NativeDisplay native_dpy)
+{
+    return vaGetDisplayWL(native_dpy);
+}
+
+static VAStatus
+vaPutSurface(
+    VADisplay           dpy,
+    VASurfaceID         surface,
+    struct drawable    *wl_drawable,
+    short               src_x,
+    short               src_y,
+    unsigned short      src_w,
+    unsigned short      src_h,
+    short               dst_x,
+    short               dst_y,
+    unsigned short      dst_w,
+    unsigned short      dst_h,
+    const VARectangle  *cliprects,
+    unsigned int        num_cliprects,
+    unsigned int        flags
+)
+{
+    VARectangle src_rect, dst_rect;
+
+    src_rect.x      = src_x;
+    src_rect.y      = src_y;
+    src_rect.width  = src_w;
+    src_rect.height = src_h;
+
+    dst_rect.x      = src_x;
+    dst_rect.y      = src_y;
+    dst_rect.width  = src_w;
+    dst_rect.height = src_h;
+    return va_put_surface(dpy, wl_drawable, surface, &src_rect, &dst_rect,
+                          cliprects, num_cliprects, flags);
+}
+
+#include "putsurface_common.c"
+
+struct display {
+    struct wl_display  *display;
+    struct wl_compositor *compositor;
+    struct wl_shell    *shell;
+    uint32_t            mask;
+    int                 event_fd;
+};
+
+struct drawable {
+    struct wl_display  *display;
+    struct wl_surface  *surface;
+    VASurfaceWL         va_wl_surface;
+    unsigned int        redraw_pending  : 1;
+};
+
+static void
+frame_redraw_callback(void *data, struct wl_callback *callback, uint32_t time)
+{
+    struct drawable * const drawable = data;
+
+    drawable->redraw_pending = 0;
+    wl_callback_destroy(callback);
+}
+
+static const struct wl_callback_listener frame_callback_listener = {
+    frame_redraw_callback
+};
+
+static VAStatus
+va_put_surface(
+    VADisplay           dpy,
+    struct drawable    *wl_drawable,
+    VASurfaceID         va_surface,
+    const VARectangle  *src_rect,
+    const VARectangle  *dst_rect,
+    const VARectangle  *cliprects,
+    unsigned int        num_cliprects,
+    unsigned int        flags
+)
+{
+    struct display *d;
+    struct wl_callback *callback;
+    VAStatus va_status;
+
+    if (!wl_drawable)
+        return VA_STATUS_ERROR_INVALID_SURFACE;
+
+    if (!wl_drawable->va_wl_surface) {
+        va_status = vaCreateSurfaceWL(
+            dpy,
+            wl_drawable->surface,
+            &wl_drawable->va_wl_surface
+        );
+        if (va_status != VA_STATUS_SUCCESS) {
+            fprintf(stderr, "error: failed to create VA/WL surface\n");
+            return va_status;
+        }
+    }
+
+    d = wl_display_get_user_data(wl_drawable->display);
+    if (!d)
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+
+    /* Wait for the previous frame to complete redraw */
+    if (wl_drawable->redraw_pending) {
+        wl_display_flush(d->display);
+        while (wl_drawable->redraw_pending)
+            wl_display_iterate(wl_drawable->display, WL_DISPLAY_READABLE);
+    }
+
+    va_status = vaAttachSurfaceWL(
+        dpy,
+        wl_drawable->va_wl_surface,
+        va_surface,
+        flags
+    );
+    if (va_status != VA_STATUS_SUCCESS)
+        return va_status;
+
+    wl_display_flush(d->display);
+    wl_drawable->redraw_pending = 1;
+    callback = wl_surface_frame(wl_drawable->surface);
+    wl_callback_add_listener(callback, &frame_callback_listener, wl_drawable);
+    return VA_STATUS_SUCCESS;
+}
+
+static void
+display_handle_global(
+    struct wl_display *display,
+    uint32_t           id,
+    const char        *interface,
+    uint32_t           version,
+    void              *data
+)
+{
+    struct display * const 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);
+}
+
+static int
+event_mask_update(uint32_t mask, void *data)
+{
+    struct display * const d = data;
+
+    d->mask = mask;
+    return 0;
+}
+
+static void *
+open_display(void)
+{
+    struct display *d;
+
+    d = calloc(1, sizeof *d);
+    if (!d)
+        return NULL;
+
+    d->display = wl_display_connect(NULL);
+    if (!d->display)
+        return NULL;
+
+    wl_display_set_user_data(d->display, d);
+    wl_display_add_global_listener(d->display, display_handle_global, d);
+    d->event_fd = wl_display_get_fd(d->display, event_mask_update, d);
+    wl_display_iterate(d->display, d->mask);
+    return d->display;
+}
+
+static void
+close_display(void *win_display)
+{
+    struct display * const d = wl_display_get_user_data(win_display);
+
+    free(d);
+    wl_display_destroy(win_display);
+}
+
+static int
+create_window(void *win_display, int x, int y, int width, int height)
+{
+    struct wl_display * const display = win_display;
+    struct display * const d = wl_display_get_user_data(display);
+    struct wl_surface *surface1, *surface2;
+    struct wl_shell_surface *shell_surface;
+    struct wl_shell_surface *shell_surface_2;
+    struct drawable *drawable1, *drawable2;
+
+    surface1 = wl_compositor_create_surface(d->compositor);
+    shell_surface = wl_shell_get_shell_surface(d->shell, surface1);
+    wl_shell_surface_set_toplevel(shell_surface);
+
+    drawable1 = malloc(sizeof(*drawable1));
+    drawable1->display          = display;
+    drawable1->surface          = surface1;
+    drawable1->va_wl_surface    = NULL;
+    drawable1->redraw_pending   = 0;
+
+    /* global out */
+    drawable_thread0 = drawable1;
+
+    if (multi_thread == 0)
+        return 0;
+
+    surface2 = wl_compositor_create_surface(d->compositor);
+    shell_surface_2 = wl_shell_get_shell_surface(d->shell, surface2);
+    wl_shell_surface_set_toplevel(shell_surface_2);
+
+    drawable2 = malloc(sizeof(*drawable2));
+    drawable2->display          = display;
+    drawable1->surface          = surface2;
+    drawable2->va_wl_surface    = NULL;
+    drawable2->redraw_pending   = 0;
+
+    /* global out */
+    drawable_thread1 = drawable2;
+    return 0;
+}
+
+static int
+check_window_event(
+    void *win_display,
+    void *drawable,
+    int  *width,
+    int  *height,
+    int  *quit
+)
+{
+    struct wl_display * const display = win_display;
+    struct display * const d = wl_display_get_user_data(display);
+    struct timeval tv;
+    fd_set rfds;
+    int retval;
+
+    if (check_event == 0)
+        return 0;
+
+    if (!(d->mask & WL_DISPLAY_READABLE))
+        return 0;
+
+    tv.tv_sec  = 0;
+    tv.tv_usec = 0;
+    do {
+        FD_ZERO(&rfds);
+        FD_SET(d->event_fd, &rfds);
+
+        retval = select(d->event_fd + 1, &rfds, NULL, NULL, &tv);
+        if (retval < 0) {
+            perror("select");
+            break;
+        }
+        if (retval == 1)
+            wl_display_iterate(d->display, WL_DISPLAY_READABLE);
+    } while (retval > 0);
+
+#if 0
+    /* bail on any focused key press */
+    if(event.type == KeyPress) {  
+        *quit = 1;
+        return 0;
+    }
+#endif
+
+#if 0
+    /* rescale the video to fit the window */
+    if(event.type == ConfigureNotify) { 
+        *width = event.xconfigure.width;
+        *height = event.xconfigure.height;
+        printf("Scale window to %dx%d\n", width, height);
+    }
+#endif
+    return 0;
+}
-- 
1.7.5.4



More information about the Libva mailing list