backend: replace get_buffer_caps hook with a struct field

Do the same as wlr_renderer: the supported buffer capabilities are
static for the lifetime of the backend.
This commit is contained in:
Simon Ser 2024-10-29 19:18:18 +01:00 committed by Kirill Primak
parent 9fdffba170
commit b908d865b1
14 changed files with 44 additions and 87 deletions

View file

@ -12,7 +12,6 @@
#include <wlr/config.h> #include <wlr/config.h>
#include <wlr/render/wlr_renderer.h> #include <wlr/render/wlr_renderer.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "backend/backend.h"
#include "backend/multi.h" #include "backend/multi.h"
#include "types/wlr_output.h" #include "types/wlr_output.h"
#include "util/env.h" #include "util/env.h"
@ -120,14 +119,6 @@ int wlr_backend_get_drm_fd(struct wlr_backend *backend) {
return backend->impl->get_drm_fd(backend); return backend->impl->get_drm_fd(backend);
} }
uint32_t backend_get_buffer_caps(struct wlr_backend *backend) {
if (!backend->impl->get_buffer_caps) {
return 0;
}
return backend->impl->get_buffer_caps(backend);
}
static size_t parse_outputs_env(const char *name) { static size_t parse_outputs_env(const char *name) {
const char *outputs_str = getenv(name); const char *outputs_str = getenv(name);
if (outputs_str == NULL) { if (outputs_str == NULL) {

View file

@ -76,10 +76,6 @@ static int backend_get_drm_fd(struct wlr_backend *backend) {
return drm->fd; return drm->fd;
} }
static uint32_t backend_get_buffer_caps(struct wlr_backend *backend) {
return WLR_BUFFER_CAP_DMABUF;
}
static bool backend_test(struct wlr_backend *backend, static bool backend_test(struct wlr_backend *backend,
const struct wlr_backend_output_state *states, size_t states_len) { const struct wlr_backend_output_state *states, size_t states_len) {
struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend); struct wlr_drm_backend *drm = get_drm_backend_from_backend(backend);
@ -96,7 +92,6 @@ static const struct wlr_backend_impl backend_impl = {
.start = backend_start, .start = backend_start,
.destroy = backend_destroy, .destroy = backend_destroy,
.get_drm_fd = backend_get_drm_fd, .get_drm_fd = backend_get_drm_fd,
.get_buffer_caps = backend_get_buffer_caps,
.test = backend_test, .test = backend_test,
.commit = backend_commit, .commit = backend_commit,
}; };
@ -238,6 +233,8 @@ struct wlr_backend *wlr_drm_backend_create(struct wlr_session *session,
} }
wlr_backend_init(&drm->backend, &backend_impl); wlr_backend_init(&drm->backend, &backend_impl);
drm->backend.buffer_caps = WLR_BUFFER_CAP_DMABUF;
drm->session = session; drm->session = session;
wl_list_init(&drm->fbs); wl_list_init(&drm->fbs);
wl_list_init(&drm->connectors); wl_list_init(&drm->connectors);

View file

@ -8,7 +8,6 @@
#include "backend/drm/drm.h" #include "backend/drm/drm.h"
#include "backend/drm/fb.h" #include "backend/drm/fb.h"
#include "backend/drm/renderer.h" #include "backend/drm/renderer.h"
#include "backend/backend.h"
#include "render/drm_format_set.h" #include "render/drm_format_set.h"
#include "render/pixel_format.h" #include "render/pixel_format.h"
#include "render/wlr_renderer.h" #include "render/wlr_renderer.h"

View file

@ -45,16 +45,9 @@ static void backend_destroy(struct wlr_backend *wlr_backend) {
free(backend); free(backend);
} }
static uint32_t get_buffer_caps(struct wlr_backend *wlr_backend) {
return WLR_BUFFER_CAP_DATA_PTR
| WLR_BUFFER_CAP_DMABUF
| WLR_BUFFER_CAP_SHM;
}
static const struct wlr_backend_impl backend_impl = { static const struct wlr_backend_impl backend_impl = {
.start = backend_start, .start = backend_start,
.destroy = backend_destroy, .destroy = backend_destroy,
.get_buffer_caps = get_buffer_caps,
}; };
static void handle_event_loop_destroy(struct wl_listener *listener, void *data) { static void handle_event_loop_destroy(struct wl_listener *listener, void *data) {
@ -74,6 +67,9 @@ struct wlr_backend *wlr_headless_backend_create(struct wl_event_loop *loop) {
wlr_backend_init(&backend->backend, &backend_impl); wlr_backend_init(&backend->backend, &backend_impl);
backend->backend.buffer_caps =
WLR_BUFFER_CAP_DATA_PTR | WLR_BUFFER_CAP_DMABUF | WLR_BUFFER_CAP_SHM;
backend->event_loop = loop; backend->event_loop = loop;
wl_list_init(&backend->outputs); wl_list_init(&backend->outputs);

View file

@ -6,7 +6,6 @@
#include <wlr/types/wlr_buffer.h> #include <wlr/types/wlr_buffer.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include "backend/backend.h"
#include "backend/multi.h" #include "backend/multi.h"
struct subbackend_state { struct subbackend_state {
@ -76,28 +75,6 @@ static int multi_backend_get_drm_fd(struct wlr_backend *backend) {
return -1; return -1;
} }
static uint32_t multi_backend_get_buffer_caps(struct wlr_backend *backend) {
struct wlr_multi_backend *multi = multi_backend_from_backend(backend);
if (wl_list_empty(&multi->backends)) {
return 0;
}
uint32_t caps = WLR_BUFFER_CAP_DATA_PTR | WLR_BUFFER_CAP_DMABUF
| WLR_BUFFER_CAP_SHM;
struct subbackend_state *sub;
wl_list_for_each(sub, &multi->backends, link) {
uint32_t backend_caps = backend_get_buffer_caps(sub->backend);
if (backend_caps != 0) {
// only count backend capable of presenting a buffer
caps = caps & backend_caps;
}
}
return caps;
}
static int compare_output_state_backend(const void *data_a, const void *data_b) { static int compare_output_state_backend(const void *data_a, const void *data_b) {
const struct wlr_backend_output_state *a = data_a; const struct wlr_backend_output_state *a = data_a;
const struct wlr_backend_output_state *b = data_b; const struct wlr_backend_output_state *b = data_b;
@ -164,7 +141,6 @@ static const struct wlr_backend_impl backend_impl = {
.start = multi_backend_start, .start = multi_backend_start,
.destroy = multi_backend_destroy, .destroy = multi_backend_destroy,
.get_drm_fd = multi_backend_get_drm_fd, .get_drm_fd = multi_backend_get_drm_fd,
.get_buffer_caps = multi_backend_get_buffer_caps,
.test = multi_backend_test, .test = multi_backend_test,
.commit = multi_backend_commit, .commit = multi_backend_commit,
}; };
@ -228,16 +204,30 @@ static struct subbackend_state *multi_backend_get_subbackend(struct wlr_multi_ba
} }
static void multi_backend_refresh_features(struct wlr_multi_backend *multi) { static void multi_backend_refresh_features(struct wlr_multi_backend *multi) {
multi->backend.buffer_caps = 0;
multi->backend.features.timeline = true; multi->backend.features.timeline = true;
bool has_buffer_cap = false;
uint32_t buffer_caps_intersection =
WLR_BUFFER_CAP_DATA_PTR | WLR_BUFFER_CAP_DMABUF | WLR_BUFFER_CAP_SHM;
struct subbackend_state *sub = NULL; struct subbackend_state *sub = NULL;
wl_list_for_each(sub, &multi->backends, link) { wl_list_for_each(sub, &multi->backends, link) {
// Only take into account backends capable of presenting a buffer
if (sub->backend->buffer_caps != 0) {
has_buffer_cap = true;
buffer_caps_intersection &= sub->backend->buffer_caps;
}
// timeline is only applicable to backends that support DMABUFs // timeline is only applicable to backends that support DMABUFs
if (backend_get_buffer_caps(sub->backend) & WLR_BUFFER_CAP_DMABUF) { if (sub->backend->buffer_caps & WLR_BUFFER_CAP_DMABUF) {
multi->backend.features.timeline = multi->backend.features.timeline && multi->backend.features.timeline = multi->backend.features.timeline &&
sub->backend->features.timeline; sub->backend->features.timeline;
} }
} }
if (has_buffer_cap) {
multi->backend.buffer_caps = buffer_caps_intersection;
}
} }
bool wlr_multi_backend_add(struct wlr_backend *_multi, bool wlr_multi_backend_add(struct wlr_backend *_multi,

View file

@ -566,17 +566,10 @@ static int backend_get_drm_fd(struct wlr_backend *backend) {
return wl->drm_fd; return wl->drm_fd;
} }
static uint32_t get_buffer_caps(struct wlr_backend *backend) {
struct wlr_wl_backend *wl = get_wl_backend_from_backend(backend);
return (wl->zwp_linux_dmabuf_v1 ? WLR_BUFFER_CAP_DMABUF : 0)
| (wl->shm ? WLR_BUFFER_CAP_SHM : 0);
}
static const struct wlr_backend_impl backend_impl = { static const struct wlr_backend_impl backend_impl = {
.start = backend_start, .start = backend_start,
.destroy = backend_destroy, .destroy = backend_destroy,
.get_drm_fd = backend_get_drm_fd, .get_drm_fd = backend_get_drm_fd,
.get_buffer_caps = get_buffer_caps,
}; };
bool wlr_backend_is_wl(struct wlr_backend *b) { bool wlr_backend_is_wl(struct wlr_backend *b) {
@ -672,6 +665,13 @@ struct wlr_backend *wlr_wl_backend_create(struct wl_event_loop *loop,
zwp_linux_dmabuf_feedback_v1_destroy(linux_dmabuf_feedback_v1); zwp_linux_dmabuf_feedback_v1_destroy(linux_dmabuf_feedback_v1);
} }
if (wl->zwp_linux_dmabuf_v1) {
wl->backend.buffer_caps |= WLR_BUFFER_CAP_DMABUF;
}
if (wl->shm) {
wl->backend.buffer_caps |= WLR_BUFFER_CAP_SHM;
}
int fd = wl_display_get_fd(wl->remote_display); int fd = wl_display_get_fd(wl->remote_display);
wl->remote_display_src = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE, wl->remote_display_src = wl_event_loop_add_fd(loop, fd, WL_EVENT_READABLE,
dispatch_events, wl); dispatch_events, wl);

View file

@ -212,17 +212,10 @@ static int backend_get_drm_fd(struct wlr_backend *backend) {
return x11->drm_fd; return x11->drm_fd;
} }
static uint32_t get_buffer_caps(struct wlr_backend *backend) {
struct wlr_x11_backend *x11 = get_x11_backend_from_backend(backend);
return (x11->have_dri3 ? WLR_BUFFER_CAP_DMABUF : 0)
| (x11->have_shm ? WLR_BUFFER_CAP_SHM : 0);
}
static const struct wlr_backend_impl backend_impl = { static const struct wlr_backend_impl backend_impl = {
.start = backend_start, .start = backend_start,
.destroy = backend_destroy, .destroy = backend_destroy,
.get_drm_fd = backend_get_drm_fd, .get_drm_fd = backend_get_drm_fd,
.get_buffer_caps = get_buffer_caps,
}; };
bool wlr_backend_is_x11(struct wlr_backend *backend) { bool wlr_backend_is_x11(struct wlr_backend *backend) {
@ -573,6 +566,13 @@ struct wlr_backend *wlr_x11_backend_create(struct wl_event_loop *loop,
} }
free(xi_reply); free(xi_reply);
if (x11->have_dri3) {
x11->backend.buffer_caps |= WLR_BUFFER_CAP_DMABUF;
}
if (x11->have_shm) {
x11->backend.buffer_caps |= WLR_BUFFER_CAP_SHM;
}
int fd = xcb_get_file_descriptor(x11->xcb); int fd = xcb_get_file_descriptor(x11->xcb);
uint32_t events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP; uint32_t events = WL_EVENT_READABLE | WL_EVENT_ERROR | WL_EVENT_HANGUP;
x11->event_source = wl_event_loop_add_fd(loop, fd, events, x11_event, x11); x11->event_source = wl_event_loop_add_fd(loop, fd, events, x11_event, x11);

View file

@ -1,13 +0,0 @@
#ifndef BACKEND_WLR_BACKEND_H
#define BACKEND_WLR_BACKEND_H
#include <wlr/backend.h>
/**
* Get the supported buffer capabilities.
*
* This functions returns a bitfield of supported wlr_buffer_cap.
*/
uint32_t backend_get_buffer_caps(struct wlr_backend *backend);
#endif

View file

@ -29,6 +29,9 @@ struct wlr_backend_output_state {
struct wlr_backend { struct wlr_backend {
const struct wlr_backend_impl *impl; const struct wlr_backend_impl *impl;
// Bitfield of supported buffer capabilities (see enum wlr_buffer_cap)
uint32_t buffer_caps;
struct { struct {
// Whether wait/signal timelines are supported in output commits // Whether wait/signal timelines are supported in output commits
bool timeline; bool timeline;

View file

@ -18,7 +18,6 @@ struct wlr_backend_impl {
bool (*start)(struct wlr_backend *backend); bool (*start)(struct wlr_backend *backend);
void (*destroy)(struct wlr_backend *backend); void (*destroy)(struct wlr_backend *backend);
int (*get_drm_fd)(struct wlr_backend *backend); int (*get_drm_fd)(struct wlr_backend *backend);
uint32_t (*get_buffer_caps)(struct wlr_backend *backend);
bool (*test)(struct wlr_backend *backend, bool (*test)(struct wlr_backend *backend,
const struct wlr_backend_output_state *states, size_t states_len); const struct wlr_backend_output_state *states, size_t states_len);
bool (*commit)(struct wlr_backend *backend, bool (*commit)(struct wlr_backend *backend,

View file

@ -2,13 +2,13 @@
#include <fcntl.h> #include <fcntl.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <wlr/backend.h>
#include <wlr/config.h> #include <wlr/config.h>
#include <wlr/interfaces/wlr_buffer.h> #include <wlr/interfaces/wlr_buffer.h>
#include <wlr/render/allocator.h> #include <wlr/render/allocator.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include <xf86drm.h> #include <xf86drm.h>
#include <xf86drmMode.h> #include <xf86drmMode.h>
#include "backend/backend.h"
#include "render/allocator/drm_dumb.h" #include "render/allocator/drm_dumb.h"
#include "render/allocator/shm.h" #include "render/allocator/shm.h"
#include "render/wlr_renderer.h" #include "render/wlr_renderer.h"
@ -96,7 +96,7 @@ static int reopen_drm_node(int drm_fd, bool allow_render_node) {
struct wlr_allocator *wlr_allocator_autocreate(struct wlr_backend *backend, struct wlr_allocator *wlr_allocator_autocreate(struct wlr_backend *backend,
struct wlr_renderer *renderer) { struct wlr_renderer *renderer) {
uint32_t backend_caps = backend_get_buffer_caps(backend); uint32_t backend_caps = backend->buffer_caps;
uint32_t renderer_caps = renderer->render_buffer_caps; uint32_t renderer_caps = renderer->render_buffer_caps;
// Note, drm_fd may be negative if unavailable // Note, drm_fd may be negative if unavailable

View file

@ -3,6 +3,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <wlr/backend.h>
#include <wlr/render/interface.h> #include <wlr/render/interface.h>
#include <wlr/render/pixman.h> #include <wlr/render/pixman.h>
#include <wlr/render/wlr_renderer.h> #include <wlr/render/wlr_renderer.h>
@ -24,7 +25,6 @@
#include <wlr/render/vulkan.h> #include <wlr/render/vulkan.h>
#endif // WLR_HAS_VULKAN_RENDERER #endif // WLR_HAS_VULKAN_RENDERER
#include "backend/backend.h"
#include "render/pixel_format.h" #include "render/pixel_format.h"
#include "render/wlr_renderer.h" #include "render/wlr_renderer.h"
#include "util/env.h" #include "util/env.h"
@ -180,8 +180,7 @@ static bool open_preferred_drm_fd(struct wlr_backend *backend, int *drm_fd_ptr,
// If the backend hasn't picked a DRM FD, but accepts DMA-BUFs, pick an // If the backend hasn't picked a DRM FD, but accepts DMA-BUFs, pick an
// arbitrary render node // arbitrary render node
uint32_t backend_caps = backend_get_buffer_caps(backend); if (backend->buffer_caps & WLR_BUFFER_CAP_DMABUF) {
if (backend_caps & WLR_BUFFER_CAP_DMABUF) {
int drm_fd = open_drm_render_node(); int drm_fd = open_drm_render_node();
if (drm_fd < 0) { if (drm_fd < 0) {
return false; return false;

View file

@ -1,7 +1,7 @@
#include <assert.h> #include <assert.h>
#include <backend/backend.h>
#include <drm_fourcc.h> #include <drm_fourcc.h>
#include <stdlib.h> #include <stdlib.h>
#include <wlr/backend.h>
#include <wlr/interfaces/wlr_output.h> #include <wlr/interfaces/wlr_output.h>
#include <wlr/render/allocator.h> #include <wlr/render/allocator.h>
#include <wlr/render/swapchain.h> #include <wlr/render/swapchain.h>

View file

@ -7,7 +7,6 @@
#include <wlr/render/swapchain.h> #include <wlr/render/swapchain.h>
#include <wlr/util/log.h> #include <wlr/util/log.h>
#include <xf86drm.h> #include <xf86drm.h>
#include "backend/backend.h"
#include "render/drm_format_set.h" #include "render/drm_format_set.h"
#include "render/wlr_renderer.h" #include "render/wlr_renderer.h"
#include "render/pixel_format.h" #include "render/pixel_format.h"
@ -17,14 +16,11 @@ bool wlr_output_init_render(struct wlr_output *output,
struct wlr_allocator *allocator, struct wlr_renderer *renderer) { struct wlr_allocator *allocator, struct wlr_renderer *renderer) {
assert(allocator != NULL && renderer != NULL); assert(allocator != NULL && renderer != NULL);
uint32_t backend_caps = backend_get_buffer_caps(output->backend); if (!(output->backend->buffer_caps & allocator->buffer_caps)) {
uint32_t renderer_caps = renderer->render_buffer_caps;
if (!(backend_caps & allocator->buffer_caps)) {
wlr_log(WLR_ERROR, "output backend and allocator buffer capabilities " wlr_log(WLR_ERROR, "output backend and allocator buffer capabilities "
"don't match"); "don't match");
return false; return false;
} else if (!(renderer_caps & allocator->buffer_caps)) { } else if (!(renderer->render_buffer_caps & allocator->buffer_caps)) {
wlr_log(WLR_ERROR, "renderer and allocator buffer capabilities " wlr_log(WLR_ERROR, "renderer and allocator buffer capabilities "
"don't match"); "don't match");
return false; return false;