From: Gwenole Beauchesne <gwenole.beauche...@intel.com> --- configure.ac | 32 ++++++- pkgconfig/Makefile.am | 4 + pkgconfig/libva-wayland.pc.in | 13 +++ va/Makefile.am | 13 +++- va/va_backend.h | 13 +++- va/wayland/Makefile.am | 53 ++++++++++ va/wayland/va_backend_wayland.h | 60 +++++++++++ va/wayland/va_wayland.c | 207 ++++++++++++++++++++++++++++++++++++++ va/wayland/va_wayland.h | 148 +++++++++++++++++++++++++++ va/wayland/va_wayland_drm.c | 209 +++++++++++++++++++++++++++++++++++++++ va/wayland/va_wayland_drm.h | 47 +++++++++ va/wayland/va_wayland_private.h | 48 +++++++++ 12 files changed, 844 insertions(+), 3 deletions(-) mode change 100644 => 100755 configure.ac mode change 100644 => 100755 pkgconfig/Makefile.am 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 old mode 100644 new mode 100755 index 4b50912..dcd27fe --- 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@:>@])], @@ -207,6 +212,29 @@ AC_SUBST(EGL_DEPS_CFLAGS) AC_SUBST(EGL_DEPS_LIBS) AM_CONDITIONAL(USE_EGL, test "$USE_EGL" = "yes") +# Check for Wayland +USE_WAYLAND=0 +USE_WAYLAND_DRM=0 +WAYLAND_DRM_CFLAGS="" +WAYLAND_DRM_LIBS="" +if test "$enable_wayland" = "yes"; then + PKG_CHECK_MODULES([WAYLAND], [wayland-client], [USE_WAYLAND=1], []) + if test "$USE_EGL" = "yes"; then + USE_WAYLAND_DRM=1 + WAYLAND_DRM_CFLAGS="$DRM_CFLAGS" + WAYLAND_DRM_LIBS="$DRM_LIBS $EGL_DEPS_LIBS" + fi +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) + +AC_SUBST([WAYLAND_DRM_CFLAGS]) +AC_SUBST([WAYLAND_DRM_LIBS]) +AC_DEFINE_UNQUOTED(USE_WAYLAND_DRM, $USE_WAYLAND_DRM, + [Defined to 1 if building the Wayland windowing system with DRM support]) +AM_CONDITIONAL(USE_WAYLAND_DRM, test $USE_WAYLAND_DRM -eq 1) + # We only need the headers, we don't link against the DRM libraries LIBVA_CFLAGS="$DRM_CFLAGS" AC_SUBST(LIBVA_CFLAGS) @@ -230,6 +258,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 @@ -244,12 +273,13 @@ 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 old mode 100644 new mode 100755 index f595413..3175d3f --- 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 0fdd2e2..bb34ab8 100755 --- a/va/Makefile.am +++ b/va/Makefile.am @@ -110,6 +110,17 @@ 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) $(WAYLAND_DRM_LIBS) +endif + + if BUILD_DUMMY_BACKEND SUBDIRS += dummy lib_LTLIBRARIES += libva-dummy.la @@ -120,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 4f69e24..3f4ada0 100755 --- a/va/va_backend.h +++ b/va/va_backend.h @@ -43,6 +43,7 @@ enum { VA_DISPLAY_X11 = 0x10, VA_DISPLAY_GLX = (VA_DISPLAY_X11 | (1 << 0)), VA_DISPLAY_ANDROID = 0x20, + VA_DISPLAY_WAYLAND = 0x30, }; struct VADriverVTable @@ -467,10 +468,20 @@ struct VADriverContext * This structure is allocated from libva with calloc(). */ struct VADriverVTableVPP *vtable_vpp; + /** \brief VA display type. */ unsigned int 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..a405c21 --- /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) \ + $(WAYLAND_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..a6fb585 --- /dev/null +++ b/va/wayland/va_backend_wayland.h @@ -0,0 +1,60 @@ +/* + * 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 <va/va_drmcommon.h> +#include <wayland-client.h> + +struct VADriverContext; +struct va_wl_surface; + +struct VADriverVTableWayland { + /* Create a surface used for rendering to Wayland */ + VAStatus (*vaCreateSurfaceWL)( + struct VADriverContext *ctx, + struct wl_surface *wl_surface, + struct va_wl_surface **out_va_wl_surface + ); + + /* Destroy a VA/Waland surface */ + VAStatus (*vaDestroySurfaceWL)( + struct VADriverContext *ctx, + struct va_wl_surface *va_wl_surface + ); + + /* Attach a VA surface to a VA/WL surface */ + VAStatus (*vaAttachSurfaceWL)( + struct VADriverContext *ctx, + struct va_wl_surface *va_wl_surface, + VASurfaceID va_surface, + unsigned int flags + ); +}; + +#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..4ebb3e0 --- /dev/null +++ b/va/wayland/va_wayland.c @@ -0,0 +1,207 @@ +/* + * 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; + + 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 +vaCreateSurfaceWL( + VADisplay dpy, + struct wl_surface *surface, + VASurfaceWL *va_wl_surface +) +{ + VADriverContextP const ctx = get_driver_context(dpy); + + if (!ctx) + return VA_STATUS_ERROR_INVALID_DISPLAY; + if (!ctx->vtable_wayland || !ctx->vtable_wayland->vaCreateSurfaceWL) + return VA_STATUS_ERROR_UNIMPLEMENTED; + return ctx->vtable_wayland->vaCreateSurfaceWL(ctx, surface, va_wl_surface); +} + +VAStatus +vaDestroySurfaceWL( + VADisplay dpy, + VASurfaceWL va_wl_surface +) +{ + VADriverContextP const ctx = get_driver_context(dpy); + + if (!ctx) + return VA_STATUS_ERROR_INVALID_DISPLAY; + if (!ctx->vtable_wayland || !ctx->vtable_wayland->vaDestroySurfaceWL) + return VA_STATUS_ERROR_UNIMPLEMENTED; + return ctx->vtable_wayland->vaDestroySurfaceWL(ctx, va_wl_surface); +} + +VAStatus +vaAttachSurfaceWL( + VADisplay dpy, + VASurfaceWL va_wl_surface, + VASurfaceID va_surface, + unsigned int flags +) +{ + VADriverContextP const ctx = get_driver_context(dpy); + + if (!ctx) + return VA_STATUS_ERROR_INVALID_DISPLAY; + if (!ctx->vtable_wayland || !ctx->vtable_wayland->vaAttachSurfaceWL) + return VA_STATUS_ERROR_UNIMPLEMENTED; + return ctx->vtable_wayland->vaAttachSurfaceWL(ctx, va_wl_surface, + va_surface, flags); +} diff --git a/va/wayland/va_wayland.h b/va/wayland/va_wayland.h new file mode 100644 index 0000000..8e0bd31 --- /dev/null +++ b/va/wayland/va_wayland.h @@ -0,0 +1,148 @@ +/* + * 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 ; + * - Create a VA/Wayland surface wrapping a Wayland surface ; + * - Perform normal VA-API operations, e.g. decode to a VA surface ; + * - Attach a VA surface to a VA/Wayland surface whenever necessary ; + * - Dispose the VA/Wayland surface before the child Wayland surface. + */ + +/** \brief An opaque VA/Wayland surface. */ +struct va_wl_surface; +typedef struct va_wl_surface *VASurfaceWL; + +/** + * \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 Creates an opaque surface wrapping the specified Wayland surface. + * + * This functions creates an opaque VA/Wayland surface so that a VA + * driver implementation could perform its housekeeping of objects + * related to the @wl_surface in there. + * + * The application shall destroy this instance with vaDestroySurfaceWL() + * prior to destroying the Wayland surface with wl_surface_destroy(). + * + * Implementation note: it is not recommanded for the VA driver to use + * wl_surface_set_user_data() to hold VA/Wayland specific data in there + * as this data is ultimately dedicated to the client application. + * + * @param[in] dpy the VA display + * @param[in] surface the Wayland surface + * @param[out] va_wl_surface the newly created VA/Wayland surface + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus +vaCreateSurfaceWL( + VADisplay dpy, + struct wl_surface *surface, + VASurfaceWL *va_wl_surface +); + +/** + * \brief Destroys a VA/Wayland surface. + * + * This function is used to destroy VA driver resources associated + * with the underlying Wayland surface. The application shall call + * this function prior to destroying the Wayland surface with + * wl_surface_destroy(). + * + * @param[in] dpy the VA display + * @param[in] va_wl_surface the VA/Wayland surface + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus +vaDestroySurfaceWL( + VADisplay dpy, + VASurfaceWL va_wl_surface +); + +/** + * \brief Attaches a VA surface to a VA/Wayland surface. + * + * This function is used to attach a VA surface to the VA/Wayland + * surface, and thus to the underlying Wayland surface. The @flags are + * used to specify how the VA surface is to be rendered, e.g. either + * field of an interleaved surface. + * + * Implementation note: the VA driver is expected to negotiate a + * suitable surface format with the compositor. + * + * @param[in] dpy the VA display + * @param[in] va_wl_surface the VA/Wayland surface + * @param[in] va_surface the VA surface to attach + * @param[in] flags the rendering flags, e.g. either field + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus +vaAttachSurfaceWL( + VADisplay dpy, + VASurfaceWL va_wl_surface, + VASurfaceID va_surface, + unsigned int flags +); + +/**@}*/ + +#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..feb4a88 --- /dev/null +++ b/va/wayland/va_wayland_drm.c @@ -0,0 +1,209 @@ +/* + * 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 <sys/stat.h> +#include <xf86drm.h> +#include "va_wayland_drm.h" +#include "va_wayland_private.h" +#include "wayland-drm-client-protocol.h" + +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->type = VA_DRI2; +} + +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 (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->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->drm = wl_display_bind(ctx->native_dpy, id, &wl_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..f5fdd2b --- /dev/null +++ b/va/wayland/va_wayland_private.h @@ -0,0 +1,48 @@ +/* + * 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 { + struct wl_drm *drm; + 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.5.4 _______________________________________________ Libva mailing list Libva@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libva