[Mesa-dev] [PATCH 1/3] Move the code to open the graphic device. Support for render-nodes.

Axel Davy axel.davy at ens.fr
Thu Nov 7 08:13:36 PST 2013


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.davy at 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



More information about the mesa-dev mailing list