From 99b70277b7a71ca729b7723c0be213c9db46702c Mon Sep 17 00:00:00 2001 From: Jonathan Gray Date: Sun, 29 May 2016 10:21:21 +0000 Subject: Import Mesa 11.2.2 --- lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c | 134 +++++++++++----------- lib/mesa/src/egl/egl-symbols-check | 4 +- 2 files changed, 68 insertions(+), 70 deletions(-) (limited to 'lib/mesa/src/egl') diff --git a/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c b/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c index c4a54431c..8e4a131b1 100644 --- a/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c +++ b/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c @@ -96,22 +96,9 @@ static __DRIcontext * egl_dri3_get_dri_context(struct loader_dri3_drawable *draw) { _EGLContext *ctx = _eglGetCurrentContext(); - struct dri2_egl_context *dri2_ctx; - if (!ctx) - return NULL; - dri2_ctx = dri2_egl_context(ctx); - return dri2_ctx->dri_context; -} + struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx); -static __DRIscreen * -egl_dri3_get_dri_screen(struct loader_dri3_drawable *draw) -{ - _EGLContext *ctx = _eglGetCurrentContext(); - struct dri2_egl_context *dri2_ctx; - if (!ctx) - return NULL; - dri2_ctx = dri2_egl_context(ctx); - return dri2_egl_display(dri2_ctx->base.Resource.Display)->dri_screen; + return dri2_ctx->dri_context; } static void @@ -123,14 +110,13 @@ egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags) dri2_flush_drawable_for_swapbuffers(disp, &dri3_surf->base); } -static const struct loader_dri3_vtable egl_dri3_vtable = { +static struct loader_dri3_vtable egl_dri3_vtable = { .get_swap_interval = egl_dri3_get_swap_interval, .clamp_swap_interval = egl_dri3_clamp_swap_interval, .set_swap_interval = egl_dri3_set_swap_interval, .set_drawable_size = egl_dri3_set_drawable_size, .in_current_context = egl_dri3_in_current_context, .get_dri_context = egl_dri3_get_dri_context, - .get_dri_screen = egl_dri3_get_dri_screen, .flush_drawable = egl_dri3_flush_drawable, .show_fps = NULL, }; @@ -142,6 +128,9 @@ dri3_destroy_surface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf) (void) drv; + if (!_eglPutSurface(surf)) + return EGL_TRUE; + loader_dri3_drawable_fini(&dri3_surf->loader_drawable); free(surf); @@ -160,6 +149,16 @@ dri3_set_swap_interval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf, return EGL_TRUE; } +static xcb_screen_t * +get_xcb_screen(xcb_screen_iterator_t iter, int screen) +{ + for (; iter.rem; --screen, xcb_screen_next(&iter)) + if (screen == 0) + return iter.data; + + return NULL; +} + static _EGLSurface * dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, void *native_surface, @@ -170,6 +169,8 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, struct dri3_egl_surface *dri3_surf; const __DRIconfig *dri_config; xcb_drawable_t drawable; + xcb_screen_iterator_t s; + xcb_screen_t *screen; STATIC_ASSERT(sizeof(uintptr_t) == sizeof(native_surface)); drawable = (uintptr_t) native_surface; @@ -186,9 +187,16 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, goto cleanup_surf; if (type == EGL_PBUFFER_BIT) { + s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); + screen = get_xcb_screen(s, dri2_dpy->screen); + if (!screen) { + _eglError(EGL_BAD_NATIVE_WINDOW, "dri3_create_surface"); + goto cleanup_surf; + } + drawable = xcb_generate_id(dri2_dpy->conn); xcb_create_pixmap(dri2_dpy->conn, conf->BufferSize, - drawable, dri2_dpy->screen->root, + drawable, screen->root, dri3_surf->base.Width, dri3_surf->base.Height); } @@ -216,25 +224,6 @@ dri3_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, return NULL; } -static int -dri3_authenticate(_EGLDisplay *disp, uint32_t id) -{ -#ifdef HAVE_WAYLAND_PLATFORM - struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); - - if (dri2_dpy->device_name) { - _eglLog(_EGL_WARNING, - "Wayland client render node authentication is unnecessary"); - return 0; - } - - _eglLog(_EGL_WARNING, - "Wayland client primary node authentication isn't supported"); -#endif - - return -1; -} - /** * Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface(). */ @@ -388,7 +377,7 @@ dri3_swap_buffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw) /* No-op for a pixmap or pbuffer surface */ if (draw->Type == EGL_PIXMAP_BIT || draw->Type == EGL_PBUFFER_BIT) - return EGL_FALSE; + return 0; return loader_dri3_swap_buffers_msc(&dri3_surf->loader_drawable, 0, 0, 0, 0, @@ -419,25 +408,6 @@ dri3_query_buffer_age(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) return loader_dri3_query_buffer_age(&dri3_surf->loader_drawable); } -static EGLBoolean -dri3_query_surface(_EGLDriver *drv, _EGLDisplay *dpy, - _EGLSurface *surf, EGLint attribute, - EGLint *value) -{ - struct dri3_egl_surface *dri3_surf = dri3_egl_surface(surf); - - switch (attribute) { - case EGL_WIDTH: - case EGL_HEIGHT: - loader_dri3_update_drawable_geometry(&dri3_surf->loader_drawable); - break; - default: - break; - } - - return _eglQuerySurface(drv, dpy, surf, attribute, value); -} - static __DRIdrawable * dri3_get_dri_drawable(_EGLSurface *surf) { @@ -447,7 +417,7 @@ dri3_get_dri_drawable(_EGLSurface *surf) } struct dri2_egl_display_vtbl dri3_x11_display_vtbl = { - .authenticate = dri3_authenticate, + .authenticate = NULL, .create_window_surface = dri3_create_window_surface, .create_pixmap_surface = dri3_create_pixmap_surface, .create_pbuffer_surface = dri3_create_pbuffer_surface, @@ -460,12 +430,34 @@ struct dri2_egl_display_vtbl dri3_x11_display_vtbl = { .post_sub_buffer = dri2_fallback_post_sub_buffer, .copy_buffers = dri3_copy_buffers, .query_buffer_age = dri3_query_buffer_age, - .query_surface = dri3_query_surface, .create_wayland_buffer_from_image = dri2_fallback_create_wayland_buffer_from_image, .get_sync_values = dri3_get_sync_values, .get_dri_drawable = dri3_get_dri_drawable, }; +static char * +dri3_get_device_name(int fd) +{ + char *ret = NULL; + + ret = drmGetRenderDeviceNameFromFd(fd); + if (ret) + return ret; + + /* For dri3, render node support is required for WL_bind_wayland_display. + * In order not to regress on older systems without kernel or libdrm + * support, fall back to dri2. User can override it with environment + * variable if they don't need to use that extension. + */ + if (getenv("EGL_FORCE_DRI3") == NULL) { + _eglLog(_EGL_WARNING, "Render node support not available, falling back to dri2"); + _eglLog(_EGL_WARNING, "If you want to force dri3, set EGL_FORCE_DRI3 environment variable"); + } else + ret = loader_get_device_name_for_fd(fd); + + return ret; +} + EGLBoolean dri3_x11_connect(struct dri2_egl_display *dri2_dpy) { @@ -474,6 +466,8 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy) xcb_present_query_version_reply_t *present_query; xcb_present_query_version_cookie_t present_query_cookie; xcb_generic_error_t *error; + xcb_screen_iterator_t s; + xcb_screen_t *screen; const xcb_query_extension_reply_t *extension; xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri3_id); @@ -516,7 +510,14 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy) } free(present_query); - dri2_dpy->fd = loader_dri3_open(dri2_dpy->conn, dri2_dpy->screen->root, 0); + s = xcb_setup_roots_iterator(xcb_get_setup(dri2_dpy->conn)); + screen = get_xcb_screen(s, dri2_dpy->screen); + if (!screen) { + _eglError(EGL_BAD_NATIVE_WINDOW, "dri3_x11_connect"); + return EGL_FALSE; + } + + dri2_dpy->fd = loader_dri3_open(dri2_dpy->conn, screen->root, 0); if (dri2_dpy->fd < 0) { int conn_error = xcb_connection_has_error(dri2_dpy->conn); _eglLog(_EGL_WARNING, "DRI3: Screen seems not DRI3 capable"); @@ -529,19 +530,18 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy) dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd, &dri2_dpy->is_different_gpu); - dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd); + dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0); if (!dri2_dpy->driver_name) { _eglLog(_EGL_WARNING, "DRI3: No driver found"); close(dri2_dpy->fd); return EGL_FALSE; } -#ifdef HAVE_WAYLAND_PLATFORM - /* Only try to get a render device name since dri3 doesn't provide a - * mechanism for authenticating client opened device node fds. If this - * fails then don't advertise the extension. */ - dri2_dpy->device_name = drmGetRenderDeviceNameFromFd(dri2_dpy->fd); -#endif + dri2_dpy->device_name = dri3_get_device_name(dri2_dpy->fd); + if (!dri2_dpy->device_name) { + close(dri2_dpy->fd); + return EGL_FALSE; + } return EGL_TRUE; } diff --git a/lib/mesa/src/egl/egl-symbols-check b/lib/mesa/src/egl/egl-symbols-check index 4c5232cb6..5d46fed57 100755 --- a/lib/mesa/src/egl/egl-symbols-check +++ b/lib/mesa/src/egl/egl-symbols-check @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash FUNCS=$(nm -D --defined-only ${1-.libs/libEGL.so} | grep -o "T .*" | cut -c 3- | while read func; do ( grep -q "^$func$" || echo $func ) <