diff options
author | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-07-16 00:27:25 +0200 |
---|---|---|
committer | Benjamin Franzke <benjaminfranzke@googlemail.com> | 2011-07-20 09:37:54 +0000 |
commit | 5e618f75ef4590e2da8a8b1bc1e6b10481a44544 (patch) | |
tree | 37f31c64bddee00dacb5bb0919f9fe10a80ce28c | |
parent | c2fb87094bb67d3c92e0bcbd7f36e8164d6e3354 (diff) |
[WIP] Add wayland drm backend
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | libva-wayland.pc.in | 12 | ||||
-rw-r--r-- | va/Makefile.am | 21 | ||||
-rw-r--r-- | va/va_wayland.h | 48 | ||||
-rw-r--r-- | va/wayland/.gitignore | 2 | ||||
-rw-r--r-- | va/wayland/Makefile.am | 38 | ||||
-rw-r--r-- | va/wayland/protocol/wayland-drm.xml | 44 | ||||
l--------- | va/wayland/va_dricommon.h | 1 | ||||
-rw-r--r-- | va/wayland/va_wayland.c | 492 | ||||
-rw-r--r-- | va/wayland/wayland-egl-priv.h | 46 |
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 |