[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