diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 00dfcbb0..6492ff40 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -14,7 +14,7 @@ #include "backend/drm/drm.h" #include "backend/drm/util.h" #include "render/drm_format_set.h" -#include "render/gbm_allocator.h" +#include "render/allocator.h" #include "render/pixel_format.h" #include "render/swapchain.h" #include "render/wlr_renderer.h" @@ -35,16 +35,10 @@ bool init_drm_renderer(struct wlr_drm_backend *drm, goto error_gbm; } - int alloc_fd = fcntl(drm->fd, F_DUPFD_CLOEXEC, 0); - if (alloc_fd < 0) { - wlr_log_errno(WLR_ERROR, "fcntl(F_DUPFD_CLOEXEC) failed"); - goto error_wlr_rend; - } - - renderer->allocator = wlr_gbm_allocator_create(alloc_fd); + renderer->allocator = wlr_allocator_autocreate(&drm->backend, + renderer->wlr_rend); if (renderer->allocator == NULL) { wlr_log(WLR_ERROR, "Failed to create allocator"); - close(alloc_fd); goto error_wlr_rend; } diff --git a/backend/headless/backend.c b/backend/headless/backend.c index 7f1e6aa4..be44a980 100644 --- a/backend/headless/backend.c +++ b/backend/headless/backend.c @@ -120,15 +120,12 @@ static void handle_renderer_destroy(struct wl_listener *listener, void *data) { } static bool backend_init(struct wlr_headless_backend *backend, - struct wl_display *display, struct wlr_allocator *allocator, - struct wlr_renderer *renderer) { + struct wl_display *display, struct wlr_renderer *renderer) { wlr_backend_init(&backend->backend, &backend_impl); backend->display = display; wl_list_init(&backend->outputs); wl_list_init(&backend->input_devices); - backend->allocator = allocator; - if (renderer == NULL) { renderer = wlr_renderer_autocreate(&backend->backend); if (!renderer) { @@ -138,6 +135,12 @@ static bool backend_init(struct wlr_headless_backend *backend, } backend->renderer = renderer; + backend->allocator = wlr_allocator_autocreate(&backend->backend, renderer); + if (!backend->allocator) { + wlr_log(WLR_ERROR, "Failed to create allocator"); + return false; + } + const struct wlr_drm_format_set *formats = wlr_renderer_get_render_formats(backend->renderer); if (formats == NULL) { @@ -219,33 +222,16 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_display *display) { backend->drm_fd = open_drm_render_node(); if (backend->drm_fd < 0) { wlr_log(WLR_ERROR, "Failed to open DRM render node"); - goto error_drm_fd; } - int drm_fd = fcntl(backend->drm_fd, F_DUPFD_CLOEXEC, 0); - if (drm_fd < 0) { - wlr_log_errno(WLR_ERROR, "fcntl(F_DUPFD_CLOEXEC) failed"); - goto error_dup; - } - - struct wlr_allocator *alloc = wlr_gbm_allocator_create(drm_fd); - if (alloc == NULL) { - wlr_log(WLR_ERROR, "Failed to create GBM allocator"); - close(drm_fd); - goto error_dup; - } - - if (!backend_init(backend, display, alloc, NULL)) { + if (!backend_init(backend, display, NULL)) { goto error_init; } return &backend->backend; error_init: - wlr_allocator_destroy(alloc); -error_dup: close(backend->drm_fd); -error_drm_fd: free(backend); return NULL; } @@ -265,23 +251,9 @@ struct wlr_backend *wlr_headless_backend_create_with_renderer( backend->drm_fd = wlr_renderer_get_drm_fd(renderer); if (backend->drm_fd < 0) { wlr_log(WLR_ERROR, "Failed to get DRM device FD from renderer"); - goto error_drm_fd; } - int drm_fd = fcntl(backend->drm_fd, F_DUPFD_CLOEXEC, 0); - if (drm_fd < 0) { - wlr_log_errno(WLR_ERROR, "fcntl(F_DUPFD_CLOEXEC) failed"); - goto error_dup; - } - - struct wlr_allocator *alloc = wlr_gbm_allocator_create(drm_fd); - if (alloc == NULL) { - wlr_log(WLR_ERROR, "Failed to create GBM allocator"); - close(drm_fd); - goto error_dup; - } - - if (!backend_init(backend, display, alloc, renderer)) { + if (!backend_init(backend, display, renderer)) { goto error_init; } @@ -291,10 +263,7 @@ struct wlr_backend *wlr_headless_backend_create_with_renderer( return &backend->backend; error_init: - wlr_allocator_destroy(alloc); -error_dup: close(backend->drm_fd); -error_drm_fd: free(backend); return NULL; } diff --git a/backend/wayland/backend.c b/backend/wayland/backend.c index f0cb2e42..e05a13a0 100644 --- a/backend/wayland/backend.c +++ b/backend/wayland/backend.c @@ -444,7 +444,6 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display, } wl_event_source_check(wl->remote_display_src); - wl->drm_fd = -1; if (wl->drm_render_name != NULL) { wlr_log(WLR_DEBUG, "Opening DRM render node %s", wl->drm_render_name); wl->drm_fd = open(wl->drm_render_name, O_RDWR | O_NONBLOCK | O_CLOEXEC); @@ -453,45 +452,40 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display, wl->drm_render_name); goto error_remote_display_src; } - - int drm_fd = fcntl(wl->drm_fd, F_DUPFD_CLOEXEC, 0); - if (drm_fd < 0) { - wlr_log(WLR_ERROR, "fcntl(F_DUPFD_CLOEXEC) failed"); - goto error_drm_fd; - } - - wl->allocator = wlr_gbm_allocator_create(drm_fd); - if (wl->allocator == NULL) { - wlr_log(WLR_ERROR, "Failed to create GBM allocator"); - close(drm_fd); - goto error_drm_fd; - } } else { - wlr_log(WLR_DEBUG, "No render node found, falling back to shared memory"); - wl->allocator = wlr_shm_allocator_create(); - if (wl->allocator == NULL) { - wlr_log(WLR_ERROR, "Failed to create shared memory allocator"); - goto error_remote_display_src; - } + wl->drm_fd = -1; } wl->renderer = wlr_renderer_autocreate(&wl->backend); if (wl->renderer == NULL) { wlr_log(WLR_ERROR, "Failed to create renderer"); + goto error_renderer; + } + + uint32_t caps = renderer_get_render_buffer_caps(wl->renderer); + + wl->allocator = wlr_allocator_autocreate(&wl->backend, wl->renderer); + if (wl->allocator == NULL) { + wlr_log(WLR_ERROR, "Failed to create allocator"); goto error_allocator; } const struct wlr_drm_format_set *remote_formats; - if (wl->drm_fd >= 0) { + if ((caps & WLR_BUFFER_CAP_DMABUF) && wl->zwp_linux_dmabuf_v1) { remote_formats = &wl->linux_dmabuf_v1_formats; - } else { + } else if ((caps & WLR_BUFFER_CAP_DATA_PTR) && wl->shm) { remote_formats = &wl->shm_formats; + } else { + wlr_log(WLR_ERROR, + "Failed to get remote formats (DRI3 and SHM unavailable)"); + goto error_allocator; } + const struct wlr_drm_format_set *render_formats = wlr_renderer_get_render_formats(wl->renderer); if (render_formats == NULL) { wlr_log(WLR_ERROR, "Failed to get available render-capable formats"); - goto error_renderer; + goto error_allocator; } uint32_t fmt = DRM_FORMAT_ARGB8888; @@ -501,21 +495,21 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display, if (remote_format == NULL) { wlr_log(WLR_ERROR, "Remote compositor doesn't support DRM format " "0x%"PRIX32, fmt); - goto error_renderer; + goto error_allocator; } const struct wlr_drm_format *render_format = wlr_drm_format_set_get(render_formats, fmt); if (render_format == NULL) { wlr_log(WLR_ERROR, "Renderer doesn't support DRM format 0x%"PRIX32, fmt); - goto error_renderer; + goto error_allocator; } wl->format = wlr_drm_format_intersect(remote_format, render_format); if (wl->format == NULL) { wlr_log(WLR_ERROR, "Failed to intersect remote and render modifiers " "for format 0x%"PRIX32, fmt); - goto error_renderer; + goto error_allocator; } wl->local_display_destroy.notify = handle_display_destroy; @@ -523,11 +517,10 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_display *display, return &wl->backend; -error_renderer: - wlr_renderer_destroy(wl->renderer); error_allocator: wlr_allocator_destroy(wl->allocator); -error_drm_fd: +error_renderer: + wlr_renderer_destroy(wl->renderer); close(wl->drm_fd); error_remote_display_src: wl_event_source_remove(wl->remote_display_src); diff --git a/backend/x11/backend.c b/backend/x11/backend.c index 9ffdfb2d..8999912d 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -610,7 +610,7 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, return false; } - const struct wlr_drm_format_set *pixmap_formats; + x11->drm_fd = -1; if (x11->have_dri3) { // DRI3 may return a render node (Xwayland) or an authenticated primary // node (plain Glamor). @@ -619,36 +619,6 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, wlr_log(WLR_ERROR, "Failed to query DRI3 DRM FD"); goto error_event; } - - char *drm_name = drmGetDeviceNameFromFd2(x11->drm_fd); - wlr_log(WLR_DEBUG, "Using DRM node %s", drm_name); - free(drm_name); - - int drm_fd = fcntl(x11->drm_fd, F_DUPFD_CLOEXEC, 0); - if (drm_fd < 0) { - wlr_log(WLR_ERROR, "fcntl(F_DUPFD_CLOEXEC) failed"); - goto error_event; - } - - x11->allocator = wlr_gbm_allocator_create(drm_fd); - if (x11->allocator == NULL) { - wlr_log(WLR_ERROR, "Failed to create GBM allocator"); - close(drm_fd); - goto error_event; - } - pixmap_formats = &x11->dri3_formats; - } else if (x11->have_shm) { - x11->drm_fd = -1; - x11->allocator = wlr_shm_allocator_create(); - if (x11->allocator == NULL) { - wlr_log(WLR_ERROR, "Failed to create shared memory allocator"); - goto error_event; - } - pixmap_formats = &x11->shm_formats; - } else { - wlr_log(WLR_ERROR, - "Failed to create allocator (DRI3 and SHM unavailable)"); - goto error_event; } x11->renderer = wlr_renderer_autocreate(&x11->backend); @@ -657,6 +627,25 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_display *display, goto error_event; } + uint32_t caps = renderer_get_render_buffer_caps(x11->renderer); + + const struct wlr_drm_format_set *pixmap_formats; + if (x11->have_dri3 && (caps & WLR_BUFFER_CAP_DMABUF)) { + pixmap_formats = &x11->dri3_formats; + } else if (x11->have_shm && (caps & WLR_BUFFER_CAP_DATA_PTR)) { + pixmap_formats = &x11->shm_formats; + } else { + wlr_log(WLR_ERROR, + "Failed to create allocator (DRI3 and SHM unavailable)"); + goto error_event; + } + + x11->allocator = wlr_allocator_autocreate(&x11->backend, x11->renderer); + if (x11->allocator == NULL) { + wlr_log(WLR_ERROR, "Failed to create allocator"); + goto error_event; + } + const struct wlr_drm_format_set *render_formats = wlr_renderer_get_render_formats(x11->renderer); if (render_formats == NULL) {