aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/x11/backend.c94
1 files changed, 57 insertions, 37 deletions
diff --git a/backend/x11/backend.c b/backend/x11/backend.c
index 6e79129f..6067c89f 100644
--- a/backend/x11/backend.c
+++ b/backend/x11/backend.c
@@ -180,8 +180,9 @@ static void backend_destroy(struct wlr_backend *backend) {
wl_list_remove(&x11->display_destroy.link);
wlr_renderer_destroy(x11->renderer);
- wlr_drm_format_set_finish(&x11->dri3_formats);
wlr_egl_finish(&x11->egl);
+ wlr_allocator_destroy(x11->allocator);
+ wlr_drm_format_set_finish(&x11->dri3_formats);
free(x11->drm_format);
#if WLR_HAS_XCB_ERRORS
@@ -237,6 +238,39 @@ static xcb_visualid_t pick_visualid(xcb_depth_t *depth) {
return 0;
}
+static int query_dri3_drm_fd(struct wlr_x11_backend *x11) {
+ xcb_dri3_open_cookie_t open_cookie =
+ xcb_dri3_open(x11->xcb, x11->screen->root, 0);
+ xcb_dri3_open_reply_t *open_reply =
+ xcb_dri3_open_reply(x11->xcb, open_cookie, NULL);
+ if (open_reply == NULL) {
+ return -1;
+ }
+
+ int *open_fds = xcb_dri3_open_reply_fds(x11->xcb, open_reply);
+ if (open_fds == NULL) {
+ free(open_reply);
+ return -1;
+ }
+
+ assert(open_reply->nfd == 1);
+ int drm_fd = open_fds[0];
+
+ free(open_reply);
+
+ int flags = fcntl(drm_fd, F_GETFD);
+ if (flags < 0) {
+ close(drm_fd);
+ return -1;
+ }
+ if (fcntl(drm_fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
+ close(drm_fd);
+ return -1;
+ }
+
+ return drm_fd;
+}
+
static bool query_dri3_modifiers(struct wlr_x11_backend *x11,
const struct wlr_x11_format *format) {
// Query the root window's supported modifiers, because we only care about
@@ -437,71 +471,57 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display,
x11->screen = xcb_setup_roots_iterator(xcb_get_setup(x11->xcb)).data;
if (!x11->screen) {
wlr_log(WLR_ERROR, "Failed to get X11 screen");
- goto error_display;
+ goto error_event;
}
x11->depth = get_depth(x11->screen, 32);
if (!x11->depth) {
wlr_log(WLR_ERROR, "Failed to get 32-bit depth for X11 screen");
- goto error_display;
+ goto error_event;
}
x11->visualid = pick_visualid(x11->depth);
if (!x11->visualid) {
wlr_log(WLR_ERROR, "Failed to pick X11 visual");
- goto error_display;
+ goto error_event;
}
x11->x11_format = x11_format_from_depth(x11->depth->depth);
if (!x11->x11_format) {
wlr_log(WLR_ERROR, "Unsupported depth %"PRIu8, x11->depth->depth);
- goto error_display;
+ goto error_event;
}
x11->colormap = xcb_generate_id(x11->xcb);
xcb_create_colormap(x11->xcb, XCB_COLORMAP_ALLOC_NONE, x11->colormap,
x11->screen->root, x11->visualid);
- if (!create_renderer_func) {
- create_renderer_func = wlr_renderer_autocreate;
- }
-
- static EGLint config_attribs[] = {
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_RED_SIZE, 1,
- EGL_GREEN_SIZE, 1,
- EGL_BLUE_SIZE, 1,
- EGL_ALPHA_SIZE, 1,
- EGL_NONE,
- };
-
- x11->renderer = create_renderer_func(&x11->egl, EGL_PLATFORM_X11_KHR,
- x11->xlib_conn, config_attribs, x11->screen->root_visual);
- if (x11->renderer == NULL) {
- wlr_log(WLR_ERROR, "Failed to create renderer");
+ // DRI3 may return a render node (Xwayland) or an authenticated primary
+ // node (plain Glamor).
+ int drm_fd = query_dri3_drm_fd(x11);
+ if (drm_fd < 0) {
+ wlr_log(WLR_ERROR, "Failed to query DRI3 DRM FD");
goto error_event;
}
- // TODO: we can use DRI3Open instead
- int drm_fd = wlr_renderer_get_drm_fd(x11->renderer);
- if (fd < 0) {
- wlr_log(WLR_ERROR, "Failed to get DRM device FD from renderer");
- return false;
+ struct wlr_gbm_allocator *gbm_alloc = wlr_gbm_allocator_create(drm_fd);
+ if (gbm_alloc == NULL) {
+ wlr_log(WLR_ERROR, "Failed to create GBM allocator");
+ close(drm_fd);
+ goto error_event;
}
+ x11->allocator = &gbm_alloc->base;
- drm_fd = fcntl(drm_fd, F_DUPFD_CLOEXEC, 0);
- if (drm_fd < 0) {
- wlr_log_errno(WLR_ERROR, "fcntl(F_DUPFD_CLOEXEC) failed");
- return false;
+ if (!create_renderer_func) {
+ create_renderer_func = wlr_renderer_autocreate;
}
- struct wlr_gbm_allocator *alloc = wlr_gbm_allocator_create(drm_fd);
- if (alloc == NULL) {
- wlr_log(WLR_ERROR, "Failed to create GBM allocator");
- return false;
+ x11->renderer = create_renderer_func(&x11->egl, EGL_PLATFORM_GBM_KHR,
+ gbm_alloc->gbm_device, NULL, 0);
+ if (x11->renderer == NULL) {
+ wlr_log(WLR_ERROR, "Failed to create renderer");
+ goto error_event;
}
- x11->allocator = &alloc->base;
const struct wlr_drm_format_set *render_formats =
wlr_renderer_get_dmabuf_render_formats(x11->renderer);