[Libva] [Driver PATCH 2/5] add wayland support
Zhao Halley
halley.zhao at intel.com
Tue Jun 5 02:12:09 PDT 2012
From: Gwenole Beauchesne <gwenole.beauchesne at intel.com>
---
configure.ac | 56 +++++++
src/Makefile.am | 7 +
src/i965_drv_video.c | 7 +
src/i965_render_wayland.c | 372 +++++++++++++++++++++++++++++++++++++++++++++
src/i965_render_wayland.h | 33 ++++
5 files changed, 475 insertions(+), 0 deletions(-)
mode change 100644 => 100755 configure.ac
create mode 100755 src/i965_render_wayland.c
create mode 100755 src/i965_render_wayland.h
diff --git a/configure.ac b/configure.ac
old mode 100644
new mode 100755
index 5717ce2..8805ffd
--- a/configure.ac
+++ b/configure.ac
@@ -41,6 +41,11 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [
AC_SUBST(AM_DEFAULT_VERBOSITY)
])
+AC_ARG_ENABLE([wayland],
+ [AC_HELP_STRING([--enable-wayland],
+ [build with Wayland support @<:@default=yes@:>@])],
+ [], [enable_wayland="yes"])
+
AC_DISABLE_STATIC
AC_PROG_LIBTOOL
AC_PROG_CC
@@ -90,6 +95,53 @@ 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"
+EGL_CFLAGS=""
+EGL_LIBS=""
+if test "$enable_egl" = "yes"; then
+ saved_CFLAGS="$CFLAGS"
+ saved_LIBS="$LIBS"
+ PKG_CHECK_MODULES([EGL], [egl], [], [EGL_LIBS="-lEGL"])
+ CFLAGS="$CFLAGS $EGL_CFLAGS"
+ LIBS="$LIBS $EGL_LIBS"
+ AC_CHECK_HEADERS([EGL/egl.h])
+ AC_CHECK_LIB(EGL, eglGetDisplay, [USE_EGL="yes"])
+ CFLAGS="$saved_CFLAGS"
+ LIBS="$saved_LIBS"
+fi
+AC_SUBST(EGL_CFLAGS)
+AC_SUBST(EGL_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_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)
+
+
AC_OUTPUT([
Makefile
debian.upstream/Makefile
@@ -109,9 +161,13 @@ AC_OUTPUT([
])
dnl Print summary
+WINSYS=""
+AS_IF([test $USE_WAYLAND -eq 1], [WINSYS="wayland $WINSYS"])
+
echo
echo $PACKAGE configuration summary:
echo
echo VA-API version ................... : $VA_VERSION_STR
echo VA-API drivers path .............. : $LIBVA_DRIVERS_PATH
+echo Windowing systems ................ : $WINSYS
echo
diff --git a/src/Makefile.am b/src/Makefile.am
index bb0b033..fc9a12b 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -102,6 +102,13 @@ source_h = \
object_heap.h \
$(NULL)
+if USE_WAYLAND
+source_c += i965_render_wayland.c
+source_h += i965_render_wayland.h
+driver_cflags += $(WAYLAND_CFLAGS) $(WAYLAND_DRM_CFLAGS)
+driver_libs += $(WAYLAND_LIBS) $(WAYLAND_DRM_LIBS)
+endif
+
i965_drv_video_la_LTLIBRARIES = i965_drv_video.la
i965_drv_video_ladir = $(LIBVA_DRIVERS_PATH)
i965_drv_video_la_CFLAGS = $(driver_cflags)
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index 81b0738..79f96f3 100755
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -44,6 +44,9 @@
#include "i965_defines.h"
#include "i965_drv_video.h"
+#if USE_WAYLAND
+# include "i965_render_wayland.h"
+#endif
#define CONFIG_ID_OFFSET 0x01000000
#define CONTEXT_ID_OFFSET 0x02000000
#define SURFACE_ID_OFFSET 0x04000000
@@ -1910,6 +1913,10 @@ i965_Init(VADriverContextP ctx)
if (intel_driver_init(ctx) == False)
return VA_STATUS_ERROR_UNKNOWN;
+#if USE_WAYLAND
+ if (!i965_render_wayland_init(ctx))
+ return VA_STATUS_ERROR_UNKNOWN;
+#endif
if (IS_G4X(i965->intel.device_id))
i965->codec_info = &g4x_hw_codec_info;
diff --git a/src/i965_render_wayland.c b/src/i965_render_wayland.c
new file mode 100755
index 0000000..26d7ba0
--- /dev/null
+++ b/src/i965_render_wayland.c
@@ -0,0 +1,372 @@
+/*
+ * 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_render_wayland.h"
+#include "i965_drv_video.h"
+
+#define VA_WL_FORMAT_RGBA (WL_DRM_FORMAT_XRGB8888)
+
+struct va_wl_surface {
+ struct wl_drm *wl_drm;
+ struct wl_surface *wl_surface;
+ struct wl_buffer *wl_buffer;
+ struct intel_region region;
+ unsigned int name;
+ unsigned int format;
+ unsigned int width;
+ unsigned int height;
+};
+
+static void
+va_surface_reset_buffer(
+ VADriverContextP ctx,
+ struct va_wl_surface *va_wl_surface
+)
+{
+ struct intel_region * const region = &va_wl_surface->region;
+
+ if (va_wl_surface->wl_buffer) {
+#if 0
+ /* XXX: automatically destroyed on next wl_surface_attach()? */
+ wl_buffer_destroy(va_wl_surface->wl_buffer);
+#endif
+ va_wl_surface->wl_buffer = NULL;
+ }
+
+ if (region->bo) {
+ dri_bo_unreference(region->bo);
+ region->bo = NULL;
+ }
+
+ va_wl_surface->name = 0;
+ va_wl_surface->format = 0;
+ va_wl_surface->width = 0;
+ va_wl_surface->height = 0;
+ memset(region, 0, sizeof(*region));
+}
+
+static VAStatus
+va_wayland_create_surface(
+ VADriverContextP ctx,
+ struct wl_surface *wl_surface,
+ struct va_wl_surface **out_va_wl_surface
+)
+{
+ struct va_wl_surface *va_wl_surface;
+ uint32_t id;
+
+ if (ctx->display_type != VA_DISPLAY_WAYLAND)
+ return VA_STATUS_ERROR_INVALID_DISPLAY;
+ if (!wl_surface)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+ if (!out_va_wl_surface)
+ return VA_STATUS_ERROR_INVALID_PARAMETER;
+
+ va_wl_surface = calloc(1, sizeof(*va_wl_surface));
+ if (!va_wl_surface)
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+
+ 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 VA_STATUS_ERROR_INVALID_DISPLAY;
+ }
+
+ va_wl_surface->wl_drm =
+ wl_display_bind(ctx->native_dpy, id, &wl_drm_interface);
+ if (!va_wl_surface->wl_drm)
+ return VA_STATUS_ERROR_INVALID_DISPLAY;
+
+ va_wl_surface->wl_surface = wl_surface;
+ va_wl_surface->wl_buffer = NULL;
+ va_wl_surface->format = 0;
+ va_wl_surface->width = 0;
+ va_wl_surface->height = 0;
+
+ *out_va_wl_surface = va_wl_surface;
+ return VA_STATUS_SUCCESS;
+}
+
+static VAStatus
+va_wayland_destroy_surface(
+ VADriverContextP ctx,
+ struct va_wl_surface *va_wl_surface
+)
+{
+ if (ctx->display_type != VA_DISPLAY_WAYLAND)
+ return VA_STATUS_ERROR_INVALID_DISPLAY;
+ if (!va_wl_surface)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ va_surface_reset_buffer(ctx, va_wl_surface);
+
+ if (va_wl_surface->wl_drm) {
+ wl_drm_destroy(va_wl_surface->wl_drm);
+ va_wl_surface->wl_drm = NULL;
+ }
+
+ free(va_wl_surface);
+ return VA_STATUS_SUCCESS;
+}
+
+static VAStatus
+va_surface_relink_buffer(
+ VADriverContextP ctx,
+ struct va_wl_surface *va_wl_surface
+)
+{
+ struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ struct i965_render_state * const render_state = &i965->render_state;
+ struct intel_region *region = render_state->draw_region;
+ uint32_t name;
+
+ if (region) {
+ if (!region->bo || dri_bo_flink(region->bo, &name) != 0)
+ return VA_STATUS_ERROR_INVALID_BUFFER;
+
+ if (name != va_wl_surface->name) {
+ dri_bo_unreference(region->bo);
+ region->bo = NULL;
+ }
+ }
+ else {
+ region = calloc(1, sizeof(*region));
+ if (!region)
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ render_state->draw_region = region;
+ }
+
+ if (!region->bo) {
+ *region = va_wl_surface->region;
+
+ region->bo = intel_bo_gem_create_from_name(
+ i965->intel.bufmgr,
+ "render buffer",
+ va_wl_surface->name
+ );
+ assert(region->bo);
+ if (!region->bo)
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+ return VA_STATUS_SUCCESS;
+}
+
+static bool
+va_surface_create_buffer_rgb(
+ VADriverContextP ctx,
+ struct va_wl_surface *va_wl_surface,
+ struct object_surface *obj_surface
+)
+{
+ struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ struct intel_region * const region = &va_wl_surface->region;
+
+ region->x = 0;
+ region->y = 0;
+ region->width = ALIGN(obj_surface->orig_width, 16);
+ region->height = ALIGN(obj_surface->orig_height, 16);
+ region->cpp = 4;
+ region->pitch = ALIGN(region->cpp * region->width, 64);
+
+ region->bo = drm_intel_bo_alloc_for_render(
+ i965->intel.bufmgr,
+ "render buffer",
+ region->pitch * region->height,
+ 0
+ );
+ if (!region->bo)
+ return false;
+
+ dri_bo_get_tiling(region->bo, ®ion->tiling, ®ion->swizzle);
+ if (dri_bo_flink(region->bo, &va_wl_surface->name) != 0) {
+ fprintf(stderr, "libva: error: flink failed for bo %p\n", region->bo);
+ return false;
+ }
+
+ va_wl_surface->format = VA_WL_FORMAT_RGBA;
+ va_wl_surface->width = obj_surface->orig_width;
+ va_wl_surface->height = obj_surface->orig_height;
+ return true;
+}
+
+static VAStatus
+va_attach_rgb_surface(
+ VADriverContextP ctx,
+ struct va_wl_surface *va_wl_surface,
+ struct object_surface *obj_surface,
+ unsigned int flags
+)
+{
+ struct intel_region * const region = &va_wl_surface->region;
+ VAStatus va_status;
+ VASurfaceID va_surface;
+ VARectangle src_rect, dst_rect;
+ unsigned int pp_flags;
+
+ /* Check local buffer */
+ if (va_wl_surface->format != VA_WL_FORMAT_RGBA ||
+ va_wl_surface->width != obj_surface->orig_width ||
+ va_wl_surface->height != obj_surface->orig_height) {
+ va_surface_reset_buffer(ctx, va_wl_surface);
+ if (!va_surface_create_buffer_rgb(ctx, va_wl_surface, obj_surface))
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+ assert(region->bo);
+
+ /* Check buffer link */
+ va_status = va_surface_relink_buffer(ctx, va_wl_surface);
+ if (va_status != VA_STATUS_SUCCESS)
+ return va_status;
+
+ /* Render to RGBA surface */
+ va_surface = obj_surface->base.id;
+ src_rect.x = 0;
+ src_rect.y = 0;
+ src_rect.width = obj_surface->orig_width;
+ src_rect.height = obj_surface->orig_height;
+ dst_rect = src_rect;
+
+ pp_flags = 0;
+ if ((flags & VA_FILTER_SCALING_MASK) == VA_FILTER_SCALING_NL_ANAMORPHIC)
+ pp_flags |= I965_PP_FLAG_AVS;
+ if (flags & VA_TOP_FIELD)
+ pp_flags |= I965_PP_FLAG_TOP_FIELD;
+ else if (flags & VA_BOTTOM_FIELD)
+ pp_flags |= I965_PP_FLAG_BOTTOM_FIELD;
+
+ intel_render_put_surface(ctx, va_surface, &src_rect, &dst_rect, pp_flags);
+ if (obj_surface->subpic != VA_INVALID_ID)
+ intel_render_put_subpicture(ctx, va_surface, &src_rect, &dst_rect);
+ return VA_STATUS_SUCCESS;
+}
+
+static VAStatus
+va_wayland_attach_surface_unlocked(
+ VADriverContextP ctx,
+ struct va_wl_surface *va_wl_surface,
+ struct object_surface *obj_surface,
+ unsigned int flags
+)
+{
+ VAStatus va_status;
+
+ va_status = va_attach_rgb_surface(ctx, va_wl_surface, obj_surface, flags);
+ if (va_status != VA_STATUS_SUCCESS)
+ return va_status;
+
+ if (!va_wl_surface->wl_buffer) {
+ va_wl_surface->wl_buffer = wl_drm_create_buffer(
+ va_wl_surface->wl_drm,
+ va_wl_surface->name,
+ va_wl_surface->width,
+ va_wl_surface->height,
+ va_wl_surface->region.pitch,
+ va_wl_surface->format
+ );
+ if (!va_wl_surface->wl_buffer)
+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
+
+ wl_surface_attach(
+ va_wl_surface->wl_surface,
+ va_wl_surface->wl_buffer,
+ 0, 0
+ );
+ }
+
+ wl_surface_damage(
+ va_wl_surface->wl_surface,
+ 0, 0, va_wl_surface->width, va_wl_surface->height
+ );
+
+ obj_surface->flags |= SURFACE_DISPLAYED;
+
+ if ((obj_surface->flags & SURFACE_ALL_MASK) == SURFACE_DISPLAYED) {
+ dri_bo_unreference(obj_surface->bo);
+ obj_surface->bo = NULL;
+ obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
+
+ if (obj_surface->free_private_data)
+ obj_surface->free_private_data(&obj_surface->private_data);
+ }
+ return VA_STATUS_SUCCESS;
+}
+
+static VAStatus
+va_wayland_attach_surface(
+ VADriverContextP ctx,
+ struct va_wl_surface *va_wl_surface,
+ VASurfaceID va_surface,
+ unsigned int flags
+)
+{
+ struct i965_driver_data * const i965 = i965_driver_data(ctx);
+ struct object_surface *obj_surface;
+ VAStatus va_status;
+
+ if (ctx->display_type != VA_DISPLAY_WAYLAND)
+ return VA_STATUS_ERROR_INVALID_DISPLAY;
+ if (!va_wl_surface)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ obj_surface = SURFACE(va_surface);
+ if (!obj_surface || !obj_surface->bo)
+ return VA_STATUS_ERROR_INVALID_SURFACE;
+
+ _i965LockMutex(&i965->render_mutex);
+ va_status = va_wayland_attach_surface_unlocked(
+ ctx,
+ va_wl_surface,
+ obj_surface,
+ flags
+ );
+ _i965UnlockMutex(&i965->render_mutex);
+ return va_status;
+}
+
+bool
+i965_render_wayland_init(VADriverContextP ctx)
+{
+ struct VADriverVTableWayland * const vtable = ctx->vtable_wayland;
+
+ if (ctx->display_type != VA_DISPLAY_WAYLAND)
+ return true;
+
+ if (!vtable)
+ return false;
+
+ vtable->vaCreateSurfaceWL = va_wayland_create_surface;
+ vtable->vaDestroySurfaceWL = va_wayland_destroy_surface;
+ vtable->vaAttachSurfaceWL = va_wayland_attach_surface;
+ return true;
+}
diff --git a/src/i965_render_wayland.h b/src/i965_render_wayland.h
new file mode 100755
index 0000000..1418c71
--- /dev/null
+++ b/src/i965_render_wayland.h
@@ -0,0 +1,33 @@
+/*
+ * 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_RENDER_WAYLAND_H
+#define I965_RENDER_WAYLAND_H
+
+#include <stdbool.h>
+
+bool
+i965_render_wayland_init(VADriverContextP ctx);
+
+#endif /* I965_RENDER_WAYLAND_H */
--
1.7.5.4
More information about the Libva
mailing list