From 9e26808c280cb32f32835231a76b5b105011fd1e Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 21 May 2018 18:50:51 +0100 Subject: output, backend/drm: add wlr_output_export_dmabuf --- backend/drm/drm.c | 21 +++++++++++++++++++++ backend/drm/renderer.c | 25 +++++++++++++++---------- 2 files changed, 36 insertions(+), 10 deletions(-) (limited to 'backend') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index ef8efb9a..5b6054d3 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -254,6 +254,26 @@ static uint32_t drm_connector_get_gamma_size(struct wlr_output *output) { return 0; } +static bool drm_connector_export_dmabuf(struct wlr_output *output, + struct wlr_dmabuf_buffer_attribs *attribs) { + struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; + struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; + + if (!drm->session->active) { + return false; + } + + struct wlr_drm_crtc *crtc = conn->crtc; + if (!crtc) { + return false; + } + struct wlr_drm_plane *plane = crtc->primary; + struct wlr_drm_surface *surf = &plane->surf; + + export_drm_bo(surf->back, attribs); + return true; +} + static void drm_connector_start_renderer(struct wlr_drm_connector *conn) { if (conn->state != WLR_DRM_CONN_CONNECTED) { return; @@ -742,6 +762,7 @@ static const struct wlr_output_impl output_impl = { .swap_buffers = drm_connector_swap_buffers, .set_gamma = drm_connector_set_gamma, .get_gamma_size = drm_connector_get_gamma_size, + .export_dmabuf = drm_connector_export_dmabuf, }; bool wlr_output_is_drm(struct wlr_output *output) { diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index d5bcef2b..2cb47a12 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -160,6 +160,19 @@ void post_drm_surface(struct wlr_drm_surface *surf) { } } +void export_drm_bo(struct gbm_bo *bo, + struct wlr_dmabuf_buffer_attribs *attribs) { + memset(attribs, 0, sizeof(struct wlr_dmabuf_buffer_attribs)); + attribs->n_planes = 1; + attribs->width = gbm_bo_get_width(bo); + attribs->height = gbm_bo_get_height(bo); + attribs->format = gbm_bo_get_format(bo); + attribs->offset[0] = 0; + attribs->stride[0] = gbm_bo_get_stride_for_plane(bo, 0); + attribs->modifier[0] = DRM_FORMAT_MOD_LINEAR; + attribs->fd[0] = gbm_bo_get_fd(bo); +} + struct tex { struct wlr_egl *egl; EGLImageKHR img; @@ -186,16 +199,8 @@ static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, return NULL; } - struct wlr_dmabuf_buffer_attribs attribs = { - .n_planes = 1, - .width = gbm_bo_get_width(bo), - .height = gbm_bo_get_height(bo), - .format = gbm_bo_get_format(bo), - }; - attribs.offset[0] = 0; - attribs.stride[0] = gbm_bo_get_stride_for_plane(bo, 0); - attribs.modifier[0] = DRM_FORMAT_MOD_LINEAR; - attribs.fd[0] = gbm_bo_get_fd(bo); + struct wlr_dmabuf_buffer_attribs attribs; + export_drm_bo(bo, &attribs); tex->tex = wlr_texture_from_dmabuf(renderer->wlr_rend, &attribs); if (tex->tex == NULL) { -- cgit v1.2.3 From bd430b8620f5dec485e49269d6add8dc3c20a8ab Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 22 May 2018 23:07:15 +0100 Subject: backend/drm: support multi-planar DMA-BUFs when exporting --- backend/drm/drm.c | 3 +-- backend/drm/renderer.c | 33 ++++++++++++++++++++++++++------- include/backend/drm/renderer.h | 2 +- 3 files changed, 28 insertions(+), 10 deletions(-) (limited to 'backend') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 5b6054d3..d54c93f8 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -270,8 +270,7 @@ static bool drm_connector_export_dmabuf(struct wlr_output *output, struct wlr_drm_plane *plane = crtc->primary; struct wlr_drm_surface *surf = &plane->surf; - export_drm_bo(surf->back, attribs); - return true; + return export_drm_bo(surf->back, attribs); } static void drm_connector_start_renderer(struct wlr_drm_connector *conn) { diff --git a/backend/drm/renderer.c b/backend/drm/renderer.c index 2cb47a12..15cf8cce 100644 --- a/backend/drm/renderer.c +++ b/backend/drm/renderer.c @@ -160,17 +160,33 @@ void post_drm_surface(struct wlr_drm_surface *surf) { } } -void export_drm_bo(struct gbm_bo *bo, +bool export_drm_bo(struct gbm_bo *bo, struct wlr_dmabuf_buffer_attribs *attribs) { memset(attribs, 0, sizeof(struct wlr_dmabuf_buffer_attribs)); - attribs->n_planes = 1; + + attribs->n_planes = gbm_bo_get_plane_count(bo); + if (attribs->n_planes > WLR_LINUX_DMABUF_MAX_PLANES) { + return false; + } + attribs->width = gbm_bo_get_width(bo); attribs->height = gbm_bo_get_height(bo); attribs->format = gbm_bo_get_format(bo); - attribs->offset[0] = 0; - attribs->stride[0] = gbm_bo_get_stride_for_plane(bo, 0); - attribs->modifier[0] = DRM_FORMAT_MOD_LINEAR; - attribs->fd[0] = gbm_bo_get_fd(bo); + + for (int i = 0; i < attribs->n_planes; ++i) { + attribs->offset[i] = gbm_bo_get_offset(bo, i); + attribs->stride[i] = gbm_bo_get_stride_for_plane(bo, i); + attribs->modifier[i] = gbm_bo_get_modifier(bo); + attribs->fd[i] = gbm_bo_get_fd(bo); + if (attribs->fd[i] < 0) { + for (int j = 0; j < i; ++j) { + close(attribs->fd[j]); + } + return false; + } + } + + return true; } struct tex { @@ -200,7 +216,10 @@ static struct wlr_texture *get_tex_for_bo(struct wlr_drm_renderer *renderer, } struct wlr_dmabuf_buffer_attribs attribs; - export_drm_bo(bo, &attribs); + if (!export_drm_bo(bo, &attribs)) { + free(tex); + return NULL; + } tex->tex = wlr_texture_from_dmabuf(renderer->wlr_rend, &attribs); if (tex->tex == NULL) { diff --git a/include/backend/drm/renderer.h b/include/backend/drm/renderer.h index f26ca3d6..00e26976 100644 --- a/include/backend/drm/renderer.h +++ b/include/backend/drm/renderer.h @@ -52,7 +52,7 @@ struct gbm_bo *get_drm_surface_front(struct wlr_drm_surface *surf); void post_drm_surface(struct wlr_drm_surface *surf); struct gbm_bo *copy_drm_surface_mgpu(struct wlr_drm_surface *dest, struct gbm_bo *src); -void export_drm_bo(struct gbm_bo *bo, +bool export_drm_bo(struct gbm_bo *bo, struct wlr_dmabuf_buffer_attribs *attribs); #endif -- cgit v1.2.3 From 47985d2dc56a6af469ac9375e7548136765aff16 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Thu, 14 Jun 2018 20:46:16 +1200 Subject: Multiseat fixes --- backend/libinput/backend.c | 4 +-- backend/session/direct.c | 60 ++++++++++++++++++++++++++----------------- backend/session/logind.c | 5 ++++ backend/session/session.c | 4 +-- include/wlr/backend/session.h | 6 ++++- 5 files changed, 50 insertions(+), 29 deletions(-) (limited to 'backend') diff --git a/backend/libinput/backend.c b/backend/libinput/backend.c index f4d54c97..1dde5854 100644 --- a/backend/libinput/backend.c +++ b/backend/libinput/backend.c @@ -55,8 +55,8 @@ static bool backend_start(struct wlr_backend *_backend) { return false; } - // TODO: Let user customize seat used - if (libinput_udev_assign_seat(backend->libinput_context, "seat0") != 0) { + if (libinput_udev_assign_seat(backend->libinput_context, + backend->session->seat) != 0) { wlr_log(L_ERROR, "Failed to assign libinput seat"); return false; } diff --git a/backend/session/direct.c b/backend/session/direct.c index 13a26d99..c1a59647 100644 --- a/backend/session/direct.c +++ b/backend/session/direct.c @@ -1,5 +1,6 @@ #define _POSIX_C_SOURCE 200809L #include +#include #include #include #include @@ -76,30 +77,39 @@ static void direct_session_close(struct wlr_session *base, int fd) { static bool direct_change_vt(struct wlr_session *base, unsigned vt) { struct direct_session *session = wl_container_of(base, session, base); + + // Only seat0 has VTs associated with it + if (strcmp(session->base.seat, "seat0") == 0) { + return true; + } + return ioctl(session->tty_fd, VT_ACTIVATE, (int)vt) == 0; } static void direct_session_destroy(struct wlr_session *base) { struct direct_session *session = wl_container_of(base, session, base); - struct vt_mode mode = { - .mode = VT_AUTO, - }; - errno = 0; + if (strcmp(session->base.seat, "seat0") == 0) { + struct vt_mode mode = { + .mode = VT_AUTO, + }; + errno = 0; + + ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode); + ioctl(session->tty_fd, KDSETMODE, KD_TEXT); + ioctl(session->tty_fd, VT_SETMODE, &mode); - ioctl(session->tty_fd, KDSKBMODE, session->old_kbmode); - ioctl(session->tty_fd, KDSETMODE, KD_TEXT); - ioctl(session->tty_fd, VT_SETMODE, &mode); + if (errno) { + wlr_log(L_ERROR, "Failed to restore tty"); + } - if (errno) { - wlr_log(L_ERROR, "Failed to restore tty"); + wl_event_source_remove(session->vt_source); + close(session->tty_fd); } direct_ipc_finish(session->sock, session->child); close(session->sock); - wl_event_source_remove(session->vt_source); - close(session->tty_fd); free(session); } @@ -138,19 +148,19 @@ static int vt_handler(int signo, void *data) { } static bool setup_tty(struct direct_session *session, struct wl_display *display) { - int fd = dup(STDIN_FILENO); + int fd = open("/dev/tty", O_RDWR); if (fd == -1) { - wlr_log_errno(L_ERROR, "Cannot open tty"); + wlr_log_errno(L_ERROR, "Cannot open /dev/tty"); return false; } - struct stat st; - if (fstat(fd, &st) == -1 || major(st.st_rdev) != TTY_MAJOR || minor(st.st_rdev) == 0) { - wlr_log(L_ERROR, "Not running from a virtual terminal"); + struct vt_stat vt_stat; + if (ioctl(fd, VT_GETSTATE, &vt_stat)) { + wlr_log_errno(L_ERROR, "Could not get current tty number"); goto error; } - int tty = minor(st.st_rdev); + int tty = vt_stat.v_active; int ret, kd_mode, old_kbmode; ret = ioctl(fd, KDGETMODE, &kd_mode); @@ -224,20 +234,24 @@ static struct wlr_session *direct_session_create(struct wl_display *disp) { goto error_session; } - if (!setup_tty(session, disp)) { - goto error_ipc; - } - - // XXX: Is it okay to trust the environment like this? const char *seat = getenv("XDG_SEAT"); if (!seat) { seat = "seat0"; } - wlr_log(L_INFO, "Successfully loaded direct session"); + if (strcmp(seat, "seat0") == 0) { + if (!setup_tty(session, disp)) { + goto error_ipc; + } + } else { + session->base.vtnr = 0; + session->tty_fd = -1; + } snprintf(session->base.seat, sizeof(session->base.seat), "%s", seat); session->base.impl = &session_direct; + + wlr_log(L_INFO, "Successfully loaded direct session"); return &session->base; error_ipc: diff --git a/backend/session/logind.c b/backend/session/logind.c index f0ac1e93..3a3cc57d 100644 --- a/backend/session/logind.c +++ b/backend/session/logind.c @@ -109,6 +109,11 @@ static void logind_release_device(struct wlr_session *base, int fd) { static bool logind_change_vt(struct wlr_session *base, unsigned vt) { struct logind_session *session = wl_container_of(base, session, base); + // Only seat0 has VTs associated with it + if (strcmp(session->base.seat, "seat0") != 0) { + return true; + } + int ret; sd_bus_message *msg = NULL; sd_bus_error error = SD_BUS_ERROR_NULL; diff --git a/backend/session/session.c b/backend/session/session.c index 2d5d9776..026040fd 100644 --- a/backend/session/session.c +++ b/backend/session/session.c @@ -19,9 +19,7 @@ extern const struct session_impl session_logind; extern const struct session_impl session_direct; static const struct session_impl *impls[] = { -#ifdef WLR_HAS_SYSTEMD - &session_logind, -#elif defined(WLR_HAS_ELOGIND) +#if defined(WLR_HAS_SYSTEMD) || defined(WLR_HAS_ELOGIND) &session_logind, #endif &session_direct, diff --git a/include/wlr/backend/session.h b/include/wlr/backend/session.h index 4d04b363..1cf41939 100644 --- a/include/wlr/backend/session.h +++ b/include/wlr/backend/session.h @@ -25,8 +25,12 @@ struct wlr_session { struct wl_signal session_signal; bool active; + /* + * 0 if virtual terminals are not supported + * i.e. seat != "seat0" + */ unsigned vtnr; - char seat[8]; + char seat[256]; struct udev *udev; struct udev_monitor *mon; -- cgit v1.2.3 From 964e0a50beabe03d84f042209fc019909b631e05 Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Thu, 14 Jun 2018 21:02:32 +1200 Subject: Check for seat0 properly --- backend/session/direct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backend') diff --git a/backend/session/direct.c b/backend/session/direct.c index c1a59647..7fa7d05b 100644 --- a/backend/session/direct.c +++ b/backend/session/direct.c @@ -79,7 +79,7 @@ static bool direct_change_vt(struct wlr_session *base, unsigned vt) { struct direct_session *session = wl_container_of(base, session, base); // Only seat0 has VTs associated with it - if (strcmp(session->base.seat, "seat0") == 0) { + if (strcmp(session->base.seat, "seat0") != 0) { return true; } -- cgit v1.2.3 From 482fc48c74361dd8b1adf0f5c14abd8e82f35bf6 Mon Sep 17 00:00:00 2001 From: Tobias Blass Date: Wed, 20 Jun 2018 21:35:15 +0200 Subject: FIX: Suprocess loops endlessly when the control socket closes. recvmsg(3) returns 0 if the connection partner has shut down its socket. The communicate function considered 0 a successful message, though, and keeps calling recvmsg(3) again and again. --- backend/session/direct-ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'backend') diff --git a/backend/session/direct-ipc.c b/backend/session/direct-ipc.c index 6c69b70a..f8ba07f7 100644 --- a/backend/session/direct-ipc.c +++ b/backend/session/direct-ipc.c @@ -130,7 +130,7 @@ static void communicate(int sock) { int drm_fd = -1; bool running = true; - while (running && recv_msg(sock, &drm_fd, &msg, sizeof(msg)) >= 0) { + while (running && recv_msg(sock, &drm_fd, &msg, sizeof(msg)) > 0) { switch (msg.type) { case MSG_OPEN: errno = 0; -- cgit v1.2.3