diff options
author | Simon Ser <contact@emersion.fr> | 2023-11-15 16:38:51 +0100 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2023-11-17 16:59:04 +0000 |
commit | 3b53d1cbf199aa5db0b1c81df92e43fc05670543 (patch) | |
tree | ca7b0a2a87911eaf7738e1a6fb5b7425958a31b6 /include | |
parent | c9c9dd6a5b866055a6a39fd78e55f6d5797fec28 (diff) |
backend/drm: introduce page-flip tracking struct
Introduce a per-page-flip tracking struct passed to the kernel
when we request a page-flip event for an atomic commit. The kernel
will pass us back this pointer when delivering the event.
This eliminates any risk of mixing up events together. In particular,
if two events are pending, or if the CRTC of a connector is swapped,
we no longer blow up in the page-flip event handler.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3753
Diffstat (limited to 'include')
-rw-r--r-- | include/backend/drm/drm.h | 26 | ||||
-rw-r--r-- | include/backend/drm/iface.h | 5 |
2 files changed, 21 insertions, 10 deletions
diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index c7dd70f8..b121b3bc 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -129,6 +129,22 @@ struct wlr_drm_connector_state { struct wlr_drm_fb *primary_fb; }; +/** + * Per-page-flip tracking struct. + * + * We've asked for a state change in the kernel, and yet to receive a + * notification for its completion. Currently, the kernel only has a queue + * length of 1, and no way to modify your submissions after they're sent. + * + * However, we might have multiple in-flight page-flip events, for instance + * when performing a non-blocking commit followed by a blocking commit. In + * that case, conn will be set to NULL on the non-blocking commit to indicate + * that it's been superseded. + */ +struct wlr_drm_page_flip { + struct wlr_drm_connector *conn; +}; + struct wlr_drm_connector { struct wlr_output output; // only valid if status != DISCONNECTED @@ -153,14 +169,8 @@ struct wlr_drm_connector { struct wl_list link; // wlr_drm_backend.connectors - /* CRTC ID if a page-flip is pending, zero otherwise. - * - * We've asked for a state change in the kernel, and yet to receive a - * notification for its completion. Currently, the kernel only has a - * queue length of 1, and no way to modify your submissions after - * they're sent. - */ - uint32_t pending_page_flip_crtc; + // Last committed page-flip + struct wlr_drm_page_flip *pending_page_flip; }; struct wlr_drm_backend *get_drm_backend_from_backend( diff --git a/include/backend/drm/iface.h b/include/backend/drm/iface.h index 9916f383..dbe4c908 100644 --- a/include/backend/drm/iface.h +++ b/include/backend/drm/iface.h @@ -12,6 +12,7 @@ struct wlr_drm_connector; struct wlr_drm_crtc; struct wlr_drm_connector_state; struct wlr_drm_fb; +struct wlr_drm_page_flip; // Used to provide atomic or legacy DRM functions struct wlr_drm_interface { @@ -19,8 +20,8 @@ struct wlr_drm_interface { void (*finish)(struct wlr_drm_backend *drm); // Commit all pending changes on a CRTC. bool (*crtc_commit)(struct wlr_drm_connector *conn, - const struct wlr_drm_connector_state *state, uint32_t flags, - bool test_only); + const struct wlr_drm_connector_state *state, + struct wlr_drm_page_flip *page_flip, uint32_t flags, bool test_only); }; extern const struct wlr_drm_interface atomic_iface; |