Add Wayland support.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Sat, 7 Apr 2012 18:08:03 +0000 (20:08 +0200)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Wed, 26 Sep 2012 13:43:47 +0000 (15:43 +0200)
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
configure.ac
src/Makefile.am
src/i965_drv_video.c
src/i965_drv_video.h
src/i965_output_wayland.c [new file with mode: 0644]
src/i965_output_wayland.h [new file with mode: 0644]

index 6bd5d90..e7f0f53 100644 (file)
@@ -51,6 +51,11 @@ AC_ARG_ENABLE(x11,
                     [build with VA/X11 API support @<:@default=yes@:>@])],
     [], [enable_x11="yes"])
 
+AC_ARG_ENABLE([wayland],
+    [AC_HELP_STRING([--enable-wayland],
+                    [build with VA/Wayland API support @<:@default=yes@:>@])],
+    [], [enable_wayland="yes"])
+
 AC_DISABLE_STATIC
 AC_PROG_LIBTOOL
 AC_PROG_CC
@@ -125,6 +130,43 @@ fi
 AC_MSG_RESULT([$LIBVA_DRIVERS_PATH])
 AC_SUBST(LIBVA_DRIVERS_PATH)
 
+# Check for EGL
+if test "$enable_wayland" = "yes"; then
+    enable_egl="yes"
+fi
+
+USE_EGL="no"
+if test "$enable_egl" = "yes"; then
+    PKG_CHECK_MODULES([EGL], [egl], [USE_EGL="yes"], [USE_EGL="no"])
+    saved_CPPFLAGS="$CPPFLAGS"
+    saved_LIBS="$LIBS"
+    CPPFLAGS="$CPPFLAGS $EGL_CFLAGS"
+    LIBS="$LIBS $EGL_LIBS"
+    AC_CHECK_HEADERS([EGL/egl.h], [:], [USE_EGL="no"])
+    AC_CHECK_LIB([EGL], [eglGetDisplay], [:], [USE_EGL="no"])
+    CPPFLAGS="$saved_CPPFLAGS"
+    LIBS="$saved_LIBS"
+fi
+AM_CONDITIONAL(USE_EGL, test "$USE_EGL" = "yes")
+
+# Check for Wayland
+USE_WAYLAND="no"
+WAYLAND_DRM_CFLAGS=""
+WAYLAND_DRM_LIBS=""
+if test "$enable_wayland" = "yes"; then
+    PKG_CHECK_MODULES([WAYLAND], [wayland-client], [USE_WAYLAND="yes"], [:])
+    PKG_CHECK_MODULES([LIBVA_WAYLAND_DEPS], [libva-wayland],
+        [AC_DEFINE([HAVE_VA_WAYLAND], [1], [Defined to 1 if VA/Wayland API is enabled])],
+        [USE_WAYLAND="no"])
+    if test "$USE_EGL" = "yes"; then
+        WAYLAND_DRM_CFLAGS="$DRM_CFLAGS"
+        WAYLAND_DRM_LIBS="$DRM_LIBS $EGL_LIBS"
+    fi
+fi
+AM_CONDITIONAL(USE_WAYLAND, test "$USE_WAYLAND" = "yes")
+AC_SUBST([WAYLAND_DRM_CFLAGS])
+AC_SUBST([WAYLAND_DRM_LIBS])
+
 AC_OUTPUT([
     Makefile
     debian.upstream/Makefile 
@@ -144,6 +186,7 @@ dnl Print summary
 BACKENDS=""
 AS_IF([test "$USE_DRM" = "yes"], [BACKENDS="$BACKENDS drm"])
 AS_IF([test "$USE_X11" = "yes"], [BACKENDS="$BACKENDS x11"])
+AS_IF([test "$USE_WAYLAND" = "yes"], [BACKENDS="$BACKENDS wayland"])
 
 echo
 echo $PACKAGE configuration summary:
index 4029ae9..68ec5d3 100644 (file)
@@ -111,5 +111,12 @@ source_c                   += i965_output_dri.c
 source_h                       += i965_output_dri.h
 endif
 
+if USE_WAYLAND
+source_c                       += i965_output_wayland.c
+source_h                       += i965_output_wayland.h
+driver_cflags                  += $(WAYLAND_CFLAGS) $(WAYLAND_DRM_CFLAGS)
+driver_libs                    += $(WAYLAND_LIBS) $(WAYLAND_DRM_LIBS)
+endif
+
 # Extra clean files so that maintainer-clean removes *everything*
 MAINTAINERCLEANFILES = Makefile.in config.h.in
index 72d8fc0..ad9c890 100644 (file)
 # include "i965_output_dri.h"
 #endif
 
+#ifdef HAVE_VA_WAYLAND
+# include "i965_output_wayland.h"
+#endif
+
 #include "intel_driver.h"
 #include "intel_memman.h"
 #include "intel_batchbuffer.h"
@@ -87,6 +91,10 @@ static int get_sampling_from_fourcc(unsigned int fourcc);
 #define IS_VA_X11(ctx) \
     (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_X11)
 
+/* Check whether we are rendering to Wayland */
+#define IS_VA_WAYLAND(ctx) \
+    (((ctx)->display_type & VA_DISPLAY_MAJOR_MASK) == VA_DISPLAY_WAYLAND)
+
 enum {
     I965_SURFACETYPE_RGBA = 1,
     I965_SURFACETYPE_YUV,
@@ -1705,6 +1713,11 @@ i965_Init(VADriverContextP ctx)
     if (i965_render_init(ctx) == False)
         return VA_STATUS_ERROR_UNKNOWN;
 
+#ifdef HAVE_VA_WAYLAND
+    if (IS_VA_WAYLAND(ctx) && !i965_output_wayland_init(ctx))
+        return VA_STATUS_ERROR_UNKNOWN;
+#endif
+
 #ifdef HAVE_VA_X11
     if (IS_VA_X11(ctx) && !i965_output_dri_init(ctx))
         return VA_STATUS_ERROR_UNKNOWN;
@@ -2432,6 +2445,11 @@ i965_Terminate(VADriverContextP ctx)
         i965_output_dri_terminate(ctx);
 #endif
 
+#ifdef HAVE_VA_WAYLAND
+    if (IS_VA_WAYLAND(ctx))
+        i965_output_wayland_terminate(ctx);
+#endif
+
     if (i965_render_terminate(ctx) == False)
         return VA_STATUS_ERROR_UNKNOWN;
 
index 2cf86cd..6b22dcd 100644 (file)
@@ -238,6 +238,9 @@ struct i965_driver_data
 
     /* VA/DRI (X11) specific data */
     struct va_dri_output *dri_output;
+
+    /* VA/Wayland specific data */
+    struct va_wl_output *wl_output;
 };
 
 #define NEW_CONFIG_ID() object_heap_allocate(&i965->config_heap);
diff --git a/src/i965_output_wayland.c b/src/i965_output_wayland.c
new file mode 100644 (file)
index 0000000..02485cf
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <va/va_backend.h>
+#include <va/va_backend_wayland.h>
+#include <wayland-client.h>
+#include <wayland-drm-client-protocol.h>
+#include "intel_driver.h"
+#include "i965_output_wayland.h"
+#include "i965_drv_video.h"
+#include "i965_defines.h"
+
+struct va_wl_output {
+    struct wl_drm      *wl_drm;
+};
+
+/* Ensure wl_drm instance is created */
+static bool
+ensure_wl_output(VADriverContextP ctx)
+{
+    struct i965_driver_data * const i965 = i965_driver_data(ctx);
+    struct va_wl_output * const wl_output = i965->wl_output;
+    uint32_t id;
+
+    if (wl_output->wl_drm)
+        return true;
+
+    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_output->wl_drm = wl_display_bind(ctx->native_dpy, id, &wl_drm_interface);
+    if (!wl_output->wl_drm)
+        return false;
+    return true;
+}
+
+/* Hook to return Wayland buffer associated with the VA surface */
+static VAStatus
+va_GetSurfaceBufferWl(
+    struct VADriverContext *ctx,
+    VASurfaceID             surface,
+    unsigned int            flags,
+    struct wl_buffer      **out_buffer
+)
+{
+    struct i965_driver_data * const i965 = i965_driver_data(ctx);
+    struct object_surface *obj_surface;
+    struct wl_buffer *buffer;
+    uint32_t name, drm_format;
+    int offsets[3], pitches[3];
+
+    obj_surface = SURFACE(surface);
+    if (!obj_surface)
+        return VA_STATUS_ERROR_INVALID_SURFACE;
+
+    if (flags != VA_FRAME_PICTURE)
+        return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
+
+    if (!out_buffer)
+        return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+    if (!ensure_wl_output(ctx))
+        return VA_STATUS_ERROR_INVALID_DISPLAY;
+
+    if (drm_intel_bo_flink(obj_surface->bo, &name) != 0)
+        return VA_STATUS_ERROR_INVALID_SURFACE;
+
+    switch (obj_surface->fourcc) {
+    case VA_FOURCC('N','V','1','2'):
+        drm_format = WL_DRM_FORMAT_NV12;
+        offsets[0] = 0;
+        pitches[0] = obj_surface->width;
+        offsets[1] = obj_surface->width * obj_surface->y_cb_offset;
+        pitches[1] = obj_surface->cb_cr_pitch;
+        offsets[2] = 0;
+        pitches[2] = 0;
+        break;
+    case VA_FOURCC('Y','V','1','2'):
+    case VA_FOURCC('I','4','2','0'):
+    case VA_FOURCC('I','M','C','1'):
+        switch (obj_surface->subsampling) {
+        case SUBSAMPLE_YUV411:
+            drm_format = WL_DRM_FORMAT_YUV411;
+            break;
+        case SUBSAMPLE_YUV420:
+            drm_format = WL_DRM_FORMAT_YUV420;
+            break;
+        case SUBSAMPLE_YUV422H:
+        case SUBSAMPLE_YUV422V:
+            drm_format = WL_DRM_FORMAT_YUV422;
+            break;
+        case SUBSAMPLE_YUV444:
+            drm_format = WL_DRM_FORMAT_YUV444;
+            break;
+        default:
+            assert(0 && "unsupported subsampling");
+            return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
+        }
+        offsets[0] = 0;
+        pitches[0] = obj_surface->width;
+        offsets[1] = obj_surface->width * obj_surface->y_cb_offset;
+        pitches[1] = obj_surface->cb_cr_pitch;
+        offsets[2] = obj_surface->width * obj_surface->y_cr_offset;
+        pitches[2] = obj_surface->cb_cr_pitch;
+        break;
+    default:
+        assert(0 && "unsupported format");
+        return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
+    }
+
+    buffer = wl_drm_create_planar_buffer(
+        i965->wl_output->wl_drm,
+        name,
+        obj_surface->orig_width,
+        obj_surface->orig_height,
+        drm_format,
+        offsets[0], pitches[0],
+        offsets[1], pitches[1],
+        offsets[2], pitches[2]
+    );
+    if (!buffer)
+        return VA_STATUS_ERROR_ALLOCATION_FAILED;
+
+    *out_buffer = buffer;
+    return VA_STATUS_SUCCESS;
+}
+
+/* Hook to return Wayland buffer associated with the VA image */
+static VAStatus
+va_GetImageBufferWl(
+    struct VADriverContext *ctx,
+    VAImageID               image,
+    unsigned int            flags,
+    struct wl_buffer      **out_buffer
+)
+{
+    return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+bool
+i965_output_wayland_init(VADriverContextP ctx)
+{
+    struct i965_driver_data * const i965 = i965_driver_data(ctx);
+    struct VADriverVTableWayland *vtable;
+
+    if (ctx->display_type != VA_DISPLAY_WAYLAND)
+        return false;
+
+    i965->wl_output = calloc(1, sizeof(struct va_wl_output));
+    if (!i965->wl_output)
+        return false;
+
+    vtable = ctx->vtable_wayland;
+    if (!vtable)
+        return false;
+
+    vtable->vaGetSurfaceBufferWl        = va_GetSurfaceBufferWl;
+    vtable->vaGetImageBufferWl          = va_GetImageBufferWl;
+    return true;
+}
+
+void
+i965_output_wayland_terminate(VADriverContextP ctx)
+{
+    struct i965_driver_data * const i965 = i965_driver_data(ctx);
+    struct va_wl_output *wl_output;
+
+    if (ctx->display_type != VA_DISPLAY_WAYLAND)
+        return;
+
+    wl_output = i965->wl_output;
+    if (!wl_output)
+        return;
+
+    if (wl_output->wl_drm) {
+        wl_drm_destroy(wl_output->wl_drm);
+        wl_output->wl_drm = NULL;
+    }
+    free(wl_output);
+    i965->wl_output = NULL;
+}
diff --git a/src/i965_output_wayland.h b/src/i965_output_wayland.h
new file mode 100644 (file)
index 0000000..61ca39f
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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.
+ */
+
+#ifndef I965_OUTPUT_WAYLAND_H
+#define I965_OUTPUT_WAYLAND_H
+
+#include <stdbool.h>
+
+bool
+i965_output_wayland_init(VADriverContextP ctx);
+
+void
+i965_output_wayland_terminate(VADriverContextP ctx);
+
+#endif /* I965_OUTPUT_WAYLAND_H */