diff --git a/backend/drm/backend.c b/backend/drm/backend.c index e6c709bf..5ff2b90c 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -207,6 +207,7 @@ struct wlr_backend *wlr_drm_backend_create(struct wl_display *display, drm->session = session; wl_list_init(&drm->fbs); wl_list_init(&drm->connectors); + wl_list_init(&drm->page_flips); drm->dev = dev; drm->fd = dev->fd; diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 92feed6c..eb9e8267 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -420,6 +420,15 @@ static void drm_connector_set_pending_page_flip(struct wlr_drm_connector *conn, conn->pending_page_flip = page_flip; } +static void page_flip_destroy(struct wlr_drm_page_flip *page_flip) { + if (!page_flip) { + return; + } + + wl_list_remove(&page_flip->link); + free(page_flip); +} + static bool drm_crtc_commit(struct wlr_drm_connector *conn, const struct wlr_drm_connector_state *state, uint32_t flags, bool test_only) { @@ -433,6 +442,7 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn, return false; } page_flip->conn = conn; + wl_list_insert(&conn->backend->page_flips, &page_flip->link); } struct wlr_drm_backend *drm = conn->backend; @@ -466,7 +476,7 @@ static bool drm_crtc_commit(struct wlr_drm_connector *conn, drm_fb_clear(&layer->pending_fb); } - free(page_flip); + page_flip_destroy(page_flip); } return ok; } @@ -1686,7 +1696,7 @@ static void handle_page_flip(int fd, unsigned seq, if (conn != NULL) { conn->pending_page_flip = NULL; } - free(page_flip); + page_flip_destroy(page_flip); if (conn == NULL) { return; diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index b121b3bc..eef778df 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -104,6 +104,8 @@ struct wlr_drm_backend { struct wl_list fbs; // wlr_drm_fb.link struct wl_list connectors; // wlr_drm_connector.link + struct wl_list page_flips; // wlr_drm_page_flip.link + /* Only initialized on multi-GPU setups */ struct wlr_drm_renderer mgpu_renderer; @@ -142,6 +144,7 @@ struct wlr_drm_connector_state { * that it's been superseded. */ struct wlr_drm_page_flip { + struct wl_list link; // wlr_drm_connector.page_flips struct wlr_drm_connector *conn; };