diff options
author | Rouven Czerwinski <rouven@czerwinskis.de> | 2019-06-26 17:14:31 +0200 |
---|---|---|
committer | Scott Anderson <ascent12@hotmail.com> | 2019-06-27 00:17:27 +0000 |
commit | d10072e76cffa962d1bc32f056524708981dfa4a (patch) | |
tree | 2c8f288e015953536708f9e4ef73edb9c2ff41a0 /backend/drm | |
parent | 0b1f9439bab7e653fb59cee2b8446dcbf359935c (diff) |
backend: drm: switch to pageflip_handler_2
atomic and legacy now both pass the backend as the user data for the
pageflip event. We than retrieve the correct connector by matching on
the crtc_id passed to the page_flip_handler2.
Wlroots also requires the DRM_CRTC_IN_VBLANK_EVENT capability now.
Fixes #1297
Diffstat (limited to 'backend/drm')
-rw-r--r-- | backend/drm/atomic.c | 6 | ||||
-rw-r--r-- | backend/drm/drm.c | 28 | ||||
-rw-r--r-- | backend/drm/legacy.c | 2 |
3 files changed, 27 insertions, 9 deletions
diff --git a/backend/drm/atomic.c b/backend/drm/atomic.c index ad5ee6e2..023307fc 100644 --- a/backend/drm/atomic.c +++ b/backend/drm/atomic.c @@ -45,18 +45,20 @@ 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 flags, bool modeset) { + struct wlr_drm_backend *drm = + get_drm_backend_from_backend(conn->output.backend); if (atom->failed) { return false; } - int ret = drmModeAtomicCommit(drm_fd, atom->req, flags, conn); + int ret = drmModeAtomicCommit(drm_fd, atom->req, flags, drm); if (ret) { wlr_log_errno(WLR_ERROR, "%s: Atomic commit failed (%s)", conn->output.name, modeset ? "modeset" : "pageflip"); // Try to commit without new changes drmModeAtomicSetCursor(atom->req, atom->cursor); - if (drmModeAtomicCommit(drm_fd, atom->req, flags, conn)) { + if (drmModeAtomicCommit(drm_fd, atom->req, flags, drm)) { wlr_log_errno(WLR_ERROR, "%s: Atomic commit without new changes failed (%s)", conn->output.name, modeset ? "modeset" : "pageflip"); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index a2bfb261..db727010 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -50,6 +50,11 @@ bool check_drm_features(struct wlr_drm_backend *drm) { return false; } + if (drmGetCap(drm->fd, DRM_CAP_CRTC_IN_VBLANK_EVENT, &cap) || !cap) { + wlr_log(WLR_ERROR, "DRM_CRTC_IN_VBLANK_EVENT unsupported"); + return false; + } + const char *no_atomic = getenv("WLR_DRM_NO_ATOMIC"); if (no_atomic && strcmp(no_atomic, "1") == 0) { wlr_log(WLR_DEBUG, @@ -1359,10 +1364,21 @@ static int mhz_to_nsec(int mhz) { } static void page_flip_handler(int fd, unsigned seq, - unsigned tv_sec, unsigned tv_usec, void *data) { - struct wlr_drm_connector *conn = data; - struct wlr_drm_backend *drm = - get_drm_backend_from_backend(conn->output.backend); + unsigned tv_sec, unsigned tv_usec, unsigned crtc_id, void *data) { + struct wlr_drm_backend *drm = data; + struct wlr_drm_connector *conn = NULL; + struct wlr_drm_connector *search; + + wl_list_for_each(search, &drm->outputs, link) { + if (search->crtc && search->crtc->id == crtc_id) { + conn = search; + } + } + + if (!conn) { + wlr_log(WLR_ERROR, "No connector for crtc_id %u", crtc_id); + return; + } conn->pageflip_pending = false; @@ -1411,8 +1427,8 @@ static void page_flip_handler(int fd, unsigned seq, int handle_drm_event(int fd, uint32_t mask, void *data) { drmEventContext event = { - .version = 2, - .page_flip_handler = page_flip_handler, + .version = 3, + .page_flip_handler2 = page_flip_handler, }; drmHandleEvent(fd, &event); diff --git a/backend/drm/legacy.c b/backend/drm/legacy.c index c414f4e6..79cd05b9 100644 --- a/backend/drm/legacy.c +++ b/backend/drm/legacy.c @@ -17,7 +17,7 @@ static bool legacy_crtc_pageflip(struct wlr_drm_backend *drm, } } - if (drmModePageFlip(drm->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, conn)) { + if (drmModePageFlip(drm->fd, crtc->id, fb_id, DRM_MODE_PAGE_FLIP_EVENT, drm)) { wlr_log_errno(WLR_ERROR, "%s: Failed to page flip", conn->output.name); return false; } |