From 184bb09ff5cf2715dfee91e25ec20cbaa2e4445c Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Sat, 30 Apr 2011 11:18:23 +0200 Subject: [PATCH] st/egl: Implement EGL_WL_bind_wayland_display for x11,drm,wayland --- configure.ac | 4 +- src/gallium/state_trackers/egl/Makefile | 2 + src/gallium/state_trackers/egl/common/egl_g3d.c | 5 + .../state_trackers/egl/common/egl_g3d_api.c | 33 +++++++ .../state_trackers/egl/common/egl_g3d_image.c | 27 ++++++ src/gallium/state_trackers/egl/common/native.h | 2 + .../egl/common/native_wayland_bufmgr.h | 46 +++++++++ .../egl/common/native_wayland_drm_bufmgr_helper.c | 57 +++++++++++ .../egl/common/native_wayland_drm_bufmgr_helper.h | 44 +++++++++ src/gallium/state_trackers/egl/drm/native_drm.c | 108 +++++++++++++++++++++ src/gallium/state_trackers/egl/drm/native_drm.h | 9 ++ .../state_trackers/egl/wayland/native_drm.c | 69 +++++++++++++ src/gallium/state_trackers/egl/x11/native_dri2.c | 69 +++++++++++++ src/gallium/state_trackers/egl/x11/x11_screen.c | 17 ++++ src/gallium/state_trackers/egl/x11/x11_screen.h | 6 ++ src/gallium/targets/egl/Makefile | 1 + 16 files changed, 497 insertions(+), 2 deletions(-) create mode 100644 src/gallium/state_trackers/egl/common/native_wayland_bufmgr.h create mode 100644 src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c create mode 100644 src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.h diff --git a/configure.ac b/configure.ac index 54d9c29..c705d45 100644 --- a/configure.ac +++ b/configure.ac @@ -1194,12 +1194,12 @@ if test "x$enable_egl" = xyes; then EGL_DRIVERS_DIRS="glx" fi + PKG_CHECK_MODULES([LIBUDEV], [libudev > 150], + [have_libudev=yes],[have_libudev=no]) if test "$mesa_driver" = dri; then # build egl_dri2 when xcb-dri2 is available PKG_CHECK_MODULES([XCB_DRI2], [x11-xcb xcb-dri2 xcb-xfixes], [have_xcb_dri2=yes],[have_xcb_dri2=no]) - PKG_CHECK_MODULES([LIBUDEV], [libudev > 150], - [have_libudev=yes],[have_libudev=no]) if test "$have_xcb_dri2" = yes; then EGL_DRIVER_DRI2=dri2 diff --git a/src/gallium/state_trackers/egl/Makefile b/src/gallium/state_trackers/egl/Makefile index 53673a7..763e7b5 100644 --- a/src/gallium/state_trackers/egl/Makefile +++ b/src/gallium/state_trackers/egl/Makefile @@ -6,6 +6,7 @@ common_INCLUDES = \ -I$(TOP)/src/gallium/include \ -I$(TOP)/src/gallium/auxiliary \ -I$(TOP)/src/egl/main \ + -I$(TOP)/src/egl/wayland/wayland-drm/ \ -I$(TOP)/include common_SOURCES = $(wildcard common/*.c) @@ -56,6 +57,7 @@ endif ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) EGL_OBJECTS += $(wayland_OBJECTS) EGL_CPPFLAGS += -DHAVE_WAYLAND_BACKEND +DEFINES += -DHAVE_WAYLAND_BACKEND endif ifneq ($(findstring drm, $(EGL_PLATFORMS)),) EGL_OBJECTS += $(drm_OBJECTS) diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c index 2c7f3bde..4bd8656 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d.c @@ -552,6 +552,11 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy) if (dpy->Platform == _EGL_PLATFORM_WAYLAND && gdpy->native->buffer) dpy->Extensions.MESA_drm_image = EGL_TRUE; +#ifdef EGL_WL_bind_wayland_display + if (gdpy->native->wayland_bufmgr) + dpy->Extensions.WL_bind_wayland_display = EGL_TRUE; +#endif + if (egl_g3d_add_configs(drv, dpy, 1) == 1) { _eglError(EGL_NOT_INITIALIZED, "eglInitialize(unable to add configs)"); goto fail; diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_api.c b/src/gallium/state_trackers/egl/common/egl_g3d_api.c index f156832..8b1821e 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_api.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_api.c @@ -868,6 +868,34 @@ egl_g3d_show_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy, #endif /* EGL_MESA_screen_surface */ +#ifdef EGL_WL_bind_wayland_display + +static EGLBoolean +egl_g3d_bind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *dpy, + struct wl_display *wl_dpy) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + + if (!gdpy->native->wayland_bufmgr) + return EGL_FALSE; + + return gdpy->native->wayland_bufmgr->bind_display(gdpy->native, wl_dpy); +} + +static EGLBoolean +egl_g3d_unbind_wayland_display_wl(_EGLDriver *drv, _EGLDisplay *dpy, + struct wl_display *wl_dpy) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + + if (!gdpy->native->wayland_bufmgr) + return EGL_FALSE; + + return gdpy->native->wayland_bufmgr->unbind_display(gdpy->native, wl_dpy); +} + +#endif /* EGL_WL_bind_wayland_display */ + void egl_g3d_init_driver_api(_EGLDriver *drv) { @@ -897,6 +925,11 @@ egl_g3d_init_driver_api(_EGLDriver *drv) drv->API.CreateDRMImageMESA = egl_g3d_create_drm_image; drv->API.ExportDRMImageMESA = egl_g3d_export_drm_image; #endif +#ifdef EGL_WL_bind_wayland_display + drv->API.BindWaylandDisplayWL = egl_g3d_bind_wayland_display_wl; + drv->API.UnbindWaylandDisplayWL = egl_g3d_unbind_wayland_display_wl; + +#endif #ifdef EGL_KHR_reusable_sync drv->API.CreateSyncKHR = egl_g3d_create_sync; diff --git a/src/gallium/state_trackers/egl/common/egl_g3d_image.c b/src/gallium/state_trackers/egl/common/egl_g3d_image.c index e1c8316..210b8c2 100644 --- a/src/gallium/state_trackers/egl/common/egl_g3d_image.c +++ b/src/gallium/state_trackers/egl/common/egl_g3d_image.c @@ -179,6 +179,27 @@ egl_g3d_reference_drm_buffer(_EGLDisplay *dpy, EGLint name, #endif /* EGL_MESA_drm_image */ +#ifdef EGL_WL_bind_wayland_display + +static struct pipe_resource * +egl_g3d_reference_wl_buffer(_EGLDisplay *dpy, struct wl_buffer *buffer, + _EGLImage *img, const EGLint *attribs) +{ + struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct pipe_resource *resource = NULL, *tmp = NULL; + + if (!gdpy->native->wayland_bufmgr) + return NULL; + + tmp = gdpy->native->wayland_bufmgr->buffer_get_resource(gdpy->native, buffer); + + pipe_resource_reference(&resource, tmp); + + return resource; +} + +#endif /* EGL_WL_bind_wayland_display */ + _EGLImage * egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLenum target, EGLClientBuffer buffer, @@ -210,6 +231,12 @@ egl_g3d_create_image(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, (EGLint) buffer, &gimg->base, attribs); break; #endif +#ifdef EGL_WL_bind_wayland_display + case EGL_WAYLAND_BUFFER_WL: + ptex = egl_g3d_reference_wl_buffer(dpy, + (struct wl_buffer *) buffer, &gimg->base, attribs); + break; +#endif default: ptex = NULL; break; diff --git a/src/gallium/state_trackers/egl/common/native.h b/src/gallium/state_trackers/egl/common/native.h index 9246f8c..8646e52 100644 --- a/src/gallium/state_trackers/egl/common/native.h +++ b/src/gallium/state_trackers/egl/common/native.h @@ -40,6 +40,7 @@ extern "C" { #include "native_buffer.h" #include "native_modeset.h" +#include "native_wayland_bufmgr.h" /** * Only color buffers are listed. The others are allocated privately through, @@ -198,6 +199,7 @@ struct native_display { const struct native_display_buffer *buffer; const struct native_display_modeset *modeset; + const struct native_display_wayland_bufmgr *wayland_bufmgr; }; /** diff --git a/src/gallium/state_trackers/egl/common/native_wayland_bufmgr.h b/src/gallium/state_trackers/egl/common/native_wayland_bufmgr.h new file mode 100644 index 0000000..b29fd15 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native_wayland_bufmgr.h @@ -0,0 +1,46 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 _NATIVE_WAYLAND_BUFMGR_H_ +#define _NATIVE_WAYLAND_BUFMGR_H_ + +struct native_display; +struct wl_display; +struct wl_buffer; +struct pipe_resource; + +struct native_display_wayland_bufmgr { + boolean (*bind_display)(struct native_display *ndpy, + struct wl_display *wl_dpy); + + boolean (*unbind_display)(struct native_display *ndpy, + struct wl_display *wl_dpy); + + struct pipe_resource *(*buffer_get_resource)(struct native_display *ndpy, + struct wl_buffer *buffer); + +}; + +#endif /* _NATIVE_WAYLAND_BUFMGR_H_ */ diff --git a/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c b/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c new file mode 100644 index 0000000..bc2cee4 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.c @@ -0,0 +1,57 @@ +#include +#include + +#include "native.h" +#include "util/u_inlines.h" +#include "state_tracker/drm_driver.h" + +#ifdef HAVE_WAYLAND_BACKEND + +#include +#include + +#include "native_wayland_drm_bufmgr_helper.h" + +void * +egl_g3d_wl_drm_helper_reference_buffer(void *user_data, uint32_t name, + int32_t width, int32_t height, + uint32_t stride, + struct wl_visual *visual) +{ + struct native_display *ndpy = user_data; + struct pipe_resource templ; + struct winsys_handle wsh; + enum pipe_format format = PIPE_FORMAT_B8G8R8A8_UNORM; + + memset(&templ, 0, sizeof(templ)); + templ.target = PIPE_TEXTURE_2D; + templ.format = format; + templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.array_size = 1; + + memset(&wsh, 0, sizeof(wsh)); + wsh.handle = name; + wsh.stride = stride; + + return ndpy->screen->resource_from_handle(ndpy->screen, &templ, &wsh); +} + +void +egl_g3d_wl_drm_helper_unreference_buffer(void *user_data, void *buffer) +{ + struct pipe_resource *resource = buffer; + + pipe_resource_reference(&resource, NULL); +} + +struct pipe_resource * +egl_g3d_wl_drm_common_wl_buffer_get_resource(struct native_display *ndpy, + struct wl_buffer *buffer) +{ + return wayland_drm_buffer_get_buffer(buffer); +} + +#endif diff --git a/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.h b/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.h new file mode 100644 index 0000000..71cb6c5 --- /dev/null +++ b/src/gallium/state_trackers/egl/common/native_wayland_drm_bufmgr_helper.h @@ -0,0 +1,44 @@ +/* + * Mesa 3-D graphics library + * Version: 7.11 + * + * Copyright (C) 2011 Benjamin Franzke + * + * 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, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 _NATIVE_WAYLAND_DRM_BUFMGR_HELPER_H_ +#define _NATIVE_WAYLAND_DRM_BUFMGR_HELPER_H_ + +#include "wayland-drm.h" + +void * +egl_g3d_wl_drm_helper_reference_buffer(void *user_data, uint32_t name, + int32_t width, int32_t height, + uint32_t stride, + struct wl_visual *visual); + +void +egl_g3d_wl_drm_helper_unreference_buffer(void *user_data, void *buffer); + +struct pipe_resource * +egl_g3d_wl_drm_common_wl_buffer_get_resource(struct native_display *ndpy, + struct wl_buffer *buffer); + +#endif /* _NATIVE_WAYLAND_DRM_BUFMGR_HELPER_H_ */ diff --git a/src/gallium/state_trackers/egl/drm/native_drm.c b/src/gallium/state_trackers/egl/drm/native_drm.c index 9863329..c89a6d4 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.c +++ b/src/gallium/state_trackers/egl/drm/native_drm.c @@ -23,6 +23,7 @@ * DEALINGS IN THE SOFTWARE. */ +#include #include #include #include @@ -36,6 +37,10 @@ #include #include "radeon/drm/radeon_drm_public.h" +#ifdef HAVE_LIBUDEV +#include +#endif + static boolean drm_display_is_format_supported(struct native_display *ndpy, enum pipe_format fmt, boolean is_color) @@ -126,6 +131,9 @@ drm_display_destroy(struct native_display *ndpy) ndpy_uninit(ndpy); + if (drmdpy->device_name) + FREE(drmdpy->device_name); + if (drmdpy->fd >= 0) close(drmdpy->fd); @@ -207,6 +215,101 @@ static struct native_display_buffer drm_display_buffer = { drm_display_export_buffer }; +static int +drm_display_authenticate(void *user_data, uint32_t magic) +{ + struct native_display *ndpy = user_data; + struct drm_display *drmdpy = drm_display(ndpy); + + return drmAuthMagic(drmdpy->fd, magic); +} + +static char * +drm_get_device_name(int fd) +{ + char *device_name = NULL; +#ifdef HAVE_LIBUDEV + struct udev *udev; + struct udev_device *device; + struct stat buf; + const char *tmp; + + udev = udev_new(); + if (fstat(fd, &buf) < 0) { + _eglLog(_EGL_WARNING, "failed to stat fd %d", fd); + goto out; + } + + device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev); + if (device == NULL) { + _eglLog(_EGL_WARNING, + "could not create udev device for fd %d", fd); + goto out; + } + + tmp = udev_device_get_devnode(device); + if (!tmp) + goto out; + device_name = strdup(tmp); + +out: + udev_device_unref(device); + udev_unref(udev); + +#endif + return device_name; +} + +#ifdef HAVE_WAYLAND_BACKEND + +static struct wayland_drm_callbacks wl_drm_callbacks = { + drm_display_authenticate, + egl_g3d_wl_drm_helper_reference_buffer, + egl_g3d_wl_drm_helper_unreference_buffer +}; + +static boolean +drm_display_bind_wayland_display(struct native_display *ndpy, + struct wl_display *wl_dpy) +{ + struct drm_display *drmdpy = drm_display(ndpy); + + if (drmdpy->wl_server_drm) + return FALSE; + + drmdpy->wl_server_drm = wayland_drm_init(wl_dpy, + drmdpy->device_name, + &wl_drm_callbacks, ndpy); + + if (!drmdpy->wl_server_drm) + return FALSE; + + return TRUE; +} + +static boolean +drm_display_unbind_wayland_display(struct native_display *ndpy, + struct wl_display *wl_dpy) +{ + struct drm_display *drmdpy = drm_display(ndpy); + + if (!drmdpy->wl_server_drm) + return FALSE; + + wayland_drm_uninit(drmdpy->wl_server_drm); + drmdpy->wl_server_drm = NULL; + + return TRUE; +} + +static struct native_display_wayland_bufmgr drm_display_wayland_bufmgr = { + drm_display_bind_wayland_display, + drm_display_unbind_wayland_display, + egl_g3d_wl_drm_common_wl_buffer_get_resource +}; + +#endif /* HAVE_WAYLAND_BACKEND */ + static struct native_display * drm_create_display(int fd, struct native_event_handler *event_handler, void *user_data) @@ -218,6 +321,7 @@ drm_create_display(int fd, struct native_event_handler *event_handler, return NULL; drmdpy->fd = fd; + drmdpy->device_name = drm_get_device_name(fd); drmdpy->event_handler = event_handler; drmdpy->base.user_data = user_data; @@ -231,6 +335,10 @@ drm_create_display(int fd, struct native_event_handler *event_handler, drmdpy->base.get_configs = drm_display_get_configs; drmdpy->base.buffer = &drm_display_buffer; +#ifdef HAVE_WAYLAND_BACKEND + if (drmdpy->device_name) + drmdpy->base.wayland_bufmgr = &drm_display_wayland_bufmgr; +#endif drm_display_init_modeset(&drmdpy->base); return &drmdpy->base; diff --git a/src/gallium/state_trackers/egl/drm/native_drm.h b/src/gallium/state_trackers/egl/drm/native_drm.h index 7da9b45..41cdc4f 100644 --- a/src/gallium/state_trackers/egl/drm/native_drm.h +++ b/src/gallium/state_trackers/egl/drm/native_drm.h @@ -37,6 +37,10 @@ #include "common/native.h" #include "common/native_helper.h" +#ifdef HAVE_WAYLAND_BACKEND +#include "common/native_wayland_drm_bufmgr_helper.h" +#endif + struct drm_config; struct drm_crtc; struct drm_connector; @@ -49,6 +53,7 @@ struct drm_display { struct native_event_handler *event_handler; int fd; + char *device_name; struct drm_config *config; /* for modesetting */ @@ -59,6 +64,10 @@ struct drm_display { struct drm_surface **shown_surfaces; /* save the original settings of the CRTCs */ struct drm_crtc *saved_crtcs; + +#ifdef HAVE_WAYLAND_BACKEND + struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */ +#endif }; struct drm_config { diff --git a/src/gallium/state_trackers/egl/wayland/native_drm.c b/src/gallium/state_trackers/egl/wayland/native_drm.c index 604720f..f643c7c 100644 --- a/src/gallium/state_trackers/egl/wayland/native_drm.c +++ b/src/gallium/state_trackers/egl/wayland/native_drm.c @@ -45,6 +45,8 @@ #include "wayland-drm-client-protocol.h" #include "wayland-egl-priv.h" +#include "common/native_wayland_drm_bufmgr_helper.h" + #include #include #include @@ -56,6 +58,7 @@ struct wayland_drm_display { struct native_event_handler *event_handler; struct wl_drm *wl_drm; + struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */ int fd; char *device_name; boolean authenticated; @@ -268,6 +271,71 @@ static struct native_display_buffer wayland_drm_display_buffer = { wayland_drm_display_export_buffer }; +static int +wayland_drm_display_authenticate(void *user_data, uint32_t magic) +{ + struct native_display *ndpy = user_data; + struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy); + boolean current_authenticate, authenticated; + + current_authenticate = drmdpy->authenticated; + + wl_drm_authenticate(drmdpy->wl_drm, magic); + force_roundtrip(drmdpy->base.dpy); + authenticated = drmdpy->authenticated; + + drmdpy->authenticated = current_authenticate; + + return authenticated ? 0 : -1; +} + +static struct wayland_drm_callbacks wl_drm_callbacks = { + wayland_drm_display_authenticate, + egl_g3d_wl_drm_helper_reference_buffer, + egl_g3d_wl_drm_helper_unreference_buffer +}; + +static boolean +wayland_drm_display_bind_wayland_display(struct native_display *ndpy, + struct wl_display *wl_dpy) +{ + struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy); + + if (drmdpy->wl_server_drm) + return FALSE; + + drmdpy->wl_server_drm = + wayland_drm_init(wl_dpy, drmdpy->device_name, + &wl_drm_callbacks, ndpy); + + if (!drmdpy->wl_server_drm) + return FALSE; + + return TRUE; +} + +static boolean +wayland_drm_display_unbind_wayland_display(struct native_display *ndpy, + struct wl_display *wl_dpy) +{ + struct wayland_drm_display *drmdpy = wayland_drm_display(ndpy); + + if (!drmdpy->wl_server_drm) + return FALSE; + + wayland_drm_uninit(drmdpy->wl_server_drm); + drmdpy->wl_server_drm = NULL; + + return TRUE; +} + +static struct native_display_wayland_bufmgr wayland_drm_display_wayland_bufmgr = { + wayland_drm_display_bind_wayland_display, + wayland_drm_display_unbind_wayland_display, + egl_g3d_wl_drm_common_wl_buffer_get_resource +}; + + struct wayland_display * wayland_create_drm_display(struct wl_display *dpy, struct native_event_handler *event_handler, @@ -294,6 +362,7 @@ wayland_create_drm_display(struct wl_display *dpy, } drmdpy->base.base.destroy = wayland_drm_display_destroy; drmdpy->base.base.buffer = &wayland_drm_display_buffer; + drmdpy->base.base.wayland_bufmgr = &wayland_drm_display_wayland_bufmgr; drmdpy->base.create_buffer = wayland_create_drm_buffer; diff --git a/src/gallium/state_trackers/egl/x11/native_dri2.c b/src/gallium/state_trackers/egl/x11/native_dri2.c index 5afca67..a56d434 100644 --- a/src/gallium/state_trackers/egl/x11/native_dri2.c +++ b/src/gallium/state_trackers/egl/x11/native_dri2.c @@ -38,6 +38,10 @@ #include "native_x11.h" #include "x11_screen.h" +#ifdef HAVE_WAYLAND_BACKEND +#include "common/native_wayland_drm_bufmgr_helper.h" +#endif + #ifdef GLX_DIRECT_RENDERING struct dri2_display { @@ -56,6 +60,9 @@ struct dri2_display { int num_configs; struct util_hash_table *surfaces; +#ifdef HAVE_WAYLAND_BACKEND + struct wl_drm *wl_server_drm; /* for EGL_WL_bind_wayland_display */ +#endif }; struct dri2_surface { @@ -802,6 +809,65 @@ dri2_display_hash_table_compare(void *key1, void *key2) return ((char *) key1 - (char *) key2); } +static int +dri2_display_authenticate(void *user_data, uint32_t magic) +{ + struct native_display *ndpy = user_data; + struct dri2_display *dri2dpy = dri2_display(ndpy); + + return x11_screen_authenticate(dri2dpy->xscr, magic); +} + +#ifdef HAVE_WAYLAND_BACKEND + +static struct wayland_drm_callbacks wl_drm_callbacks = { + dri2_display_authenticate, + egl_g3d_wl_drm_helper_reference_buffer, + egl_g3d_wl_drm_helper_unreference_buffer +}; + +static boolean +dri2_display_bind_wayland_display(struct native_display *ndpy, + struct wl_display *wl_dpy) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + + if (dri2dpy->wl_server_drm) + return FALSE; + + dri2dpy->wl_server_drm = wayland_drm_init(wl_dpy, + x11_screen_get_device_name(dri2dpy->xscr), + &wl_drm_callbacks, ndpy); + + if (!dri2dpy->wl_server_drm) + return FALSE; + + return TRUE; +} + +static boolean +dri2_display_unbind_wayland_display(struct native_display *ndpy, + struct wl_display *wl_dpy) +{ + struct dri2_display *dri2dpy = dri2_display(ndpy); + + if (!dri2dpy->wl_server_drm) + return FALSE; + + wayland_drm_uninit(dri2dpy->wl_server_drm); + dri2dpy->wl_server_drm = NULL; + + return TRUE; +} + +static struct native_display_wayland_bufmgr dri2_display_wayland_bufmgr = { + dri2_display_bind_wayland_display, + dri2_display_unbind_wayland_display, + egl_g3d_wl_drm_common_wl_buffer_get_resource +}; + +#endif /* HAVE_WAYLAND_BACKEND */ + struct native_display * x11_create_dri2_display(Display *dpy, struct native_event_handler *event_handler, @@ -851,6 +917,9 @@ x11_create_dri2_display(Display *dpy, dri2dpy->base.is_pixmap_supported = dri2_display_is_pixmap_supported; dri2dpy->base.create_window_surface = dri2_display_create_window_surface; dri2dpy->base.create_pixmap_surface = dri2_display_create_pixmap_surface; +#ifdef HAVE_WAYLAND_BACKEND + dri2dpy->base.wayland_bufmgr = &dri2_display_wayland_bufmgr; +#endif return &dri2dpy->base; } diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.c b/src/gallium/state_trackers/egl/x11/x11_screen.c index c919b79..f1cc440 100644 --- a/src/gallium/state_trackers/egl/x11/x11_screen.c +++ b/src/gallium/state_trackers/egl/x11/x11_screen.c @@ -307,6 +307,23 @@ x11_screen_enable_dri2(struct x11_screen *xscr, return xscr->dri_fd; } +char * +x11_screen_get_device_name(struct x11_screen *xscr) +{ + return xscr->dri_device; +} + +int +x11_screen_authenticate(struct x11_screen *xscr, uint32_t id) +{ + boolean authenticated; + + authenticated = DRI2Authenticate(xscr->dpy, + RootWindow(xscr->dpy, xscr->number), id); + + return authenticated ? 0 : -1; +} + /** * Create/Destroy the DRI drawable. */ diff --git a/src/gallium/state_trackers/egl/x11/x11_screen.h b/src/gallium/state_trackers/egl/x11/x11_screen.h index 2e313e0..acf1300 100644 --- a/src/gallium/state_trackers/egl/x11/x11_screen.h +++ b/src/gallium/state_trackers/egl/x11/x11_screen.h @@ -97,6 +97,12 @@ x11_screen_enable_dri2(struct x11_screen *xscr, x11_drawable_invalidate_buffers invalidate_buffers, void *user_data); +char * +x11_screen_get_device_name(struct x11_screen *xscr); + +int +x11_screen_authenticate(struct x11_screen *xscr, uint32_t id); + void x11_drawable_enable_dri2(struct x11_screen *xscr, Drawable drawable, boolean on); diff --git a/src/gallium/targets/egl/Makefile b/src/gallium/targets/egl/Makefile index 9d76a70..a455b61 100644 --- a/src/gallium/targets/egl/Makefile +++ b/src/gallium/targets/egl/Makefile @@ -49,6 +49,7 @@ endif ifneq ($(findstring wayland, $(EGL_PLATFORMS)),) egl_SYS += $(WAYLAND_LIBS) $(LIBDRM_LIB) egl_LIBS += $(TOP)/src/gallium/winsys/sw/wayland/libws_wayland.a +egl_LIBS += $(TOP)/src/egl/wayland/wayland-drm/libwayland-drm.a endif ifneq ($(findstring drm, $(EGL_PLATFORMS)),) egl_SYS += $(LIBDRM_LIB) -- 2.7.4