This patch moves the code to open the graphic device in the Wayland backend, removes the authentication request when we are on a render-node, and has a few fixes.
Signed-off-by: Axel Davy <axel.d...@ens.fr> --- src/egl/drivers/dri2/egl_dri2.h | 1 + src/egl/drivers/dri2/platform_wayland.c | 93 ++++++++++++++++++++++----------- 2 files changed, 63 insertions(+), 31 deletions(-) diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index c7d6484..350a626 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -133,6 +133,7 @@ struct dri2_egl_display int authenticated; int formats; uint32_t capabilities; + int enable_tiling; #endif int (*authenticate) (_EGLDisplay *disp, uint32_t id); diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c index c0de16b..709df36 100644 --- a/src/egl/drivers/dri2/platform_wayland.c +++ b/src/egl/drivers/dri2/platform_wayland.c @@ -622,8 +622,8 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp) _eglCleanupDisplay(disp); dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); - close(dri2_dpy->fd); dlclose(dri2_dpy->driver); + close(dri2_dpy->fd); free(dri2_dpy->driver_name); free(dri2_dpy->device_name); wl_drm_destroy(dri2_dpy->wl_drm); @@ -635,34 +635,28 @@ dri2_terminate(_EGLDriver *drv, _EGLDisplay *disp) return EGL_TRUE; } +static char +is_fd_render_node(int fd) +{ + struct stat render; + + if (fstat(fd, &render)) + return 0; + + if (!S_ISCHR(render.st_mode)) + return 0; + + if (render.st_rdev & 0x80) + return 1; + return 0; +} + static void drm_handle_device(void *data, struct wl_drm *drm, const char *device) { struct dri2_egl_display *dri2_dpy = data; - drm_magic_t magic; dri2_dpy->device_name = strdup(device); - if (!dri2_dpy->device_name) - return; - -#ifdef O_CLOEXEC - dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC); - if (dri2_dpy->fd == -1 && errno == EINVAL) -#endif - { - dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR); - if (dri2_dpy->fd != -1) - fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | - FD_CLOEXEC); - } - if (dri2_dpy->fd == -1) { - _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)", - dri2_dpy->device_name, strerror(errno)); - return; - } - - drmGetMagic(dri2_dpy->fd, &magic); - wl_drm_authenticate(dri2_dpy->wl_drm, magic); } static void @@ -738,7 +732,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) struct dri2_egl_display *dri2_dpy; const __DRIconfig *config; uint32_t types; - int i; + int i, is_render_node; + drm_magic_t magic; static const unsigned int argb_masks[4] = { 0xff0000, 0xff00, 0xff, 0xff000000 }; static const unsigned int rgb_masks[4] = { 0xff0000, 0xff00, 0xff, 0 }; @@ -778,9 +773,39 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) if (roundtrip(dri2_dpy) < 0 || dri2_dpy->wl_drm == NULL) goto cleanup_dpy; - if (roundtrip(dri2_dpy) < 0 || dri2_dpy->fd == -1) + if (roundtrip(dri2_dpy) < 0 || dri2_dpy->device_name == NULL) goto cleanup_drm; +#ifdef O_CLOEXEC + dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR | O_CLOEXEC); + if (dri2_dpy->fd == -1 && errno == EINVAL) +#endif + { + dri2_dpy->fd = open(dri2_dpy->device_name, O_RDWR); + if (dri2_dpy->fd != -1) + fcntl(dri2_dpy->fd, F_SETFD, fcntl(dri2_dpy->fd, F_GETFD) | + FD_CLOEXEC); + } + if (dri2_dpy->fd == -1) { + _eglLog(_EGL_WARNING, "wayland-egl: could not open %s (%s)", + dri2_dpy->device_name, strerror(errno)); + goto cleanup_drm; + } + + if (is_fd_render_node(dri2_dpy->fd)) + { + _eglLog(_EGL_DEBUG, "wayland-egl: card is render-node"); + dri2_dpy->authenticated = 1; + is_render_node = 1; + } + else + { + drmGetMagic(dri2_dpy->fd, &magic); + wl_drm_authenticate(dri2_dpy->wl_drm, magic); + is_render_node = 0; + } + dri2_dpy->enable_tiling = 1; + if (roundtrip(dri2_dpy) < 0 || !dri2_dpy->authenticated) goto cleanup_fd; @@ -799,7 +824,7 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) dri2_dpy->dri2_loader_extension.flushFrontBuffer = dri2_flush_front_buffer; dri2_dpy->dri2_loader_extension.getBuffersWithFormat = dri2_get_buffers_with_format; - + dri2_dpy->extensions[0] = &dri2_dpy->dri2_loader_extension.base; dri2_dpy->extensions[1] = &image_lookup_extension.base; dri2_dpy->extensions[2] = &use_invalidate.base; @@ -808,14 +833,16 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) if (!dri2_create_screen(disp)) goto cleanup_driver; - /* The server shouldn't advertise WL_DRM_CAPABILITY_PRIME if the driver - * doesn't have createImageFromFds, since we're using the same driver on - * both sides. We don't want crash if that happens anyway, so fall back to - * gem names if we don't have prime support. */ + /* Render-nodes need to be able to export prime fd, + * since they are not allowed to use GEM names.*/ if (dri2_dpy->image->base.version < 7 || dri2_dpy->image->createImageFromFds == NULL) - dri2_dpy->capabilities &= WL_DRM_CAPABILITY_PRIME; + { + dri2_dpy->capabilities &= ~WL_DRM_CAPABILITY_PRIME; + if (is_render_node) + goto cleanup_screen; + } types = EGL_WINDOW_BIT; for (i = 0; dri2_dpy->driver_configs[i]; i++) { @@ -840,6 +867,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) return EGL_TRUE; + cleanup_screen: + dri2_dpy->core->destroyScreen(dri2_dpy->dri_screen); cleanup_driver: dlclose(dri2_dpy->driver); cleanup_driver_name: @@ -849,6 +878,8 @@ dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) cleanup_drm: free(dri2_dpy->device_name); wl_drm_destroy(dri2_dpy->wl_drm); + if (dri2_dpy->own_device) + wl_display_disconnect(dri2_dpy->wl_dpy); cleanup_dpy: free(dri2_dpy); -- 1.8.1.2 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev