summaryrefslogtreecommitdiff
path: root/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c')
-rw-r--r--lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c100
1 files changed, 64 insertions, 36 deletions
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 8e4a131b1..1648ef08d 100644
--- a/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c
+++ b/lib/mesa/src/egl/drivers/dri2/platform_x11_dri3.c
@@ -96,11 +96,24 @@ static __DRIcontext *
egl_dri3_get_dri_context(struct loader_dri3_drawable *draw)
{
_EGLContext *ctx = _eglGetCurrentContext();
- struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
-
+ struct dri2_egl_context *dri2_ctx;
+ if (!ctx)
+ return NULL;
+ dri2_ctx = dri2_egl_context(ctx);
return dri2_ctx->dri_context;
}
+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;
+}
+
static void
egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
{
@@ -110,13 +123,14 @@ egl_dri3_flush_drawable(struct loader_dri3_drawable *draw, unsigned flags)
dri2_flush_drawable_for_swapbuffers(disp, &dri3_surf->base);
}
-static struct loader_dri3_vtable egl_dri3_vtable = {
+static const 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,
};
@@ -128,9 +142,6 @@ 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);
@@ -224,6 +235,25 @@ 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().
*/
@@ -408,6 +438,25 @@ 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)
{
@@ -417,7 +466,7 @@ dri3_get_dri_drawable(_EGLSurface *surf)
}
struct dri2_egl_display_vtbl dri3_x11_display_vtbl = {
- .authenticate = NULL,
+ .authenticate = dri3_authenticate,
.create_window_surface = dri3_create_window_surface,
.create_pixmap_surface = dri3_create_pixmap_surface,
.create_pbuffer_surface = dri3_create_pbuffer_surface,
@@ -430,34 +479,12 @@ 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)
{
@@ -530,18 +557,19 @@ 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, 0);
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
if (!dri2_dpy->driver_name) {
_eglLog(_EGL_WARNING, "DRI3: No driver found");
close(dri2_dpy->fd);
return EGL_FALSE;
}
- dri2_dpy->device_name = dri3_get_device_name(dri2_dpy->fd);
- if (!dri2_dpy->device_name) {
- 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
return EGL_TRUE;
}