From 05ebaf5f4c69e194a76fe56dd268f888548bc254 Mon Sep 17 00:00:00 2001 From: Gwenole Beauchesne Date: Fri, 6 Apr 2012 17:23:55 +0200 Subject: [PATCH] API: add support for Wayland. Signed-off-by: Gwenole Beauchesne --- configure.ac | 19 ++++ pkgconfig/Makefile.am | 4 + pkgconfig/libva-wayland.pc.in | 12 +++ va/Makefile.am | 12 ++- va/va_backend.h | 13 ++- va/wayland/Makefile.am | 54 +++++++++++ va/wayland/va_backend_wayland.h | 65 +++++++++++++ va/wayland/va_wayland.c | 191 +++++++++++++++++++++++++++++++++++++ va/wayland/va_wayland.h | 131 ++++++++++++++++++++++++++ va/wayland/va_wayland_drm.c | 202 ++++++++++++++++++++++++++++++++++++++++ va/wayland/va_wayland_drm.h | 52 +++++++++++ va/wayland/va_wayland_private.h | 44 +++++++++ 12 files changed, 797 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 1f958a8..4c2c192 100644 --- a/configure.ac +++ b/configure.ac @@ -136,6 +136,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@:>@])], @@ -271,6 +276,17 @@ AC_SUBST(EGL_DEPS_LIBS) AM_CONDITIONAL(USE_EGL, test "$USE_EGL" = "yes") AM_CONDITIONAL(BUILD_EGL_TEST, [test "x$USE_EGL" = "xyes" && test "x$libglesv1_cm" = "xyes"]) +# Check for Wayland +USE_WAYLAND="no" +if test "$enable_wayland" = "yes"; then + PKG_CHECK_MODULES([WAYLAND], [wayland-client], [USE_WAYLAND="yes"], [:]) + if test "$USE_WAYLAND" = "yes"; then + AC_DEFINE([HAVE_VA_WAYLAND], [1], + [Defined to 1 if VA/Wayland API is built]) + fi +fi +AM_CONDITIONAL(USE_WAYLAND, test "$USE_WAYLAND" = "yes") + # We only need the headers, we don't link against the DRM libraries LIBVA_CFLAGS="$DRM_CFLAGS" AC_SUBST(LIBVA_CFLAGS) @@ -303,6 +319,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 @@ -321,6 +338,7 @@ AC_OUTPUT([ va/egl/Makefile va/glx/Makefile va/va_version.h + va/wayland/Makefile va/x11/Makefile ]) @@ -329,6 +347,7 @@ AS_IF([test x$USE_DRM = xyes], [BACKENDS="drm $BACKENDS"]) AS_IF([test x$USE_X11 = xyes], [BACKENDS="x11 $BACKENDS"]) AS_IF([test x$USE_GLX = xyes], [BACKENDS="glx $BACKENDS"]) AS_IF([test x$USE_EGL = xyes], [BACKENDS="egl $BACKENDS"]) +AS_IF([test x$USE_WAYLAND = xyes], [BACKENDS="wayland $BACKENDS"]) echo echo "libva - ${LIBVA_VERSION} (VA-API ${VA_API_VERSION})" diff --git a/pkgconfig/Makefile.am b/pkgconfig/Makefile.am index df5672c..a3435a4 100644 --- a/pkgconfig/Makefile.am +++ b/pkgconfig/Makefile.am @@ -34,6 +34,9 @@ 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 @@ -41,6 +44,7 @@ all_pcfiles_in += libva-drm.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..ee92ac2 --- /dev/null +++ b/pkgconfig/libva-wayland.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ +display=wayland + +Name: libva-${display} +Description: Userspace Video Acceleration (VA) ${display} interface +Requires: libva wayland-client +Version: @VA_API_VERSION@ +Libs: -L${libdir} -lva-${display} +Cflags: -I${includedir} diff --git a/va/Makefile.am b/va/Makefile.am index 8178b9f..bc726ec 100644 --- a/va/Makefile.am +++ b/va/Makefile.am @@ -109,6 +109,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 @@ -119,7 +129,7 @@ libva_dummy_la_LIBADD = $(libvacorelib) dummy/libva_dummy.la \ $(LIBVA_LIBS) $(DRM_LIBS) endif -DIST_SUBDIRS = x11 glx egl dummy drm +DIST_SUBDIRS = x11 glx egl dummy drm wayland DISTCLEANFILES = \ va_version.h \ diff --git a/va/va_backend.h b/va/va_backend.h index b6b651c..a0c408d 100644 --- a/va/va_backend.h +++ b/va/va_backend.h @@ -48,6 +48,8 @@ enum { VA_DISPLAY_ANDROID = 0x20, /** \brief VA/DRM API is used, through vaGetDisplayDRM() entry-point. */ VA_DISPLAY_DRM = 0x30, + /** \brief VA/Wayland API is used, through vaGetDisplayWl() entry-point. */ + VA_DISPLAY_WAYLAND = 0x40, }; struct VADriverVTable @@ -462,7 +464,16 @@ struct VADriverContext /** \brief VA display type. */ unsigned long display_type; - unsigned long reserved[44]; /* 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[43]; /* 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..595fc91 --- /dev/null +++ b/va/wayland/Makefile.am @@ -0,0 +1,54 @@ +# 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 \ + $(top_srcdir)/va/drm/va_drm_utils.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..b33e3a1 --- /dev/null +++ b/va/wayland/va_backend_wayland.h @@ -0,0 +1,65 @@ +/* + * 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 +#include + +/** \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, + unsigned int flags, + struct wl_buffer **out_buffer + ); + + /** \brief Hook to return Wayland buffer associated with the VA image. */ + VAStatus (*vaGetImageBufferWl)( + struct VADriverContext *ctx, + VAImageID image, + unsigned int flags, + 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..22f916f --- /dev/null +++ b/va/wayland/va_wayland.c @@ -0,0 +1,191 @@ +/* + * 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 "sysdeps.h" +#include +#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; + VADisplayContextWaylandP pDisplayContextWl; + + if (!pDisplayContext) + return; + + pDisplayContextWl = pDisplayContext->opaque; + if (pDisplayContextWl && pDisplayContextWl->destroy) + pDisplayContextWl->destroy(pDisplayContext); + + pDriverContext = pDisplayContext->pDriverContext; + if (pDriverContext) { + 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 --- */ +/* -------------------------------------------------------------------------- */ + +struct va_wayland_backend { + VADisplayContextCreateFunc create; + VADisplayContextDestroyFunc destroy; +}; + +static const struct va_wayland_backend g_backends[] = { + { va_wayland_drm_create, + va_wayland_drm_destroy }, + { NULL, } +}; + +VADisplay +vaGetDisplayWl(struct wl_display *display) +{ + VADisplayContextP pDisplayContext = NULL; + VADriverContextP pDriverContext; + 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; + + for (i = 0; g_backends[i].create != NULL; i++) { + if (g_backends[i].create(pDisplayContext)) + break; + g_backends[i].destroy(pDisplayContext); + } + + return (VADisplay)pDisplayContext; + +error: + va_DisplayContextDestroy(pDisplayContext); + return NULL; +} + +VAStatus +vaGetSurfaceBufferWl( + VADisplay dpy, + VASurfaceID surface, + unsigned int flags, + 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, flags, + out_buffer); +} + +VAStatus +vaGetImageBufferWl( + VADisplay dpy, + VAImageID image, + unsigned int flags, + 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, flags, + out_buffer); +} diff --git a/va/wayland/va_wayland.h b/va/wayland/va_wayland.h new file mode 100644 index 0000000..46fbf2c --- /dev/null +++ b/va/wayland/va_wayland.h @@ -0,0 +1,131 @@ +/* + * 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 +#include + +/** + * \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. + * + * The @flags describe the desired picture structure. This is useful + * to expose a de-interlaced buffer. If the VA driver does not support + * any of the supplied flags, then #VA_STATUS_ERROR_FLAG_NOT_SUPPORTED + * is returned. The following flags are allowed: \c VA_FRAME_PICTURE, + * \c VA_TOP_FIELD, \c VA_BOTTOM_FIELD. + * + * @param[in] dpy the VA display + * @param[in] surface the VA surface + * @param[in] flags the deinterlacing flags + * @param[out] out_buffer a wl_buffer wrapping the VA @surface + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus +vaGetSurfaceBufferWl( + VADisplay dpy, + VASurfaceID surface, + unsigned int flags, + 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. + * + * The @flags describe the desired picture structure. See + * vaGetSurfaceBufferWl() description for more details. + * + * @param[in] dpy the VA display + * @param[in] image the VA image + * @param[in] flags the deinterlacing flags + * @param[out] out_buffer a wl_buffer wrapping the VA @image + * @return VA_STATUS_SUCCESS if successful + */ +VAStatus +vaGetImageBufferWl( + VADisplay dpy, + VAImageID image, + unsigned int flags, + 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..30c3953 --- /dev/null +++ b/va/wayland/va_wayland_drm.c @@ -0,0 +1,202 @@ +/* + * 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 "sysdeps.h" +#include +#include +#include +#include +#include +#include +#include "va_drmcommon.h" +#include "drm/va_drm_utils.h" +#include "va_wayland_drm.h" +#include "va_wayland_private.h" +#include "wayland-drm-client-protocol.h" + +/* XXX: Wayland/DRM support currently lives in Mesa libEGL.so.* library */ +#define LIBWAYLAND_DRM_NAME "libEGL.so.1" + +typedef struct va_wayland_drm_context { + struct va_wayland_context base; + void *handle; + struct wl_drm *drm; + void *drm_interface; + unsigned int is_authenticated : 1; +} VADisplayContextWaylandDRM; + +static void +drm_handle_device(void *data, struct wl_drm *drm, const char *device) +{ + VADisplayContextP const pDisplayContext = data; + VADriverContextP const ctx = pDisplayContext->pDriverContext; + VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque; + 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; + VADisplayContextWaylandDRM * const wl_drm_ctx = pDisplayContext->opaque; + struct drm_state * const drm_state = ctx->drm_state; + + wl_drm_ctx->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 +}; + +static VAStatus +va_DisplayContextGetDriverName( + VADisplayContextP pDisplayContext, + char **driver_name_ptr +) +{ + VADriverContextP const ctx = pDisplayContext->pDriverContext; + + return VA_DRM_GetDriverName(ctx, driver_name_ptr); +} + +void +va_wayland_drm_destroy(VADisplayContextP pDisplayContext) +{ + VADriverContextP const ctx = pDisplayContext->pDriverContext; + struct va_wayland_drm_context * const wl_drm_ctx = pDisplayContext->opaque; + 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->handle) { + dlclose(wl_drm_ctx->handle); + wl_drm_ctx->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_create(VADisplayContextP pDisplayContext) +{ + VADriverContextP const ctx = pDisplayContext->pDriverContext; + struct va_wayland_drm_context *wl_drm_ctx; + struct drm_state *drm_state; + uint32_t id; + + wl_drm_ctx = malloc(sizeof(*wl_drm_ctx)); + if (!wl_drm_ctx) + return false; + wl_drm_ctx->base.destroy = va_wayland_drm_destroy; + wl_drm_ctx->handle = NULL; + wl_drm_ctx->drm = NULL; + wl_drm_ctx->drm_interface = NULL; + wl_drm_ctx->is_authenticated = 0; + pDisplayContext->opaque = wl_drm_ctx; + 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->handle = dlopen(LIBWAYLAND_DRM_NAME, RTLD_LAZY|RTLD_LOCAL); + if (!wl_drm_ctx->handle) + return false; + + wl_drm_ctx->drm_interface = + dlsym(wl_drm_ctx->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..6fb8f52 --- /dev/null +++ b/va/wayland/va_wayland_drm.h @@ -0,0 +1,52 @@ +/* + * 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 +#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 + */ +DLL_HIDDEN +bool +va_wayland_drm_create(VADisplayContextP pDisplayContext); + +DLL_HIDDEN +void +va_wayland_drm_destroy(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..f09f4b7 --- /dev/null +++ b/va/wayland/va_wayland_private.h @@ -0,0 +1,44 @@ +/* + * 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 + +struct va_wayland_context; + +typedef bool (*VADisplayContextCreateFunc)(VADisplayContextP pDisplayContext); +typedef void (*VADisplayContextDestroyFunc)(VADisplayContextP pDisplayContext); + +/* VA/Wayland base display context */ +typedef struct va_wayland_context { + VADisplayContextDestroyFunc destroy; +} VADisplayContextWayland, *VADisplayContextWaylandP; + +DLL_HIDDEN +void +va_wayland_error(const char *format, ...); + +#endif /* VA_WAYLAND_PRIVATE_H */ -- 2.7.4