From 771263380c3b3b4b412964b0fe53619aa7c580e2 Mon Sep 17 00:00:00 2001 From: emersion Date: Thu, 4 Jan 2018 12:46:15 +0100 Subject: Add wlr_output::enabled --- backend/drm/drm.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'backend/drm') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index dd5c97f5..32b2f88c 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -257,6 +257,8 @@ static void wlr_drm_connector_enable(struct wlr_output *output, bool enable) { if (enable) { wlr_drm_connector_start_renderer(conn); } + + wlr_output_update_enabled(&conn->output, enable); } static void realloc_planes(struct wlr_drm_backend *drm, const uint32_t *crtc_in, @@ -722,7 +724,8 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { drmModeFreeConnector(drm_conn); continue; } - wlr_output_init(&wlr_conn->output, &drm->backend, &output_impl); + wlr_output_init(&wlr_conn->output, &drm->backend, &output_impl, + drm->display); struct wl_event_loop *ev = wl_display_get_event_loop(drm->display); wlr_conn->retry_pageflip = wl_event_loop_add_timer(ev, retry_pageflip, @@ -792,7 +795,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { wl_list_insert(&wlr_conn->output.modes, &mode->wlr_mode.link); } - wlr_output_create_global(&wlr_conn->output, drm->display); + wlr_output_update_enabled(&wlr_conn->output, true); wlr_conn->state = WLR_DRM_CONN_NEEDS_MODESET; wlr_log(L_INFO, "Sending modesetting signal for '%s'", @@ -802,7 +805,7 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { drm_conn->connection != DRM_MODE_CONNECTED) { wlr_log(L_INFO, "'%s' disconnected", wlr_conn->output.name); - wlr_output_destroy_global(&wlr_conn->output); + wlr_output_update_enabled(&wlr_conn->output, false); wlr_drm_connector_cleanup(wlr_conn); } -- cgit v1.2.3 From 53ba9b4eec4345cb5ba6640e8677f3b2477d2693 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 7 Jan 2018 00:28:21 +0100 Subject: Fix output enable in DRM backend --- backend/drm/atomic.c | 14 +++++++++++--- backend/drm/drm.c | 5 ++++- backend/drm/legacy.c | 5 +++-- include/backend/drm/iface.h | 2 +- 4 files changed, 19 insertions(+), 7 deletions(-) (limited to 'backend/drm') diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index e7374a00..8d98bac2 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -123,14 +123,22 @@ static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm, mode); } -static void atomic_conn_enable(struct wlr_drm_backend *drm, +static bool atomic_conn_enable(struct wlr_drm_backend *drm, struct wlr_drm_connector *conn, bool enable) { struct wlr_drm_crtc *crtc = conn->crtc; - struct atomic atom; + struct atomic atom; atomic_begin(crtc, &atom); atomic_add(&atom, crtc->id, crtc->props.active, enable); - atomic_end(drm->fd, &atom); + if (enable) { + atomic_add(&atom, conn->id, conn->props.crtc_id, crtc->id); + atomic_add(&atom, crtc->id, crtc->props.mode_id, crtc->mode_id); + } else { + atomic_add(&atom, conn->id, conn->props.crtc_id, 0); + atomic_add(&atom, crtc->id, crtc->props.mode_id, 0); + } + return atomic_commit(drm->fd, &atom, conn, DRM_MODE_ATOMIC_ALLOW_MODESET, + true); } bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 32b2f88c..0d32605a 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -252,7 +252,10 @@ static void wlr_drm_connector_enable(struct wlr_output *output, bool enable) { } struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; - drm->iface->conn_enable(drm, conn, enable); + bool ok = drm->iface->conn_enable(drm, conn, enable); + if (!ok) { + return; + } if (enable) { wlr_drm_connector_start_renderer(conn); diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c index d75eb2cb..61140cec 100644 --- a/backend/drm/legacy.c +++ b/backend/drm/legacy.c @@ -25,10 +25,11 @@ static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm, return true; } -static void legacy_conn_enable(struct wlr_drm_backend *drm, +static bool legacy_conn_enable(struct wlr_drm_backend *drm, struct wlr_drm_connector *conn, bool enable) { - drmModeConnectorSetProperty(drm->fd, conn->id, conn->props.dpms, + int ret = drmModeConnectorSetProperty(drm->fd, conn->id, conn->props.dpms, enable ? DRM_MODE_DPMS_ON : DRM_MODE_DPMS_OFF); + return ret >= 0; } bool legacy_crtc_set_cursor(struct wlr_drm_backend *drm, diff --git a/include/backend/drm/iface.h b/include/backend/drm/iface.h index bc61eb51..4a5d2e9d 100644 --- a/include/backend/drm/iface.h +++ b/include/backend/drm/iface.h @@ -15,7 +15,7 @@ struct wlr_drm_crtc; // Used to provide atomic or legacy DRM functions struct wlr_drm_interface { // Enable or disable DPMS for connector - void (*conn_enable)(struct wlr_drm_backend *drm, + bool (*conn_enable)(struct wlr_drm_backend *drm, struct wlr_drm_connector *conn, bool enable); // Pageflip on crtc. If mode is non-NULL perform a full modeset using it. bool (*crtc_pageflip)(struct wlr_drm_backend *drm, -- cgit v1.2.3 From 3101c300b1b60bf47e7dd8032aff4da88a7b9e36 Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Mon, 15 Jan 2018 12:21:22 +0000 Subject: Don't crash if crtc->cursor is NULL Same as what atomic_crtc_set_cursor does Core was generated by `_build/rootston/rootston'. Program terminated with signal SIGSEGV, Segmentation fault. 0 0xb6f28a1c in atomic_crtc_move_cursor (drm=0x1ebc8e8, crtc=0x1ead498, x=0, y=0) at ../backend/drm/atomic.c:170 170 if (!crtc || !crtc->cursor) { (gdb) bt 0 0xb6f28a1c in atomic_crtc_move_cursor (drm=0x1ebc8e8, crtc=0x1ead498, x=0, y=0) at ../backend/drm/atomic.c:170 1 0xb6f2a856 in wlr_drm_connector_move_cursor (output=0x2242b28, x=0, y=0) at ../backend/drm/drm.c:634 2 0xb6f3cea0 in wlr_output_cursor_set_image (cursor=0x21a0338, pixels=0x22e1290 "", stride=24, width=24, height=24, hotspot_x=4, hotspot_y=4) at ../types/wlr_output.c:516 3 0xb6f39da2 in wlr_cursor_set_image (cur=0x22cfc90, pixels=0x22e1290 "", stride=24, width=24, height=24, hotspot_x=4, hotspot_y=4, scale=1) at ../types/wlr_cursor.c:310 4 0xb6f44d2a in wlr_xcursor_manager_set_cursor_image (manager=0x22cfd10, name=0x434420 "left_ptr", cursor=0x22cfc90) at ../types/wlr_xcursor_manager.c:80 5 0x00431c0a in roots_seat_configure_xcursor (seat=0x22cef08) at ../rootston/seat.c:515 6 0x0043137c in roots_seat_init_cursor (seat=0x22cef08) at ../rootston/seat.c:210 7 0x004315ec in roots_seat_create (input=0x218d220, name=0x434594 "seat0") at ../rootston/seat.c:289 8 0x0042ecba in input_get_seat (input=0x218d220, name=0x434594 "seat0") at ../rootston/input.c:39 9 0x0042ed04 in input_add_notify (listener=0x218d228, data=0x218d3b0) at ../rootston/input.c:54 10 0xb6f2f2e6 in wl_signal_emit (signal=0x1ea548c, data=0x218d3b0) at /usr/include/wayland-server-core.h:387 11 0xb6f2f572 in input_add_reemit (listener=0x1ea9990, data=0x218d3b0) at ../backend/multi/backend.c:101 12 0xb6f2db7e in wl_signal_emit (signal=0x1ea992c, data=0x218d3b0) at /usr/include/wayland-server-core.h:387 13 0xb6f2ddaa in handle_device_added (backend=0x1ea9920, libinput_dev=0x2292598) at ../backend/libinput/events.c:87 14 0xb6f2e164 in wlr_libinput_event (backend=0x1ea9920, event=0x2292b78) at ../backend/libinput/events.c:198 15 0xb6f2d678 in wlr_libinput_readable (fd=23, mask=1, _backend=0x1ea9920) at ../backend/libinput/backend.c:28 16 0xb6f2d7c0 in wlr_libinput_backend_start (_backend=0x1ea9920) at ../backend/libinput/backend.c:74 17 0xb6f27170 in wlr_backend_start (backend=0x1ea9920) at ../backend/backend.c:30 18 0xb6f2f320 in multi_backend_start (wlr_backend=0x1ea5480) at ../backend/multi/backend.c:22 19 0xb6f27170 in wlr_backend_start (backend=0x1ea5480) at ../backend/backend.c:30 20 0x0042fbc6 in main (argc=1, argv=0xbe89dd04) at ../rootston/main.c:60 --- backend/drm/atomic.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'backend/drm') diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index e7374a00..64fae6e4 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -167,6 +167,10 @@ bool legacy_crtc_move_cursor(struct wlr_drm_backend *drm, static bool atomic_crtc_move_cursor(struct wlr_drm_backend *drm, struct wlr_drm_crtc *crtc, int x, int y) { + if (!crtc || !crtc->cursor) { + return true; + } + struct wlr_drm_plane *plane = crtc->cursor; // We can't use atomic operations on fake planes if (plane->id == 0) { -- cgit v1.2.3 From 0eebaf98d0550a9ea7adb743a5b85634f1d76b73 Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 15 Jan 2018 21:49:37 +0100 Subject: drm: do not pageflip when enabling output --- backend/drm/atomic.c | 24 +++++++++++++----------- types/wlr_output.c | 4 ++++ 2 files changed, 17 insertions(+), 11 deletions(-) (limited to 'backend/drm') diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index 8d98bac2..3e8866ad 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -33,7 +33,6 @@ static bool atomic_end(int drm_fd, struct atomic *atom) { } uint32_t flags = DRM_MODE_ATOMIC_TEST_ONLY | DRM_MODE_ATOMIC_NONBLOCK; - if (drmModeAtomicCommit(drm_fd, atom->req, flags, NULL)) { wlr_log_errno(L_ERROR, "Atomic test failed"); drmModeAtomicSetCursor(atom->req, atom->cursor); @@ -44,13 +43,11 @@ static bool atomic_end(int drm_fd, struct atomic *atom) { } static bool atomic_commit(int drm_fd, struct atomic *atom, - struct wlr_drm_connector *conn, uint32_t flag, bool modeset) { + struct wlr_drm_connector *conn, uint32_t flags, bool modeset) { if (atom->failed) { return false; } - uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | flag; - int ret = drmModeAtomicCommit(drm_fd, atom->req, flags, conn); if (ret) { wlr_log_errno(L_ERROR, "%s: Atomic commit failed (%s)", @@ -59,7 +56,8 @@ static bool atomic_commit(int drm_fd, struct atomic *atom, // Try to commit without new changes drmModeAtomicSetCursor(atom->req, atom->cursor); if (drmModeAtomicCommit(drm_fd, atom->req, flags, conn)) { - wlr_log_errno(L_ERROR, "%s: Atomic commit failed (%s)", + wlr_log_errno(L_ERROR, + "%s: Atomic commit without new changes failed (%s)", conn->output.name, modeset ? "modeset" : "pageflip"); } } @@ -100,8 +98,8 @@ static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm, struct wlr_drm_connector *conn, struct wlr_drm_crtc *crtc, uint32_t fb_id, drmModeModeInfo *mode) { - if (mode) { - if (crtc->mode_id) { + if (mode != NULL) { + if (crtc->mode_id != 0) { drmModeDestroyPropertyBlob(drm->fd, crtc->mode_id); } @@ -111,16 +109,20 @@ static bool atomic_crtc_pageflip(struct wlr_drm_backend *drm, } } - struct atomic atom; + uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT; + if (mode != NULL) { + flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; + } else { + flags |= DRM_MODE_ATOMIC_NONBLOCK; + } + struct atomic atom; atomic_begin(crtc, &atom); atomic_add(&atom, conn->id, conn->props.crtc_id, crtc->id); atomic_add(&atom, crtc->id, crtc->props.mode_id, crtc->mode_id); atomic_add(&atom, crtc->id, crtc->props.active, 1); set_plane_props(&atom, crtc->primary, crtc->id, fb_id, true); - return atomic_commit(drm->fd, &atom, conn, - mode ? DRM_MODE_ATOMIC_ALLOW_MODESET : DRM_MODE_ATOMIC_NONBLOCK, - mode); + return atomic_commit(drm->fd, &atom, conn, flags, mode); } static bool atomic_conn_enable(struct wlr_drm_backend *drm, diff --git a/types/wlr_output.c b/types/wlr_output.c index 8194c17e..b47fb3a0 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -156,6 +156,10 @@ static void wlr_output_update_matrix(struct wlr_output *output) { } void wlr_output_enable(struct wlr_output *output, bool enable) { + if (output->enabled == enable) { + return; + } + if (output->impl->enable) { output->impl->enable(output, enable); } -- cgit v1.2.3