backend/session: operate on wlr_device
Instead of operating on FDs in {open,close}_device, operate on wlr_devices. This avoids the device lookup in wlr_session and allows callers to have access to wlr_device fields. For now, we use it to remove wlr_session_signal_add and replace it with a more idiomatic wlr_session.events.change field. In the future, other events will be added.
This commit is contained in:
parent
63df2bcbe6
commit
44a4792fd8
|
@ -151,7 +151,7 @@ static struct wlr_backend *attempt_noop_backend(struct wl_display *display) {
|
||||||
static struct wlr_backend *attempt_drm_backend(struct wl_display *display,
|
static struct wlr_backend *attempt_drm_backend(struct wl_display *display,
|
||||||
struct wlr_backend *backend, struct wlr_session *session,
|
struct wlr_backend *backend, struct wlr_session *session,
|
||||||
wlr_renderer_create_func_t create_renderer_func) {
|
wlr_renderer_create_func_t create_renderer_func) {
|
||||||
int gpus[8];
|
struct wlr_device *gpus[8];
|
||||||
size_t num_gpus = wlr_session_find_gpus(session, 8, gpus);
|
size_t num_gpus = wlr_session_find_gpus(session, 8, gpus);
|
||||||
struct wlr_backend *primary_drm = NULL;
|
struct wlr_backend *primary_drm = NULL;
|
||||||
wlr_log(WLR_INFO, "Found %zu GPUs", num_gpus);
|
wlr_log(WLR_INFO, "Found %zu GPUs", num_gpus);
|
||||||
|
@ -160,7 +160,7 @@ static struct wlr_backend *attempt_drm_backend(struct wl_display *display,
|
||||||
struct wlr_backend *drm = wlr_drm_backend_create(display, session,
|
struct wlr_backend *drm = wlr_drm_backend_create(display, session,
|
||||||
gpus[i], primary_drm, create_renderer_func);
|
gpus[i], primary_drm, create_renderer_func);
|
||||||
if (!drm) {
|
if (!drm) {
|
||||||
wlr_log(WLR_ERROR, "Failed to open DRM device %d", gpus[i]);
|
wlr_log(WLR_ERROR, "Failed to create DRM backend");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ static void backend_destroy(struct wlr_backend *backend) {
|
||||||
|
|
||||||
finish_drm_resources(drm);
|
finish_drm_resources(drm);
|
||||||
finish_drm_renderer(&drm->renderer);
|
finish_drm_renderer(&drm->renderer);
|
||||||
wlr_session_close_file(drm->session, drm->fd);
|
wlr_session_close_file(drm->session, drm->dev);
|
||||||
wl_event_source_remove(drm->drm_event);
|
wl_event_source_remove(drm->drm_event);
|
||||||
free(drm);
|
free(drm);
|
||||||
}
|
}
|
||||||
|
@ -128,13 +128,14 @@ static void handle_display_destroy(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
||||||
struct wlr_session *session, int gpu_fd, struct wlr_backend *parent,
|
struct wlr_session *session, struct wlr_device *dev,
|
||||||
|
struct wlr_backend *parent,
|
||||||
wlr_renderer_create_func_t create_renderer_func) {
|
wlr_renderer_create_func_t create_renderer_func) {
|
||||||
assert(display && session && gpu_fd >= 0);
|
assert(display && session && dev);
|
||||||
assert(!parent || wlr_backend_is_drm(parent));
|
assert(!parent || wlr_backend_is_drm(parent));
|
||||||
|
|
||||||
char *name = drmGetDeviceNameFromFd2(gpu_fd);
|
char *name = drmGetDeviceNameFromFd2(dev->fd);
|
||||||
drmVersion *version = drmGetVersion(gpu_fd);
|
drmVersion *version = drmGetVersion(dev->fd);
|
||||||
wlr_log(WLR_INFO, "Initializing DRM backend for %s (%s)", name, version->name);
|
wlr_log(WLR_INFO, "Initializing DRM backend for %s (%s)", name, version->name);
|
||||||
free(name);
|
free(name);
|
||||||
drmFreeVersion(version);
|
drmFreeVersion(version);
|
||||||
|
@ -149,13 +150,14 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
||||||
drm->session = session;
|
drm->session = session;
|
||||||
wl_list_init(&drm->outputs);
|
wl_list_init(&drm->outputs);
|
||||||
|
|
||||||
drm->fd = gpu_fd;
|
drm->dev = dev;
|
||||||
|
drm->fd = dev->fd;
|
||||||
if (parent != NULL) {
|
if (parent != NULL) {
|
||||||
drm->parent = get_drm_backend_from_backend(parent);
|
drm->parent = get_drm_backend_from_backend(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
drm->drm_invalidated.notify = drm_invalidated;
|
drm->drm_invalidated.notify = drm_invalidated;
|
||||||
wlr_session_signal_add(session, gpu_fd, &drm->drm_invalidated);
|
wl_signal_add(&dev->events.change, &drm->drm_invalidated);
|
||||||
|
|
||||||
drm->display = display;
|
drm->display = display;
|
||||||
struct wl_event_loop *event_loop = wl_display_get_event_loop(display);
|
struct wl_event_loop *event_loop = wl_display_get_event_loop(display);
|
||||||
|
@ -195,7 +197,7 @@ error_event:
|
||||||
wl_list_remove(&drm->session_signal.link);
|
wl_list_remove(&drm->session_signal.link);
|
||||||
wl_event_source_remove(drm->drm_event);
|
wl_event_source_remove(drm->drm_event);
|
||||||
error_fd:
|
error_fd:
|
||||||
wlr_session_close_file(drm->session, drm->fd);
|
wlr_session_close_file(drm->session, dev);
|
||||||
free(drm);
|
free(drm);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,12 +17,27 @@ static struct wlr_libinput_backend *get_libinput_backend_from_backend(
|
||||||
static int libinput_open_restricted(const char *path,
|
static int libinput_open_restricted(const char *path,
|
||||||
int flags, void *_backend) {
|
int flags, void *_backend) {
|
||||||
struct wlr_libinput_backend *backend = _backend;
|
struct wlr_libinput_backend *backend = _backend;
|
||||||
return wlr_session_open_file(backend->session, path);
|
struct wlr_device *dev = wlr_session_open_file(backend->session, path);
|
||||||
|
if (dev == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return dev->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void libinput_close_restricted(int fd, void *_backend) {
|
static void libinput_close_restricted(int fd, void *_backend) {
|
||||||
struct wlr_libinput_backend *backend = _backend;
|
struct wlr_libinput_backend *backend = _backend;
|
||||||
wlr_session_close_file(backend->session, fd);
|
|
||||||
|
struct wlr_device *dev;
|
||||||
|
bool found = false;
|
||||||
|
wl_list_for_each(dev, &backend->session->devices, link) {
|
||||||
|
if (dev->fd == fd) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
wlr_session_close_file(backend->session, dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct libinput_interface libinput_impl = {
|
static const struct libinput_interface libinput_impl = {
|
||||||
|
|
|
@ -55,7 +55,7 @@ static int udev_event(int fd, uint32_t mask, void *data) {
|
||||||
|
|
||||||
wl_list_for_each(dev, &session->devices, link) {
|
wl_list_for_each(dev, &session->devices, link) {
|
||||||
if (dev->dev == devnum) {
|
if (dev->dev == devnum) {
|
||||||
wlr_signal_emit_safe(&dev->signal, session);
|
wlr_signal_emit_safe(&dev->events.change, NULL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,10 +169,11 @@ void wlr_session_destroy(struct wlr_session *session) {
|
||||||
session->impl->destroy(session);
|
session->impl->destroy(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wlr_session_open_file(struct wlr_session *session, const char *path) {
|
struct wlr_device *wlr_session_open_file(struct wlr_session *session,
|
||||||
|
const char *path) {
|
||||||
int fd = session->impl->open(session, path);
|
int fd = session->impl->open(session, path);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
return fd;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_device *dev = malloc(sizeof(*dev));
|
struct wlr_device *dev = malloc(sizeof(*dev));
|
||||||
|
@ -189,46 +190,24 @@ int wlr_session_open_file(struct wlr_session *session, const char *path) {
|
||||||
|
|
||||||
dev->fd = fd;
|
dev->fd = fd;
|
||||||
dev->dev = st.st_rdev;
|
dev->dev = st.st_rdev;
|
||||||
wl_signal_init(&dev->signal);
|
wl_signal_init(&dev->events.change);
|
||||||
wl_list_insert(&session->devices, &dev->link);
|
wl_list_insert(&session->devices, &dev->link);
|
||||||
|
|
||||||
return fd;
|
return dev;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
free(dev);
|
free(dev);
|
||||||
close(fd);
|
close(fd);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct wlr_device *find_device(struct wlr_session *session, int fd) {
|
|
||||||
struct wlr_device *dev;
|
|
||||||
|
|
||||||
wl_list_for_each(dev, &session->devices, link) {
|
|
||||||
if (dev->fd == fd) {
|
|
||||||
return dev;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wlr_log(WLR_ERROR, "Tried to use fd %d not opened by session", fd);
|
|
||||||
assert(0);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_session_close_file(struct wlr_session *session, int fd) {
|
void wlr_session_close_file(struct wlr_session *session,
|
||||||
struct wlr_device *dev = find_device(session, fd);
|
struct wlr_device *dev) {
|
||||||
|
session->impl->close(session, dev->fd);
|
||||||
session->impl->close(session, fd);
|
|
||||||
wl_list_remove(&dev->link);
|
wl_list_remove(&dev->link);
|
||||||
free(dev);
|
free(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void wlr_session_signal_add(struct wlr_session *session, int fd,
|
|
||||||
struct wl_listener *listener) {
|
|
||||||
struct wlr_device *dev = find_device(session, fd);
|
|
||||||
|
|
||||||
wl_signal_add(&dev->signal, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wlr_session_change_vt(struct wlr_session *session, unsigned vt) {
|
bool wlr_session_change_vt(struct wlr_session *session, unsigned vt) {
|
||||||
if (!session) {
|
if (!session) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -240,32 +219,32 @@ bool wlr_session_change_vt(struct wlr_session *session, unsigned vt) {
|
||||||
/* Tests if 'path' is KMS compatible by trying to open it.
|
/* Tests if 'path' is KMS compatible by trying to open it.
|
||||||
* It leaves the open device in *fd_out it it succeeds.
|
* It leaves the open device in *fd_out it it succeeds.
|
||||||
*/
|
*/
|
||||||
static int open_if_kms(struct wlr_session *restrict session,
|
static struct wlr_device *open_if_kms(struct wlr_session *restrict session,
|
||||||
const char *restrict path) {
|
const char *restrict path) {
|
||||||
if (!path) {
|
if (!path) {
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = wlr_session_open_file(session, path);
|
struct wlr_device *dev = wlr_session_open_file(session, path);
|
||||||
if (fd < 0) {
|
if (!dev) {
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
drmVersion *ver = drmGetVersion(fd);
|
drmVersion *ver = drmGetVersion(dev->fd);
|
||||||
if (!ver) {
|
if (!ver) {
|
||||||
goto out_fd;
|
goto out_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
drmFreeVersion(ver);
|
drmFreeVersion(ver);
|
||||||
return fd;
|
return dev;
|
||||||
|
|
||||||
out_fd:
|
out_dev:
|
||||||
wlr_session_close_file(session, fd);
|
wlr_session_close_file(session, dev);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t explicit_find_gpus(struct wlr_session *session,
|
static size_t explicit_find_gpus(struct wlr_session *session,
|
||||||
size_t ret_len, int ret[static ret_len], const char *str) {
|
size_t ret_len, struct wlr_device *ret[static ret_len], const char *str) {
|
||||||
char *gpus = strdup(str);
|
char *gpus = strdup(str);
|
||||||
if (!gpus) {
|
if (!gpus) {
|
||||||
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
wlr_log_errno(WLR_ERROR, "Allocation failed");
|
||||||
|
@ -281,7 +260,7 @@ static size_t explicit_find_gpus(struct wlr_session *session,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret[i] = open_if_kms(session, ptr);
|
ret[i] = open_if_kms(session, ptr);
|
||||||
if (ret[i] < 0) {
|
if (!ret[i]) {
|
||||||
wlr_log(WLR_ERROR, "Unable to open %s as DRM device", ptr);
|
wlr_log(WLR_ERROR, "Unable to open %s as DRM device", ptr);
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
|
@ -296,7 +275,7 @@ static size_t explicit_find_gpus(struct wlr_session *session,
|
||||||
* If it's not found, it returns the first valid GPU it finds.
|
* If it's not found, it returns the first valid GPU it finds.
|
||||||
*/
|
*/
|
||||||
size_t wlr_session_find_gpus(struct wlr_session *session,
|
size_t wlr_session_find_gpus(struct wlr_session *session,
|
||||||
size_t ret_len, int *ret) {
|
size_t ret_len, struct wlr_device **ret) {
|
||||||
const char *explicit = getenv("WLR_DRM_DEVICES");
|
const char *explicit = getenv("WLR_DRM_DEVICES");
|
||||||
if (explicit) {
|
if (explicit) {
|
||||||
return explicit_find_gpus(session, ret_len, ret, explicit);
|
return explicit_find_gpus(session, ret_len, ret, explicit);
|
||||||
|
@ -348,17 +327,18 @@ size_t wlr_session_find_gpus(struct wlr_session *session,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = open_if_kms(session, udev_device_get_devnode(dev));
|
struct wlr_device *wlr_dev =
|
||||||
if (fd < 0) {
|
open_if_kms(session, udev_device_get_devnode(dev));
|
||||||
|
if (!wlr_dev) {
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
udev_device_unref(dev);
|
udev_device_unref(dev);
|
||||||
|
|
||||||
ret[i] = fd;
|
ret[i] = wlr_dev;
|
||||||
if (is_boot_vga) {
|
if (is_boot_vga) {
|
||||||
int tmp = ret[0];
|
struct wlr_device *tmp = ret[0];
|
||||||
ret[0] = ret[i];
|
ret[0] = ret[i];
|
||||||
ret[i] = tmp;
|
ret[i] = tmp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,7 @@ struct wlr_drm_backend {
|
||||||
bool addfb2_modifiers;
|
bool addfb2_modifiers;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
|
struct wlr_device *dev;
|
||||||
|
|
||||||
size_t num_crtcs;
|
size_t num_crtcs;
|
||||||
struct wlr_drm_crtc *crtcs;
|
struct wlr_drm_crtc *crtcs;
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
* a DRM backend, other kinds of backends raise SIGABRT).
|
* a DRM backend, other kinds of backends raise SIGABRT).
|
||||||
*/
|
*/
|
||||||
struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
struct wlr_backend *wlr_drm_backend_create(struct wl_display *display,
|
||||||
struct wlr_session *session, int gpu_fd, struct wlr_backend *parent,
|
struct wlr_session *session, struct wlr_device *dev,
|
||||||
|
struct wlr_backend *parent,
|
||||||
wlr_renderer_create_func_t create_renderer_func);
|
wlr_renderer_create_func_t create_renderer_func);
|
||||||
|
|
||||||
bool wlr_backend_is_drm(struct wlr_backend *backend);
|
bool wlr_backend_is_drm(struct wlr_backend *backend);
|
||||||
|
|
|
@ -11,9 +11,11 @@ struct session_impl;
|
||||||
struct wlr_device {
|
struct wlr_device {
|
||||||
int fd;
|
int fd;
|
||||||
dev_t dev;
|
dev_t dev;
|
||||||
struct wl_signal signal;
|
|
||||||
|
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct wl_signal change;
|
||||||
|
} events;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wlr_session {
|
struct wlr_session {
|
||||||
|
@ -74,21 +76,21 @@ void wlr_session_destroy(struct wlr_session *session);
|
||||||
*
|
*
|
||||||
* Returns -errno on error.
|
* Returns -errno on error.
|
||||||
*/
|
*/
|
||||||
int wlr_session_open_file(struct wlr_session *session, const char *path);
|
struct wlr_device *wlr_session_open_file(struct wlr_session *session,
|
||||||
|
const char *path);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Closes a file previously opened with wlr_session_open_file.
|
* Closes a file previously opened with wlr_session_open_file.
|
||||||
*/
|
*/
|
||||||
void wlr_session_close_file(struct wlr_session *session, int fd);
|
void wlr_session_close_file(struct wlr_session *session,
|
||||||
|
struct wlr_device *device);
|
||||||
|
|
||||||
void wlr_session_signal_add(struct wlr_session *session, int fd,
|
|
||||||
struct wl_listener *listener);
|
|
||||||
/*
|
/*
|
||||||
* Changes the virtual terminal.
|
* Changes the virtual terminal.
|
||||||
*/
|
*/
|
||||||
bool wlr_session_change_vt(struct wlr_session *session, unsigned vt);
|
bool wlr_session_change_vt(struct wlr_session *session, unsigned vt);
|
||||||
|
|
||||||
size_t wlr_session_find_gpus(struct wlr_session *session,
|
size_t wlr_session_find_gpus(struct wlr_session *session,
|
||||||
size_t ret_len, int *ret);
|
size_t ret_len, struct wlr_device **ret);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue