[Libva] [PATCH 1/4] API: add support for Wayland.

Gwenole Beauchesne gb.devel at gmail.com
Fri Jul 13 07:02:40 PDT 2012


Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
---
 configure.ac                    |   17 +++
 pkgconfig/Makefile.am           |    4 +
 pkgconfig/libva-wayland.pc.in   |   13 +++
 va/Makefile.am                  |   12 +-
 va/va_backend.h                 |   13 ++-
 va/wayland/Makefile.am          |   53 +++++++++
 va/wayland/va_backend_wayland.h |   63 +++++++++++
 va/wayland/va_wayland.c         |  192 ++++++++++++++++++++++++++++++++
 va/wayland/va_wayland.h         |  118 ++++++++++++++++++++
 va/wayland/va_wayland_drm.c     |  229 +++++++++++++++++++++++++++++++++++++++
 va/wayland/va_wayland_drm.h     |   47 ++++++++
 va/wayland/va_wayland_private.h |   51 +++++++++
 12 files changed, 810 insertions(+), 2 deletions(-)
 create mode 100644 pkgconfig/libva-wayland.pc.in
 create mode 100644 va/wayland/Makefile.am
 create mode 100644 va/wayland/va_backend_wayland.h
 create mode 100644 va/wayland/va_wayland.c
 create mode 100644 va/wayland/va_wayland.h
 create mode 100644 va/wayland/va_wayland_drm.c
 create mode 100644 va/wayland/va_wayland_drm.h
 create mode 100644 va/wayland/va_wayland_private.h

diff --git a/configure.ac b/configure.ac
index a706c35..6d38368 100644
--- a/configure.ac
+++ b/configure.ac
@@ -126,6 +126,11 @@ AC_ARG_ENABLE(egl,
                     [build with EGL support @<:@default=yes@:>@])],
     [], [enable_egl="yes"])
 
+AC_ARG_ENABLE([wayland],
+    [AC_HELP_STRING([--enable-wayland],
+                    [build with Wayland support @<:@default=yes@:>@])],
+    [], [enable_wayland="yes"])
+
 AC_ARG_ENABLE(dummy-driver,
     [AC_HELP_STRING([--enable-dummy-driver],
                     [build dummy video driver @<:@default=yes@:>@])],
@@ -220,6 +225,15 @@ AC_SUBST(EGL_DEPS_CFLAGS)
 AC_SUBST(EGL_DEPS_LIBS)
 AM_CONDITIONAL(USE_EGL, test "$USE_EGL" = "yes")
 
+# Check for Wayland
+USE_WAYLAND=0
+if test "$enable_wayland" = "yes"; then
+    PKG_CHECK_MODULES([WAYLAND], [wayland-client], [USE_WAYLAND=1], [])
+fi
+AC_DEFINE_UNQUOTED(USE_WAYLAND, $USE_WAYLAND,
+    [Defined to 1 if building the Wayland windowing system])
+AM_CONDITIONAL(USE_WAYLAND, test $USE_WAYLAND -eq 1)
+
 # We only need the headers, we don't link against the DRM libraries
 LIBVA_CFLAGS="$DRM_CFLAGS"
 AC_SUBST(LIBVA_CFLAGS)
@@ -243,6 +257,7 @@ AC_OUTPUT([
     pkgconfig/libva-egl.pc
     pkgconfig/libva-glx.pc
     pkgconfig/libva-tpi.pc
+    pkgconfig/libva-wayland.pc
     pkgconfig/libva-x11.pc
     pkgconfig/libva.pc
     test/Makefile
@@ -258,12 +273,14 @@ AC_OUTPUT([
     va/egl/Makefile
     va/glx/Makefile
     va/va_version.h
+    va/wayland/Makefile
     va/x11/Makefile
 ])
 
 # Print a small summary
 AS_IF([test x$USE_GLX = xyes], [BACKENDS="glx $BACKENDS"])
 AS_IF([test x$USE_EGL = xyes], [BACKENDS="egl $BACKENDS"])
+AS_IF([test $USE_WAYLAND -eq 1], [BACKENDS="wayland $BACKENDS"])
 
 echo
 echo "libva - ${LIBVA_VERSION} (VA-API ${VA_API_VERSION})"
diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am
index f595413..3175d3f 100644
--- a/pkgconfig/Makefile.am
+++ b/pkgconfig/Makefile.am
@@ -29,12 +29,16 @@ endif
 if USE_EGL
 pcfiles		+= libva-egl.pc
 endif
+if USE_WAYLAND
+pcfiles		+= libva-wayland.pc
+endif
 
 all_pcfiles_in	 = libva.pc.in
 all_pcfiles_in	+= libva-tpi.pc.in
 all_pcfiles_in	+= libva-x11.pc.in
 all_pcfiles_in	+= libva-glx.pc.in
 all_pcfiles_in	+= libva-egl.pc.in
+all_pcfiles_in	+= libva-wayland.pc.in
 
 pkgconfigdir = @pkgconfigdir@
 pkgconfig_DATA = $(pcfiles)
diff --git a/pkgconfig/libva-wayland.pc.in b/pkgconfig/libva-wayland.pc.in
new file mode 100644
index 0000000..d818313
--- /dev/null
+++ b/pkgconfig/libva-wayland.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+extra_libs=@WAYLAND_DRM_LIBS@
+display=wayland
+
+Name: libva-${display}
+Description: Userspace Video Acceleration (VA) ${display} interface
+Requires: libva
+Version: @VA_API_VERSION@
+Libs: -L${libdir} -lva-${display} ${extra_libs}
+Cflags: -I${includedir}
diff --git a/va/Makefile.am b/va/Makefile.am
index 47b7ba6..fb9961f 100644
--- a/va/Makefile.am
+++ b/va/Makefile.am
@@ -111,6 +111,16 @@ libva_egl_la_LIBADD		= $(libvacorelib) egl/libva_egl.la libva-x11.la \
 	$(GL_DEPS_LIBS) -ldl
 endif
 
+if USE_WAYLAND
+SUBDIRS				+= wayland
+lib_LTLIBRARIES			+= libva-wayland.la
+libva_wayland_la_SOURCES	=
+libva_wayland_la_LDFLAGS	= $(LDADD)
+libva_wayland_la_DEPENDENCIES	= $(libvacorelib) wayland/libva_wayland.la
+libva_wayland_la_LIBADD		= $(libvacorelib) wayland/libva_wayland.la \
+	$(WAYLAND_LIBS) $(DRM_LIBS) -ldl
+endif
+
 if BUILD_DUMMY_BACKEND
 SUBDIRS				+= dummy
 lib_LTLIBRARIES			+= libva-dummy.la
@@ -121,7 +131,7 @@ libva_dummy_la_LIBADD		= $(libvacorelib) dummy/libva_dummy.la \
 	$(LIBVA_LIBS) $(DRM_LIBS)
 endif
 
-DIST_SUBDIRS = x11 glx egl dummy
+DIST_SUBDIRS = x11 glx egl dummy wayland
 
 DISTCLEANFILES = \
 	va_version.h		\
diff --git a/va/va_backend.h b/va/va_backend.h
index 14d1657..22085cb 100644
--- a/va/va_backend.h
+++ b/va/va_backend.h
@@ -49,6 +49,8 @@ enum {
     VA_DISPLAY_GLX      = (VA_DISPLAY_X11 | (1 << 0)),
     /** \brief VA/Android API is used, through vaGetDisplay() entry-point */
     VA_DISPLAY_ANDROID  = 0x20,
+    /** \brief VA/Wayland API is used, through vaGetDisplayWl() entry-point. */
+    VA_DISPLAY_WAYLAND  = 0x30,
 };
 
 struct VADriverVTable
@@ -477,7 +479,16 @@ struct VADriverContext
     /** \brief VA display type. */
     unsigned long display_type;
 
-    unsigned long reserved[43];         /* reserve for future add-ins, decrease the subscript accordingly */
+    /**
+     * The VA/Wayland implementation hooks.
+     *
+     * This structure is intended for drivers that implement the
+     * VA/Wayland API. libVA allocates this structure with calloc()
+     * and owns the resulting memory.
+     */
+    struct VADriverVTableWayland *vtable_wayland;
+
+    unsigned long reserved[42];         /* reserve for future add-ins, decrease the subscript accordingly */
 };
 
 #define VA_DISPLAY_MAGIC 0x56414430 /* VAD0 */
diff --git a/va/wayland/Makefile.am b/va/wayland/Makefile.am
new file mode 100644
index 0000000..0746787
--- /dev/null
+++ b/va/wayland/Makefile.am
@@ -0,0 +1,53 @@
+# Copyright (C) 2012 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.
+
+INCLUDES = \
+	-DLINUX			\
+	-I$(top_srcdir)		\
+	-I$(top_srcdir)/va	\
+	$(WAYLAND_CFLAGS)	\
+	$(DRM_CFLAGS)		\
+	$(NULL)
+
+source_c = \
+	va_wayland.c		\
+	va_wayland_drm.c	\
+	$(NULL)
+
+source_h = \
+	va_backend_wayland.h	\
+	va_wayland.h		\
+	$(NULL)
+
+source_h_priv = \
+	va_wayland_drm.h	\
+	va_wayland_private.h	\
+	$(NULL)
+
+noinst_LTLIBRARIES		= libva_wayland.la
+libva_waylandincludedir		= ${includedir}/va
+libva_waylandinclude_HEADERS	= $(source_h)
+libva_wayland_la_SOURCES	= $(source_c)
+noinst_HEADERS			= $(source_h_priv)
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/va/wayland/va_backend_wayland.h b/va/wayland/va_backend_wayland.h
new file mode 100644
index 0000000..dfa43eb
--- /dev/null
+++ b/va/wayland/va_backend_wayland.h
@@ -0,0 +1,63 @@
+/*
+ * va_backend_wayland.h - VA driver implementation hooks for Wayland
+ *
+ * Copyright (c) 2012 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 INTEL 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.
+ */
+
+#ifndef VA_BACKEND_WAYLAND_H
+#define VA_BACKEND_WAYLAND_H
+
+#include <va/va.h>
+#include <wayland-client.h>
+
+/** \brief VA/Wayland API version. */
+#define VA_WAYLAND_API_VERSION  (0x574c4400) /* WLD0 */
+
+/* Forward declarations */
+struct VADriverContext;
+
+/** \brief VA/Wayland implementation hooks. */
+struct VADriverVTableWayland {
+    /**
+     * \brief Interface version.
+     *
+     * Implementations shall set this field to \ref VA_WAYLAND_API_VERSION.
+     */
+    unsigned int version;
+
+    /** \brief Hook to return Wayland buffer associated with the VA surface. */
+    VAStatus (*vaGetSurfaceBufferWl)(
+        struct VADriverContext *ctx,
+        VASurfaceID             surface,
+        struct wl_buffer      **out_buffer
+    );
+
+    /** \brief Hook to return Wayland buffer associated with the VA image. */
+    VAStatus (*vaGetImageBufferWl)(
+        struct VADriverContext *ctx,
+        VAImageID               image,
+        struct wl_buffer      **out_buffer
+    );
+};
+
+#endif /* VA_BACKEND_WAYLAND_H */
diff --git a/va/wayland/va_wayland.c b/va/wayland/va_wayland.c
new file mode 100644
index 0000000..cfd2ec1
--- /dev/null
+++ b/va/wayland/va_wayland.c
@@ -0,0 +1,192 @@
+/*
+ * va_wayland.c - Wayland API
+ *
+ * Copyright (c) 2012 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 INTEL 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 <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "va_wayland.h"
+#include "va_wayland_drm.h"
+#include "va_wayland_private.h"
+#include "va_backend.h"
+#include "va_backend_wayland.h"
+
+static inline VADriverContextP
+get_driver_context(VADisplay dpy)
+{
+    if (!vaDisplayIsValid(dpy))
+        return NULL;
+    return ((VADisplayContextP)dpy)->pDriverContext;
+}
+
+void
+va_wayland_error(const char *format, ...)
+{
+    va_list args;
+
+    va_start(args, format);
+    fprintf(stderr, "VA error: wayland: ");
+    vfprintf(stderr, format, args);
+    fprintf(stderr, "\n");
+    va_end(args);
+}
+
+static int
+va_DisplayContextIsValid(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP const pDriverContext = pDisplayContext->pDriverContext;
+
+    return (pDriverContext &&
+            pDriverContext->display_type == VA_DISPLAY_WAYLAND);
+}
+
+static void
+va_DisplayContextDestroy(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP pDriverContext;
+
+    if (!pDisplayContext)
+        return;
+
+    pDriverContext = pDisplayContext->pDriverContext;
+    if (pDriverContext) {
+        VADisplayContextWaylandP const pDisplayContextWl =
+            pDisplayContext->opaque;
+        if (pDisplayContextWl && pDisplayContextWl->finalize)
+            pDisplayContextWl->finalize(pDisplayContext);
+        free(pDriverContext->vtable_wayland);
+        pDriverContext->vtable_wayland = NULL;
+        free(pDriverContext);
+        pDisplayContext->pDriverContext = NULL;
+    }
+    free(pDisplayContext->opaque);
+    pDisplayContext->opaque = NULL;
+    free(pDisplayContext);
+}
+
+static VAStatus
+va_DisplayContextGetDriverName(VADisplayContextP pDisplayContext, char **name)
+{
+    *name = NULL;
+    return VA_STATUS_ERROR_UNKNOWN;
+}
+
+/* -------------------------------------------------------------------------- */
+/* --- Public interface                                                   --- */
+/* -------------------------------------------------------------------------- */
+
+static const VADisplayContextInitFunc g_display_context_init_funcs[] = {
+    va_wayland_drm_init,
+    NULL
+};
+
+VADisplay
+vaGetDisplayWl(struct wl_display *display)
+{
+    VADisplayContextP pDisplayContext = NULL;
+    VADisplayContextWaylandP pDisplayContextWl;
+    VADriverContextP pDriverContext;
+    VADisplayContextInitFunc init_backend;
+    struct VADriverVTableWayland *vtable;
+    unsigned int i;
+
+    pDisplayContext = calloc(1, sizeof(*pDisplayContext));
+    if (!pDisplayContext)
+        return NULL;
+
+    pDisplayContext->vadpy_magic        = VA_DISPLAY_MAGIC;
+    pDisplayContext->vaIsValid          = va_DisplayContextIsValid;
+    pDisplayContext->vaDestroy          = va_DisplayContextDestroy;
+    pDisplayContext->vaGetDriverName    = va_DisplayContextGetDriverName;
+
+    pDriverContext = calloc(1, sizeof(*pDriverContext));
+    if (!pDriverContext)
+        goto error;
+    pDisplayContext->pDriverContext     = pDriverContext;
+
+    pDriverContext->native_dpy          = display;
+    pDriverContext->display_type        = VA_DISPLAY_WAYLAND;
+
+    vtable = calloc(1, sizeof(*vtable));
+    if (!vtable)
+        goto error;
+    pDriverContext->vtable_wayland      = vtable;
+
+    vtable->version                     = VA_WAYLAND_API_VERSION;
+
+    pDisplayContextWl = calloc(1, sizeof(*pDisplayContextWl));
+    if (!pDisplayContextWl)
+        goto error;
+    pDisplayContext->opaque = pDisplayContextWl;
+
+    init_backend = NULL;
+    for (i = 0; g_display_context_init_funcs[i] != NULL; i++) {
+        init_backend = g_display_context_init_funcs[i];
+        if (init_backend(pDisplayContext))
+            break;
+        if (pDisplayContextWl->finalize)
+            pDisplayContextWl->finalize(pDisplayContext);
+        init_backend = NULL;
+    }
+    if (!init_backend)
+        goto error;
+    return (VADisplay)pDisplayContext;
+
+error:
+    va_DisplayContextDestroy(pDisplayContext);
+    return NULL;
+}
+
+VAStatus
+vaGetSurfaceBufferWl(
+    VADisplay           dpy,
+    VASurfaceID         surface,
+    struct wl_buffer  **out_buffer
+)
+{
+    VADriverContextP const ctx = get_driver_context(dpy);
+
+    if (!ctx)
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+    if (!ctx->vtable_wayland || !ctx->vtable_wayland->vaGetSurfaceBufferWl)
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+    return ctx->vtable_wayland->vaGetSurfaceBufferWl(ctx, surface, out_buffer);
+}
+
+VAStatus
+vaGetImageBufferWl(
+    VADisplay           dpy,
+    VAImageID           image,
+    struct wl_buffer  **out_buffer
+)
+{
+    VADriverContextP const ctx = get_driver_context(dpy);
+
+    if (!ctx)
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+    if (!ctx->vtable_wayland || !ctx->vtable_wayland->vaGetImageBufferWl)
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+    return ctx->vtable_wayland->vaGetImageBufferWl(ctx, image, out_buffer);
+}
diff --git a/va/wayland/va_wayland.h b/va/wayland/va_wayland.h
new file mode 100644
index 0000000..009f2d1
--- /dev/null
+++ b/va/wayland/va_wayland.h
@@ -0,0 +1,118 @@
+/*
+ * va_wayland.h - Wayland API
+ *
+ * Copyright (c) 2012 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 INTEL 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.
+ */
+
+#ifndef VA_WAYLAND_H
+#define VA_WAYLAND_H
+
+#include <va/va.h>
+#include <wayland-client.h>
+
+/**
+ * \file va_wayland.h
+ * \brief The Wayland rendering API
+ *
+ * This file contains the \ref api_wayland "Wayland rendering API".
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup api_wayland Wayland rendering API
+ *
+ * @{
+ *
+ * Theory of operations:
+ * - Create a VA display for an active Wayland display ;
+ * - Perform normal VA-API operations, e.g. decode to a VA surface ;
+ * - Get wl_buffer associated to the VA surface ;
+ * - Attach wl_buffer to wl_surface ;
+ */
+
+/**
+ * \brief Returns a VA display wrapping the specified Wayland display.
+ *
+ * This functions returns a (possibly cached) VA display from the
+ * specified Wayland @display.
+ *
+ * @param[in]   display         the native Wayland display
+ * @return the VA display
+ */
+VADisplay
+vaGetDisplayWl(struct wl_display *display);
+
+/**
+ * \brief Returns the Wayland buffer associated with a VA surface.
+ *
+ * This function returns a wl_buffer handle that can be used as an
+ * argument to wl_surface_attach(). This buffer references the
+ * underlying VA @surface. As such, the VA @surface and Wayland
+ * @out_buffer have the same size and color format. Should specific
+ * color conversion be needed, then VA/VPP API can fulfill this
+ * purpose.
+ *
+ * @param[in]   dpy         the VA display
+ * @param[in]   surface     the VA surface
+ * @param[out]  out_buffer  a wl_buffer wrapping the VA @surface
+ * @return VA_STATUS_SUCCESS if successful
+ */
+VAStatus
+vaGetSurfaceBufferWl(
+    VADisplay           dpy,
+    VASurfaceID         surface,
+    struct wl_buffer  **out_buffer
+);
+
+/**
+ * \brief Returns the Wayland buffer associated with a VA image.
+ *
+ * This function returns a wl_buffer handle that can be used as an
+ * argument to wl_surface_attach(). This buffer references the
+ * underlying VA @image. As such, the VA @image and Wayland
+ * @out_buffer have the same size and color format. Should specific
+ * color conversion be needed, then VA/VPP API can fulfill this
+ * purpose.
+ *
+ * @param[in]   dpy         the VA display
+ * @param[in]   image       the VA image
+ * @param[out]  out_buffer  a wl_buffer wrapping the VA @image
+ * @return VA_STATUS_SUCCESS if successful
+ */
+VAStatus
+vaGetImageBufferWl(
+    VADisplay           dpy,
+    VAImageID           image,
+    struct wl_buffer  **out_buffer
+);
+
+/**@}*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VA_WAYLAND_H */
diff --git a/va/wayland/va_wayland_drm.c b/va/wayland/va_wayland_drm.c
new file mode 100644
index 0000000..3a97083
--- /dev/null
+++ b/va/wayland/va_wayland_drm.c
@@ -0,0 +1,229 @@
+/*
+ * va_wayland_drm.c - Wayland/DRM helpers
+ *
+ * Copyright (c) 2012 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 INTEL 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 <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#include <sys/stat.h>
+#include <xf86drm.h>
+#include "va_drmcommon.h"
+#include "va_wayland_drm.h"
+#include "va_wayland_private.h"
+#include "wayland-drm-client-protocol.h"
+
+/* XXX: wayland-drm currently lives in libEGL.so.* library */
+#define LIBEGL_NAME "libEGL.so.1"
+
+static void
+drm_handle_device(void *data, struct wl_drm *drm, const char *device)
+{
+    VADisplayContextP const pDisplayContext = data;
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    VADisplayContextWaylandP const wl_ctx = pDisplayContext->opaque;
+    VADisplayContextWaylandDRM * const wl_drm_ctx = &wl_ctx->backend.drm;
+    struct drm_state * const drm_state = ctx->drm_state;
+    drm_magic_t magic;
+    struct stat st;
+
+    if (stat(device, &st) < 0) {
+        va_wayland_error("failed to identify %s: %s (errno %d)",
+                         device, strerror(errno), errno);
+        return;
+    }
+
+    if (!S_ISCHR(st.st_mode)) {
+        va_wayland_error("%s is not a device", device);
+        return;
+    }
+
+    drm_state->fd = open(device, O_RDWR);
+    if (drm_state->fd < 0) {
+        va_wayland_error("failed to open %s: %s (errno %d)",
+                         device, strerror(errno), errno);
+        return;
+    }
+
+    drmGetMagic(drm_state->fd, &magic);
+    wl_drm_authenticate(wl_drm_ctx->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)
+{
+    VADisplayContextP const pDisplayContext = data;
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    VADisplayContextWaylandP const wl_ctx = pDisplayContext->opaque;
+    struct drm_state * const drm_state = ctx->drm_state;
+
+    wl_ctx->backend.drm.is_authenticated = 1;
+    drm_state->auth_type                 = VA_DRM_AUTH_CUSTOM;
+}
+
+static const struct wl_drm_listener drm_listener = {
+    drm_handle_device,
+    drm_handle_format,
+    drm_handle_authenticated
+};
+
+struct driver_name_map {
+    const char *key;
+    int key_len;
+    const char *name;
+};
+
+static const struct driver_name_map g_driver_name_map[] = {
+    { "i915",       4, "i965"  }, // Intel OTC GenX driver
+    { "pvrsrvkm",   8, "pvr"   }, // Intel UMG PVR driver
+    { "emgd",       4, "emgd"  }, // Intel ECG PVR driver
+    { NULL, }
+};
+
+static VAStatus
+va_DisplayContextGetDriverName(
+    VADisplayContextP pDisplayContext,
+    char            **driver_name_ptr
+)
+{
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    struct drm_state * const drm_state = ctx->drm_state;
+    drmVersionPtr drm_version;
+    char *driver_name = NULL;
+    const struct driver_name_map *m;
+
+    *driver_name_ptr = NULL;
+
+    drm_version = drmGetVersion(drm_state->fd);
+    if (!drm_version)
+        return VA_STATUS_ERROR_UNKNOWN;
+
+    for (m = g_driver_name_map; m->key != NULL; m++) {
+        if (drm_version->name_len >= m->key_len &&
+            strncmp(drm_version->name, m->key, m->key_len) == 0)
+            break;
+    }
+    drmFreeVersion(drm_version);
+
+    if (!m->name)
+        return VA_STATUS_ERROR_UNKNOWN;
+
+    driver_name = strdup(m->name);
+    if (!driver_name)
+        return VA_STATUS_ERROR_ALLOCATION_FAILED;
+
+    *driver_name_ptr = driver_name;
+    return VA_STATUS_SUCCESS;
+}
+
+static void
+va_wayland_drm_finalize(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    VADisplayContextWaylandP const wl_ctx = pDisplayContext->opaque;
+    VADisplayContextWaylandDRM * const wl_drm_ctx = &wl_ctx->backend.drm;
+    struct drm_state * const drm_state = ctx->drm_state;
+
+    if (wl_drm_ctx->drm) {
+        wl_drm_destroy(wl_drm_ctx->drm);
+        wl_drm_ctx->drm = NULL;
+    }
+    wl_drm_ctx->is_authenticated = 0;
+
+    if (wl_drm_ctx->libEGL_handle) {
+        dlclose(wl_drm_ctx->libEGL_handle);
+        wl_drm_ctx->libEGL_handle = NULL;
+    }
+
+    if (drm_state) {
+        if (drm_state->fd >= 0) {
+            close(drm_state->fd);
+            drm_state->fd = -1;
+        }
+        free(ctx->drm_state);
+        ctx->drm_state = NULL;
+    }
+}
+
+bool
+va_wayland_drm_init(VADisplayContextP pDisplayContext)
+{
+    VADriverContextP const ctx = pDisplayContext->pDriverContext;
+    VADisplayContextWaylandP const wl_ctx = pDisplayContext->opaque;
+    VADisplayContextWaylandDRM * const wl_drm_ctx = &wl_ctx->backend.drm;
+    struct drm_state *drm_state;
+    uint32_t id;
+
+    wl_drm_ctx->drm                     = NULL;
+    wl_drm_ctx->is_authenticated        = 0;
+    wl_ctx->finalize                    = va_wayland_drm_finalize;
+    pDisplayContext->vaGetDriverName    = va_DisplayContextGetDriverName;
+
+    drm_state = calloc(1, sizeof(struct drm_state));
+    if (!drm_state)
+        return false;
+    drm_state->fd        = -1;
+    drm_state->auth_type = 0;
+    ctx->drm_state       = drm_state;
+
+    id = wl_display_get_global(ctx->native_dpy, "wl_drm", 1);
+    if (!id) {
+        wl_display_roundtrip(ctx->native_dpy);
+        id = wl_display_get_global(ctx->native_dpy, "wl_drm", 1);
+        if (!id)
+            return false;
+    }
+
+    wl_drm_ctx->libEGL_handle = dlopen(LIBEGL_NAME, RTLD_LAZY|RTLD_LOCAL);
+    if (!wl_drm_ctx->libEGL_handle)
+        return false;
+
+    wl_drm_ctx->drm_interface =
+        dlsym(wl_drm_ctx->libEGL_handle, "wl_drm_interface");
+    if (!wl_drm_ctx->drm_interface)
+        return false;
+
+    wl_drm_ctx->drm =
+        wl_display_bind(ctx->native_dpy, id, wl_drm_ctx->drm_interface);
+    if (!wl_drm_ctx->drm)
+        return false;
+
+    wl_drm_add_listener(wl_drm_ctx->drm, &drm_listener, pDisplayContext);
+    wl_display_roundtrip(ctx->native_dpy);
+    if (drm_state->fd < 0)
+        return false;
+
+    wl_display_roundtrip(ctx->native_dpy);
+    if (!wl_drm_ctx->is_authenticated)
+        return false;
+    return true;
+}
diff --git a/va/wayland/va_wayland_drm.h b/va/wayland/va_wayland_drm.h
new file mode 100644
index 0000000..01b89f4
--- /dev/null
+++ b/va/wayland/va_wayland_drm.h
@@ -0,0 +1,47 @@
+/*
+ * va_wayland_drm.h - Wayland/DRM helpers
+ *
+ * Copyright (c) 2012 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 INTEL 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.
+ */
+
+#ifndef VA_WAYLAND_DRM_H
+#define VA_WAYLAND_DRM_H
+
+#include <stdbool.h>
+#include "va_wayland.h"
+#include "va_backend.h"
+#include "va_backend_wayland.h"
+
+/**
+ * \brief Initializes Wayland/DRM layer.
+ *
+ * This is an internal function used to initialize the VA/DRM subsystem
+ * if the application is running on a DRM-based server.
+ *
+ * @param[in]   pDisplayContext the VA display context
+ * @return true if successful
+ */
+bool
+va_wayland_drm_init(VADisplayContextP pDisplayContext);
+
+#endif /* VA_WAYLAND_DRM_H */
diff --git a/va/wayland/va_wayland_private.h b/va/wayland/va_wayland_private.h
new file mode 100644
index 0000000..0c3bfec
--- /dev/null
+++ b/va/wayland/va_wayland_private.h
@@ -0,0 +1,51 @@
+/*
+ * va_wayland_private.h - Wayland private API
+ *
+ * Copyright (c) 2012 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 INTEL 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.
+ */
+
+#ifndef VA_WAYLAND_PRIVATE_H
+#define VA_WAYLAND_PRIVATE_H
+
+typedef bool (*VADisplayContextInitFunc)(VADisplayContextP pDisplayContext);
+typedef void (*VADisplayContextFinalizeFunc)(VADisplayContextP pDisplayContext);
+
+typedef struct _VADisplayContextWaylandDRM {
+    /* XXX: wayland-drm lives in libEGL.so.* for now */
+    void                               *libEGL_handle;
+    struct wl_drm                      *drm;
+    void                               *drm_interface;
+    unsigned int                        is_authenticated        : 1;
+} VADisplayContextWaylandDRM;
+
+typedef struct _VADisplayContextWayland {
+    union {
+        VADisplayContextWaylandDRM      drm;
+    } backend;
+    VADisplayContextFinalizeFunc        finalize;
+} VADisplayContextWayland, *VADisplayContextWaylandP;
+
+void
+va_wayland_error(const char *format, ...);
+
+#endif /* VA_WAYLAND_PRIVATE_H */
-- 
1.7.9.5



More information about the Libva mailing list