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)
{
.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,
};
(void) drv;
- if (!_eglPutSurface(surf))
- return EGL_TRUE;
-
loader_dri3_drawable_fini(&dri3_surf->loader_drawable);
free(surf);
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().
*/
(int64_t *) sbc) ? EGL_TRUE : EGL_FALSE;
}
+static _EGLImage *
+dri3_create_image_khr_pixmap(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_image *dri2_img;
+ xcb_drawable_t drawable;
+ xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie;
+ xcb_dri3_buffer_from_pixmap_reply_t *bp_reply;
+ unsigned int format;
+
+ drawable = (xcb_drawable_t) (uintptr_t) buffer;
+ bp_cookie = xcb_dri3_buffer_from_pixmap(dri2_dpy->conn, drawable);
+ bp_reply = xcb_dri3_buffer_from_pixmap_reply(dri2_dpy->conn,
+ bp_cookie, NULL);
+ if (!bp_reply) {
+ _eglError(EGL_BAD_ALLOC, "xcb_dri3_buffer_from_pixmap");
+ return NULL;
+ }
+
+ switch (bp_reply->depth) {
+ case 16:
+ format = __DRI_IMAGE_FORMAT_RGB565;
+ break;
+ case 24:
+ format = __DRI_IMAGE_FORMAT_XRGB8888;
+ break;
+ case 32:
+ format = __DRI_IMAGE_FORMAT_ARGB8888;
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER,
+ "dri3_create_image_khr: unsupported pixmap depth");
+ free(bp_reply);
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ dri2_img = malloc(sizeof *dri2_img);
+ if (!dri2_img) {
+ _eglError(EGL_BAD_ALLOC, "dri3_create_image_khr");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ if (!_eglInitImage(&dri2_img->base, disp)) {
+ free(dri2_img);
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ dri2_img->dri_image = loader_dri3_create_image(dri2_dpy->conn,
+ bp_reply,
+ format,
+ dri2_dpy->dri_screen,
+ dri2_dpy->image,
+ dri2_img);
+
+ free(bp_reply);
+
+ return &dri2_img->base;
+}
+
+static _EGLImage *
+dri3_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLContext *ctx, EGLenum target,
+ EGLClientBuffer buffer, const EGLint *attr_list)
+{
+ (void) drv;
+
+ switch (target) {
+ case EGL_NATIVE_PIXMAP_KHR:
+ return dri3_create_image_khr_pixmap(disp, ctx, buffer, attr_list);
+ default:
+ return dri2_create_image_khr(drv, disp, ctx, target, buffer, attr_list);
+ }
+}
+
/**
* Called by the driver when it needs to update the real front buffer with the
* contents of its fake front buffer.
}
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,
.destroy_surface = dri3_destroy_surface,
- .create_image = dri2_create_image_khr,
+ .create_image = dri3_create_image_khr,
.swap_interval = dri3_set_swap_interval,
.swap_buffers = dri3_swap_buffers,
.swap_buffers_with_damage = dri2_fallback_swap_buffers_with_damage,
.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)
{
dri3_query =
xcb_dri3_query_version_reply(dri2_dpy->conn, dri3_query_cookie, &error);
if (dri3_query == NULL || error != NULL) {
- _eglLog(_EGL_WARNING, "DRI2: failed to query dri3 version");
+ _eglLog(_EGL_WARNING, "DRI3: failed to query the version");
free(dri3_query);
free(error);
return EGL_FALSE;
xcb_present_query_version_reply(dri2_dpy->conn,
present_query_cookie, &error);
if (present_query == NULL || error != NULL) {
- _eglLog(_EGL_WARNING, "DRI2: failed to query Present version");
+ _eglLog(_EGL_WARNING, "DRI3: failed to query Present version");
free(present_query);
free(error);
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, "DRI2: Screen seem not DRI3 capable");
+ _eglLog(_EGL_WARNING, "DRI3: Screen seems not DRI3 capable");
if (conn_error)
- _eglLog(_EGL_WARNING, "DRI2: Failed to initialize DRI3");
+ _eglLog(_EGL_WARNING, "DRI3: Failed to initialize");
return EGL_FALSE;
}
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd, 0);
if (!dri2_dpy->driver_name) {
- _eglLog(_EGL_WARNING, "DRI2: No driver found");
+ _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;
}