summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Franzke <benjaminfranzke@googlemail.com>2011-07-16 00:27:25 +0200
committerBenjamin Franzke <benjaminfranzke@googlemail.com>2011-07-20 09:37:54 +0000
commit5e618f75ef4590e2da8a8b1bc1e6b10481a44544 (patch)
tree37f31c64bddee00dacb5bb0919f9fe10a80ce28c
parentc2fb87094bb67d3c92e0bcbd7f36e8164d6e3354 (diff)
[WIP] Add wayland drm backend
-rw-r--r--Makefile.am3
-rw-r--r--configure.ac14
-rw-r--r--libva-wayland.pc.in12
-rw-r--r--va/Makefile.am21
-rw-r--r--va/va_wayland.h48
-rw-r--r--va/wayland/.gitignore2
-rw-r--r--va/wayland/Makefile.am38
-rw-r--r--va/wayland/protocol/wayland-drm.xml44
l---------va/wayland/va_dricommon.h1
-rw-r--r--va/wayland/va_wayland.c492
-rw-r--r--va/wayland/wayland-egl-priv.h46
11 files changed, 716 insertions, 5 deletions
diff --git a/Makefile.am b/Makefile.am
index 4d4fb49..581050f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -32,6 +32,7 @@ endif
pcfiles = libva.pc libva-tpi.pc
pcfiles += libva-x11.pc
+pcfiles += libva-wayland.pc
if USE_GLX
pcfiles += libva-glx.pc
endif
@@ -43,6 +44,6 @@ endif
pkgconfigdir = @pkgconfigdir@
pkgconfig_DATA = $(pcfiles)
-EXTRA_DIST = libva.pc.in libva-tpi.pc.in libva-x11.pc.in libva-glx.pc.in libva-egl.pc.in
+EXTRA_DIST = libva.pc.in libva-tpi.pc.in libva-x11.pc.in libva-wayland.pc.in libva-glx.pc.in libva-egl.pc.in
CLEANFILES = $(pcfiles)
diff --git a/configure.ac b/configure.ac
index 4372a8a..48e977d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -77,6 +77,11 @@ AC_ARG_ENABLE(dummy-backend,
[build dummy libva backend])],
[], [enable_dummy_backend=no])
+AC_ARG_ENABLE(wayland-backend,
+ [AC_HELP_STRING([--enable-wayland-backend],
+ [build wayland libva backend])],
+ [], [enable_wayland_backend=no])
+
AC_ARG_ENABLE(i965-driver,
[AC_HELP_STRING([--enable-i965-driver],
[build i965 video driver])],
@@ -120,6 +125,12 @@ if test x$libudev = xno; then
fi
AM_CONDITIONAL(BUILD_DUMMY_BACKEND, test x$enable_dummy_backend = xyes)
+if test x$enable_wayland_backend = xyes; then
+ PKG_CHECK_MODULES([WAYLAND], [wayland-client libdrm_intel])
+ WAYLAND_SCANNER_RULES(['$(top_srcdir)/va/wayland/protocol'])
+fi
+AM_CONDITIONAL(BUILD_WAYLAND_BACKEND, test x$enable_wayland_backend = xyes)
+
# Check for OpenGL (X11)
USE_GLX="no"
GL_DEPS_CFLAGS=""
@@ -170,6 +181,7 @@ AC_OUTPUT([
va/glx/Makefile
va/egl/Makefile
va/dummy/Makefile
+ va/wayland/Makefile
dummy_drv_video/Makefile
i965_drv_video/Makefile
i965_drv_video/shaders/Makefile
@@ -188,6 +200,7 @@ AC_OUTPUT([
test/vainfo/Makefile
libva.pc
libva-x11.pc
+ libva-wayland.pc
libva-glx.pc
libva-egl.pc
libva-tpi.pc
@@ -214,6 +227,7 @@ AS_IF([test x$USE_EGL = xyes], [BACKENDS="egl $BACKENDS"])
BACKENDS="x11 $BACKENDS"
AS_IF([test x$enable_dummy_backend = xyes], [BACKENDS="dummy
$BACKENDS"])
+AS_IF([test x$enable_wayland_backend = xyes], [BACKENDS="wayland $BACKENDS"])
echo " • Winsys : ${BACKENDS}"
diff --git a/libva-wayland.pc.in b/libva-wayland.pc.in
new file mode 100644
index 0000000..c23f6bb
--- /dev/null
+++ b/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
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lva-${display}
+Cflags: -I${includedir}
diff --git a/va/Makefile.am b/va/Makefile.am
index 0d955c4..9b51e94 100644
--- a/va/Makefile.am
+++ b/va/Makefile.am
@@ -60,6 +60,19 @@ libva_dummy_backend =
libva_dummy_backenddir =
endif
+if BUILD_WAYLAND_BACKEND
+libva_wayland_backend = libva-wayland.la
+libva_wayland_backenddir = wayland
+
+libva_wayland_la_SOURCES =
+libva_wayland_la_LIBADD = $(libvacorelib) wayland/libva_wayland.la $(LIBVA_LIBS) $(WAYLAND_LIBS)
+libva_wayland_la_LDFLAGS = $(LDADD)
+libva_wayland_la_DEPENDENCIES = $(libvacorelib) wayland/libva_wayland.la
+else
+libva_wayland_backend =
+libva_wayland_backenddir =
+endif
+
if USE_GLX
libva_glx_backend = libva-glx.la
libva_glx_backenddir = glx
@@ -86,14 +99,14 @@ libva_egl_backend =
libva_egl_backenddir =
endif
-lib_LTLIBRARIES = libva.la libva-tpi.la $(libva_x11_backend) $(libva_dummy_backend) $(libva_glx_backend) $(libva_egl_backend)
+lib_LTLIBRARIES = libva.la libva-tpi.la $(libva_x11_backend) $(libva_dummy_backend) $(libva_wayland_backend) $(libva_glx_backend) $(libva_egl_backend)
-DIST_SUBDIRS = x11 glx egl dummy
+DIST_SUBDIRS = x11 glx egl dummy wayland
-SUBDIRS = $(libva_x11_backenddir) $(libva_dummy_backenddir) $(libva_glx_backenddir) $(libva_egl_backenddir)
+SUBDIRS = $(libva_x11_backenddir) $(libva_dummy_backenddir) $(libva_wayland_backenddir) $(libva_glx_backenddir) $(libva_egl_backenddir)
libvaincludedir = ${includedir}/va
-libvainclude_HEADERS = va.h va_tpi.h va_x11.h va_backend.h va_dummy.h va_version.h va_backend_tpi.h
+libvainclude_HEADERS = va.h va_tpi.h va_x11.h va_backend.h va_dummy.h va_wayland.h va_version.h va_backend_tpi.h
DISTCLEANFILES = \
va_version.h
diff --git a/va/va_wayland.h b/va/va_wayland.h
new file mode 100644
index 0000000..2cecbb7
--- /dev/null
+++ b/va/va_wayland.h
@@ -0,0 +1,48 @@
+#ifndef _VA_WAYLAND_H_
+#define _VA_WAYLAND_H_
+
+#include <va/va.h>
+#include <wayland-client.h>
+#include <wayland-egl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Returns a suitable VADisplay for VA API
+ */
+VADisplay vaGetDisplay (
+ struct wl_display *display
+);
+
+/*
+ * Output rendering
+ * Following is the rendering interface for wayland surfaces,
+ * to get the decode output surface to a wayland surface
+ * It basically performs a de-interlacing (if needed),
+ * color space conversion and scaling to the destination
+ * rectangle
+ */
+VAStatus vaPutSurface (
+ VADisplay dpy,
+ VASurfaceID surface,
+ struct wl_egl_window *draw, /* wayland surface */
+ short srcx,
+ short srcy,
+ unsigned short srcw,
+ unsigned short srch,
+ short destx,
+ short desty,
+ unsigned short destw,
+ unsigned short desth,
+ VARectangle *cliprects, /* client supplied destination clip list */
+ unsigned int number_cliprects, /* number of clip rects in the clip list */
+ unsigned int flags /* PutSurface flags */
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VA_WAYLAND_H_ */
diff --git a/va/wayland/.gitignore b/va/wayland/.gitignore
new file mode 100644
index 0000000..0b7b71b
--- /dev/null
+++ b/va/wayland/.gitignore
@@ -0,0 +1,2 @@
+wayland-drm-client-protocol.h
+wayland-drm-protocol.c
diff --git a/va/wayland/Makefile.am b/va/wayland/Makefile.am
new file mode 100644
index 0000000..992e5c9
--- /dev/null
+++ b/va/wayland/Makefile.am
@@ -0,0 +1,38 @@
+# Copyright (c) 2007 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.
+
+AM_CFLAGS = -DLINUX -DWAYLAND \
+ -I$(top_srcdir)/va $(WAYLAND_CFLAGS)
+
+noinst_LTLIBRARIES = libva_wayland.la
+
+libva_wayland_la_LIBADD = $(LIBVA_LIBS) $(WAYLAND_LIBS)
+
+libva_waylandincludedir = ${includedir}/va
+
+libva_wayland_la_SOURCES = va_wayland.c \
+ wayland-drm-client-protocol.h wayland-drm-protocol.c
+
+BUILT_SOURCES = wayland-drm-client-protocol.h wayland-drm-protocol.c
+CLEANFILES = $(BUILT_SOURCES)
+
+@wayland_scanner_rules@
diff --git a/va/wayland/protocol/wayland-drm.xml b/va/wayland/protocol/wayland-drm.xml
new file mode 100644
index 0000000..0331f12
--- /dev/null
+++ b/va/wayland/protocol/wayland-drm.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="drm">
+ <!-- drm support. This object is created by the server and published
+ using the display's global event. -->
+ <interface name="wl_drm" version="1">
+ <enum name="error">
+ <entry name="authenticate_fail" value="0"/>
+ <entry name="invalid_visual" value="1"/>
+ <entry name="invalid_name" value="2"/>
+ </enum>
+
+ <!-- Call this request with the magic received from drmGetMagic().
+ It will be passed on to the drmAuthMagic() or
+ DRIAuthConnection() call. This authentication must be
+ completed before create_buffer could be used. -->
+ <request name="authenticate">
+ <arg name="id" type="uint"/>
+ </request>
+
+ <!-- Create a wayland buffer for the named DRM buffer. The DRM
+ surface must have a name using the flink ioctl -->
+ <request name="create_buffer">
+ <arg name="id" type="new_id" interface="wl_buffer"/>
+ <arg name="name" type="uint"/>
+ <arg name="width" type="int"/>
+ <arg name="height" type="int"/>
+ <arg name="stride" type="uint"/>
+ <arg name="visual" type="object" interface="wl_visual"/>
+ </request>
+
+ <!-- Notification of the path of the drm device which is used by
+ the server. The client should use this device for creating
+ local buffers. Only buffers created from this device should
+ be be passed to the server using this drm object's
+ create_buffer request. -->
+ <event name="device">
+ <arg name="name" type="string"/>
+ </event>
+
+ <!-- Raised if the authenticate request succeeded -->
+ <event name="authenticated"/>
+ </interface>
+
+</protocol>
diff --git a/va/wayland/va_dricommon.h b/va/wayland/va_dricommon.h
new file mode 120000
index 0000000..18a0364
--- /dev/null
+++ b/va/wayland/va_dricommon.h
@@ -0,0 +1 @@
+../x11/va_dricommon.h \ No newline at end of file
diff --git a/va/wayland/va_wayland.c b/va/wayland/va_wayland.c
new file mode 100644
index 0000000..2ba5b6b
--- /dev/null
+++ b/va/wayland/va_wayland.c
@@ -0,0 +1,492 @@
+/*
+ * Copyright (c) 2011 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 "va.h"
+#include "va_backend.h"
+#include "va_wayland.h"
+#include "va_dricommon.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <wayland-client.h>
+#include <wayland-util.h>
+#include "wayland-drm-client-protocol.h"
+#include "wayland-egl-priv.h"
+
+#include <intel_bufmgr.h>
+
+struct wldrm_ctx {
+ struct VADriverContext base;
+
+ struct wl_drm *drm;
+ int authenticated;
+
+ drm_intel_bufmgr *bufmgr;
+};
+
+struct wldrm_buffer {
+ union dri_buffer base;
+ drm_intel_bo *bo;
+ struct wl_buffer *buf;
+};
+
+enum wldrm_buffer_type {
+ WLDRM_BUFFER_FRONT,
+ WLDRM_BUFFER_BACK,
+ WLDRM_BUFFER_COUNT
+};
+
+struct wldrm_drawable {
+ struct dri_drawable base;
+ struct wl_egl_window *win;
+
+ int block_swap_buffers;
+
+ struct wldrm_buffer *buffer[WLDRM_BUFFER_COUNT];
+};
+
+enum {
+ __DRI_BUFFER_FRONT_LEFT = 0,
+ __DRI_BUFFER_BACK_LEFT,
+ __DRI_BUFFER_FRONT_RIGHT,
+ __DRI_BUFFER_BACK_RIGHT,
+ __DRI_BUFFER_DEPTH,
+ __DRI_BUFFER_STENCIL,
+ __DRI_BUFFER_ACCUM,
+ __DRI_BUFFER_FAKE_FRONT_LEFT,
+ __DRI_BUFFER_FAKE_FRONT_RIGHT
+};
+
+/* Cast helpers */
+
+static inline struct wldrm_ctx *
+wldrm_ctx(struct VADriverContext *driver_ctx)
+{
+ return (struct wldrm_ctx *) driver_ctx;
+}
+
+static inline struct wldrm_drawable *
+wldrm_drawable(struct dri_drawable *drawable)
+{
+ return (struct wldrm_drawable *) drawable;
+}
+
+static inline struct VADriverContext *
+va_driver_ctx(struct VADisplayContext *display_ctx)
+{
+ return display_ctx->pDriverContext;
+}
+
+/* Wayland utility */
+
+static void
+sync_callback(void *data)
+{
+ int *done = data;
+
+ *done = 1;
+}
+
+static void
+force_roundtrip(struct wl_display *display)
+{
+ int done = 0;
+
+ wl_display_sync_callback(display, sync_callback, &done);
+ wl_display_iterate(display, WL_DISPLAY_WRITABLE);
+ while (!done)
+ wl_display_iterate(display, WL_DISPLAY_READABLE);
+}
+
+static inline uint32_t
+surface_get_id(struct wl_surface *surface)
+{
+ struct wl_object *object = (struct wl_object *) surface;
+
+ return object->id;
+}
+
+static inline int
+align(int value, int alignment)
+{
+ return (value + alignment - 1) & ~(alignment - 1);
+}
+
+static drm_intel_bo *
+bo_alloc(struct wldrm_ctx *wctx,
+ int width, int height, int cpp,
+ int *name, int *pitch)
+{
+ drm_intel_bo *bo;
+ int size;
+
+ *pitch = align(width, 64) * cpp;
+ size = *pitch * align(height, 4);
+
+ bo = drm_intel_bo_alloc_for_render(wctx->bufmgr,
+ "render buffer", size, 0);
+ if (drm_intel_bo_flink(bo, name))
+ fprintf(stderr, "flink failed for bo: %p\n", bo);
+
+ return bo;
+}
+
+static union dri_buffer *
+wldrm_get_render_buffer(struct VADriverContext *ctx,
+ struct dri_drawable *drawable)
+{
+ struct wldrm_ctx *wctx = wldrm_ctx(ctx);
+ struct wldrm_drawable *wdrawable = wldrm_drawable(drawable);
+ struct wl_egl_window *win = wdrawable->win;
+ struct wldrm_buffer *wbuffer;
+
+ if (!wdrawable->buffer[WLDRM_BUFFER_BACK]) {
+ wbuffer = calloc(1, sizeof *wbuffer);
+ if (!wbuffer)
+ return NULL;
+
+ wbuffer->bo = bo_alloc(wctx,
+ win->width, win->height, 4,
+ &wbuffer->base.dri2.name,
+ &wbuffer->base.dri2.pitch);
+
+ wbuffer->base.dri2.attachment = __DRI_BUFFER_BACK_LEFT;
+ wbuffer->base.dri2.cpp = 4;
+ wbuffer->base.dri2.flags = 0;
+
+ wdrawable->buffer[WLDRM_BUFFER_BACK] = wbuffer;
+ }
+
+ return &wdrawable->buffer[WLDRM_BUFFER_BACK]->base;
+}
+
+static void
+wldrm_frame_callback(struct wl_surface *surface, void *data, uint32_t time)
+{
+ struct wldrm_drawable *wdrawable = data;
+
+ wdrawable->block_swap_buffers = 0;
+}
+
+static void
+wldrm_swap_buffer(struct VADriverContext *ctx,
+ struct dri_drawable *drawable)
+{
+ struct wldrm_ctx *wctx = wldrm_ctx(ctx);
+ struct wldrm_drawable *wdrawable = wldrm_drawable(drawable);
+ struct wl_display *display = wctx->base.native_dpy;
+ struct wl_egl_window *win = wdrawable->win;
+ struct wldrm_buffer *wbuf;
+
+ while (wdrawable->block_swap_buffers)
+ wl_display_iterate(display, WL_DISPLAY_READABLE);
+
+ wdrawable->block_swap_buffers = 1;
+ wl_display_frame_callback(display, win->surface,
+ wldrm_frame_callback, wdrawable);
+
+ wbuf = wdrawable->buffer[WLDRM_BUFFER_BACK];
+ wdrawable->buffer[WLDRM_BUFFER_BACK] =
+ wdrawable->buffer[WLDRM_BUFFER_FRONT];
+ wdrawable->buffer[WLDRM_BUFFER_FRONT] = wbuf;
+ assert(wbuf);
+
+ if (!wbuf->buf) {
+ wbuf->buf =
+ wl_drm_create_buffer(wctx->drm, wbuf->base.dri2.name,
+ win->width, win->height,
+ wbuf->base.dri2.pitch, win->visual);
+ }
+
+ wl_buffer_damage(wbuf->buf, 0, 0, win->width, win->height);
+ wl_surface_attach(win->surface, wbuf->buf, 0, 0);
+ wl_surface_damage(win->surface, 0, 0, win->width, win->height);
+
+ wl_display_flush(display);
+}
+
+static struct dri_drawable *
+wldrm_get_drawable(struct VADriverContext *ctx, void *native_drawable)
+{
+ struct dri_state *dri_state = ctx->dri_state;
+ struct wl_egl_window *win = native_drawable;
+ struct wldrm_drawable *wdrawable;
+ int index = surface_get_id(win->surface) % DRAWABLE_HASH_SZ;
+
+ for (wdrawable = wldrm_drawable(dri_state->drawable_hash[index]);
+ wdrawable != NULL;
+ wdrawable = wldrm_drawable(wdrawable->base.next)) {
+ if (wdrawable->win == win)
+ return &wdrawable->base;
+ }
+
+ wdrawable = calloc(1, sizeof *wdrawable);
+ if (!wdrawable)
+ return NULL;
+
+ wdrawable->base.next = dri_state->drawable_hash[index];
+ dri_state->drawable_hash[index] = &wdrawable->base;
+
+ wdrawable->base.is_window = 1;
+ wdrawable->base.x = 0;
+ wdrawable->base.y = 0;
+ wdrawable->base.width = win->width;
+ wdrawable->base.height = win->height;
+
+ wdrawable->win = win;
+ wdrawable->buffer[0] = wdrawable->buffer[1] = NULL;
+ wdrawable->block_swap_buffers = 0;
+
+ return &wdrawable->base;
+}
+
+static void
+drm_handle_device(void *data, struct wl_drm *drm, const char *device)
+{
+ struct wldrm_ctx *wctx = data;
+ struct dri_state *dri_state = wctx->base.dri_state;
+ drm_magic_t magic;
+ struct stat st;
+
+ if (stat(device, &st) == -1) {
+ fprintf(stderr, "Cannot identify '%s': %d, %s\n",
+ device, errno, strerror(errno));
+ return;
+ }
+
+ if (!S_ISCHR(st.st_mode)) {
+ fprintf(stderr, "%s is no device\n", device);
+ return;
+ }
+
+ dri_state->fd = open(device, O_RDWR);
+ if (dri_state->fd == -1) {
+ fprintf(stderr, "Cannot open '%s': %d, %s\n",
+ device, errno, strerror(errno));
+ return;
+ }
+
+ drmGetMagic(dri_state->fd, &magic);
+ wl_drm_authenticate(wctx->drm, magic);
+}
+
+static void
+drm_handle_authenticated(void *data, struct wl_drm *drm)
+{
+ struct wldrm_ctx *wctx = data;
+
+ wctx->authenticated = 1;
+}
+
+static const struct wl_drm_listener drm_listener = {
+ drm_handle_device,
+ drm_handle_authenticated
+};
+
+static VAStatus
+wldrm_display_ctx_get_driver_name(struct VADisplayContext *display_ctx,
+ char **driver_name)
+{
+ struct wldrm_ctx *wctx = wldrm_ctx(va_driver_ctx(display_ctx));
+ struct dri_state *dri_state = wctx->base.dri_state;
+ struct wl_display *display = wctx->base.native_dpy;
+ uint32_t id;
+
+ memset(dri_state, 0, sizeof(*dri_state));
+ id = wl_display_get_global(display, "wl_drm", 1);
+ if (id == 0)
+ force_roundtrip(display);
+ id = wl_display_get_global(display, "wl_drm", 1);
+ if (id == 0)
+ goto error_unknown;
+ wctx->drm = wl_drm_create(display, id, 1);
+ if (!wctx->drm)
+ goto error_unknown;
+ wl_drm_add_listener(wctx->drm, &drm_listener, wctx);
+ force_roundtrip(display);
+ if (dri_state->fd == -1) {
+ fprintf(stderr, "can't open DRM devices\n");
+ goto cleanup_drm;
+ }
+
+ force_roundtrip(display);
+ if (!wctx->authenticated)
+ goto cleanup_fd;
+
+ wctx->bufmgr = intel_bufmgr_gem_init(dup(dri_state->fd), 0x80000);
+ //intel_bufmgr_gem_enable_reuse(wctx->bufmgr);
+
+ *driver_name = strdup("i965");
+ dri_state->driConnectedFlag = VA_DRI2;
+
+ dri_state->getRenderingBuffer = wldrm_get_render_buffer;
+ dri_state->swapBuffer = wldrm_swap_buffer;
+ dri_state->getDrawable = wldrm_get_drawable;
+
+ return VA_STATUS_SUCCESS;
+
+cleanup_fd:
+ close(dri_state->fd);
+ dri_state->fd = -1;
+cleanup_drm:
+ wl_drm_destroy(wctx->drm);
+error_unknown:
+ return VA_STATUS_ERROR_UNKNOWN;
+}
+
+static int
+wldrm_display_ctx_is_valid(struct VADisplayContext *display_ctx)
+{
+ return (display_ctx != NULL && va_driver_ctx(display_ctx) != NULL);
+}
+
+static void
+wldrm_display_ctx_destroy(struct VADisplayContext *display_ctx)
+{
+ struct wldrm_ctx *wctx;
+ struct dri_state *dri_state;
+
+ if (!wldrm_display_ctx_is_valid(display_ctx))
+ return;
+
+ wctx = wldrm_ctx(va_driver_ctx(display_ctx));
+ dri_state = wctx->base.dri_state;
+
+ drm_intel_bufmgr_destroy(wctx->bufmgr);
+ close(dri_state->fd);
+
+ free(dri_state);
+ free(wctx);
+ free(display_ctx);
+}
+
+VADisplay
+vaGetDisplay(struct wl_display *native_dpy)
+{
+ VADisplay dpy = NULL;
+ struct VADisplayContext *display_ctx;
+
+ if (!native_dpy)
+ return NULL;
+
+ if (!dpy) {
+ /* create new entry */
+ struct wldrm_ctx *wctx;
+ struct dri_state *dri_state;
+
+ display_ctx = calloc(1, sizeof *display_ctx);
+ wctx = calloc(1, sizeof *wctx);
+ dri_state = calloc(1, sizeof *dri_state);
+
+ if (display_ctx && wctx && dri_state) {
+ display_ctx->vadpy_magic = VA_DISPLAY_MAGIC;
+ display_ctx->pDriverContext = &wctx->base;
+ display_ctx->vaGetDriverName =
+ wldrm_display_ctx_get_driver_name;
+ display_ctx->vaIsValid = wldrm_display_ctx_is_valid;
+ display_ctx->vaDestroy = wldrm_display_ctx_destroy;
+
+ wctx->base.native_dpy = native_dpy;
+ wctx->base.dri_state = dri_state;
+
+ dpy = (VADisplay) display_ctx;
+ } else {
+ if (display_ctx)
+ free(display_ctx);
+ if (wctx)
+ free(wctx);
+ if (dri_state)
+ free(dri_state);
+ }
+ }
+
+ return dpy;
+}
+
+#define CTX(dpy) (va_driver_ctx((struct VADisplayContext *)dpy))
+#define CHECK_DISPLAY(dpy) \
+ if( !wldrm_display_ctx_is_valid(dpy) ) { \
+ return VA_STATUS_ERROR_INVALID_DISPLAY; }
+
+extern int fool_postp; /* do nothing for vaPutSurface if set */
+extern int trace_flag; /* trace vaPutSurface parameters */
+
+void
+va_TracePutSurface(VADisplay dpy,
+ VASurfaceID surface,
+ void *draw,
+ short srcx, short srcy,
+ unsigned short srcw, unsigned short srch,
+ short destx, short desty,
+ unsigned short destw, unsigned short desth,
+ VARectangle *cliprects,
+ unsigned int number_cliprects,
+ unsigned int flags);
+
+#define VA_TRACE(trace_func,...) \
+ if (trace_flag) { \
+ trace_func(__VA_ARGS__); \
+ }
+
+VAStatus
+vaPutSurface(VADisplay dpy,
+ VASurfaceID surface,
+ struct wl_egl_window *draw,
+ short srcx, short srcy,
+ unsigned short srcw, unsigned short srch,
+ short destx, short desty,
+ unsigned short destw, unsigned short desth,
+ VARectangle *cliprects, /* client supplied clip list */
+ /* number of clip rects in the clip list */
+ unsigned int number_cliprects,
+ unsigned int flags /* de-interlacing flags */)
+{
+ struct VADriverContext *ctx;
+
+ if (fool_postp)
+ return VA_STATUS_SUCCESS;
+
+ if (draw == NULL)
+ return VA_STATUS_ERROR_UNKNOWN;
+
+ CHECK_DISPLAY(dpy);
+ ctx = CTX(dpy);
+
+ VA_TRACE(va_TracePutSurface, dpy, surface, draw,
+ srcx, srcy, srcw, srch,
+ destx, desty, destw, desth,
+ cliprects, number_cliprects, flags);
+
+ return ctx->vtable->vaPutSurface(ctx, surface, draw,
+ srcx, srcy, srcw, srch,
+ destx, desty, destw, desth,
+ cliprects, number_cliprects, flags);
+}
diff --git a/va/wayland/wayland-egl-priv.h b/va/wayland/wayland-egl-priv.h
new file mode 100644
index 0000000..179f5cf
--- /dev/null
+++ b/va/wayland/wayland-egl-priv.h
@@ -0,0 +1,46 @@
+#ifndef _WAYLAND_EGL_PRIV_H
+#define _WAYLAND_EGL_PRIV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* GCC visibility */
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define WL_EGL_EXPORT __attribute__ ((visibility("default")))
+#else
+#define WL_EGL_EXPORT
+#endif
+
+#include <wayland-client.h>
+
+struct wl_egl_window {
+ struct wl_surface *surface;
+ struct wl_visual *visual;
+
+ int width;
+ int height;
+ int dx;
+ int dy;
+
+ int attached_width;
+ int attached_height;
+};
+
+struct wl_egl_pixmap {
+ struct wl_visual *visual;
+ struct wl_buffer *buffer;
+
+ int width;
+ int height;
+
+ void (*destroy) (struct wl_egl_pixmap *egl_pixmap);
+
+ void *driver_private;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif