* [PATCH] drm/atomic: introduce PAGE_FLIP_EVENT property
@ 2026-05-30 17:14 Simon Ser
2026-05-31 9:10 ` Xaver Hugl
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Simon Ser @ 2026-05-30 17:14 UTC (permalink / raw)
To: dri-devel
Cc: wayland-devel, Daniel Stone, Michel Dänzer, Pekka Paalanen,
Christian König, Simona Vetter
Currently user-space can only request page-flip events for all CRTCs included
in an atomic commit. This is cumbersome with multi-CRTC commits: when moving a
plane from a different CRTC, or when disabling a plane, user-space has no way
to opt-out of the page-flip events.
Additionally, page-flip events are invalid for already-disable planes, so
user-space needs to add special cases [1]. Libraries cannot add planes to the
commit without risking causing unexpected page-flip events for the
compositor [2]. Figuring out what CRTCs get implicitly included in a commit is
non-trivial [3].
Introduce a new PAGE_FLIP_EVENT CRTC property so that user-space can select
explicitly which CRTCs will get page-flip events. The property is very
similar to IN_FENCE_FD/OUT_FENCE_PTR: it always reads as zero, and 1 can
be written to request an event.
A user-space implementation is available at [4].
[1]: https://github.com/ValveSoftware/gamescope/blob/67fcb3aebae0ae1eb2d1cff60f29e6d9fe1d128f/src/Backends/DRMBackend.cpp#L2897
[2]: https://gitlab.freedesktop.org/emersion/libliftoff/-/merge_requests/85
[3]: https://lore.kernel.org/dri-devel/20250501112945.6448-1-contact@emersion.fr/
[4]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5387
Signed-off-by: Simon Ser <contact@emersion.fr>
Cc: Daniel Stone <daniel@fooishbar.org>
Cc: Michel Dänzer <michel.daenzer@mailbox.org>
Cc: Pekka Paalanen <pekka.paalanen@collabora.com>
Cc: Christian König <christian.koenig@amd.com>
Cc: Simona Vetter <simona@ffwll.ch>
---
drivers/gpu/drm/drm_atomic_uapi.c | 17 +++++++++++++++--
drivers/gpu/drm/drm_crtc.c | 7 +++++++
drivers/gpu/drm/drm_mode_config.c | 6 ++++++
include/drm/drm_crtc.h | 6 ++++++
include/drm/drm_mode_config.h | 4 ++++
5 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 6441b55cc274..21f2b0df4f63 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -466,6 +466,14 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
return -EFAULT;
set_out_fence_for_crtc(state->state, crtc, fence_ptr);
+ } else if (property == config->prop_page_flip_event) {
+ if (val != 1) {
+ drm_dbg_atomic(crtc->dev,
+ "[CRTC:%d:%s] PAGE_FLIP_EVENT can only be set to 1",
+ crtc->base.id, crtc->name);
+ return -EINVAL;
+ }
+ state->page_flip_event_requested = val;
} else if (property == crtc->scaling_filter_property) {
state->scaling_filter = val;
} else if (property == crtc->sharpness_strength_property) {
@@ -507,6 +515,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
*val = state->background_color;
else if (property == config->prop_out_fence_ptr)
*val = 0;
+ else if (property == config->prop_page_flip_event)
+ *val = 0;
else if (property == crtc->scaling_filter_property)
*val = state->scaling_filter;
else if (property == crtc->sharpness_strength_property)
@@ -1385,6 +1395,7 @@ static int prepare_signaling(struct drm_device *dev,
struct drm_connector *conn;
struct drm_connector_state *conn_state;
int i, c = 0, ret;
+ bool page_flip_event_requested;
if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
return 0;
@@ -1392,9 +1403,11 @@ static int prepare_signaling(struct drm_device *dev,
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
s32 __user *fence_ptr;
+ page_flip_event_requested = arg->flags & DRM_MODE_PAGE_FLIP_EVENT ||
+ crtc_state->page_flip_event_requested;
fence_ptr = get_out_fence_for_crtc(crtc_state->state, crtc);
- if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) {
+ if (page_flip_event_requested || fence_ptr) {
struct drm_pending_vblank_event *e;
e = create_vblank_event(crtc, arg->user_data);
@@ -1404,7 +1417,7 @@ static int prepare_signaling(struct drm_device *dev,
crtc_state->event = e;
}
- if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
+ if (page_flip_event_requested) {
struct drm_pending_vblank_event *e = crtc_state->event;
if (!file_priv)
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 63ead8ba6756..5ad6681bd47c 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -248,6 +248,11 @@ struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
* The sharpness effect takes place post blending on the final composed output.
* If the feature is disabled, the content remains same without any sharpening effect
* and when this feature is applied, it enhances the clarity of the content.
+ * PAGE_FLIP_EVENT:
+ * Atomic property for requesting a page-flip event on this CRTC.
+ *
+ * The value of this property is an integer value which always reads as
+ * zero and can be written with 1 to request the event.
*/
__printf(6, 0)
@@ -322,6 +327,8 @@ static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *
config->prop_out_fence_ptr, 0);
drm_object_attach_property(&crtc->base,
config->prop_vrr_enabled, 0);
+ drm_object_attach_property(&crtc->base,
+ config->prop_page_flip_event, 0);
}
return 0;
diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
index f432f485a914..688937d2e1ec 100644
--- a/drivers/gpu/drm/drm_mode_config.c
+++ b/drivers/gpu/drm/drm_mode_config.c
@@ -496,6 +496,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
return -ENOMEM;
dev->mode_config.prop_out_fence_ptr = prop;
+ prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
+ "PAGE_FLIP_EVENT", 0, 1);
+ if (!prop)
+ return -ENOMEM;
+ dev->mode_config.prop_page_flip_event = prop;
+
prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
"CRTC_ID", DRM_MODE_OBJECT_CRTC);
if (!prop)
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 152349f973e3..b0f9130d263a 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -311,6 +311,12 @@ struct drm_crtc_state {
*/
bool vrr_enabled;
+ /**
+ * @page_flip_event_requested: indicates whether a page-flip event has
+ * been requested on this CRTC.
+ */
+ bool page_flip_event_requested;
+
/**
* @self_refresh_active:
*
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index d8f5b7e9673e..13f39677c32f 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -670,6 +670,10 @@ struct drm_mode_config {
* value of type s32, and then cast that pointer to u64.
*/
struct drm_property *prop_out_fence_ptr;
+ /**
+ * @page_flip_event_property: property to request page-flip events.
+ */
+ struct drm_property *prop_page_flip_event;
/**
* @prop_crtc_id: Default atomic plane property to specify the
* &drm_crtc.
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] drm/atomic: introduce PAGE_FLIP_EVENT property
2026-05-30 17:14 [PATCH] drm/atomic: introduce PAGE_FLIP_EVENT property Simon Ser
@ 2026-05-31 9:10 ` Xaver Hugl
2026-05-31 9:26 ` Simon Ser
2026-06-16 11:15 ` Pekka Paalanen
2 siblings, 0 replies; 4+ messages in thread
From: Xaver Hugl @ 2026-05-31 9:10 UTC (permalink / raw)
To: Simon Ser
Cc: dri-devel, wayland-devel, Daniel Stone, Michel Dänzer,
Pekka Paalanen, Christian König, Simona Vetter
+1, this is very useful. A KWin implementation for this is at
https://invent.kde.org/plasma/kwin/-/merge_requests/9308
- Xaver
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] drm/atomic: introduce PAGE_FLIP_EVENT property
2026-05-30 17:14 [PATCH] drm/atomic: introduce PAGE_FLIP_EVENT property Simon Ser
2026-05-31 9:10 ` Xaver Hugl
@ 2026-05-31 9:26 ` Simon Ser
2026-06-16 11:15 ` Pekka Paalanen
2 siblings, 0 replies; 4+ messages in thread
From: Simon Ser @ 2026-05-31 9:26 UTC (permalink / raw)
To: dri-devel
Cc: wayland-devel, Daniel Stone, Michel Dänzer, Pekka Paalanen,
Christian König, Simona Vetter
IGT test available here:
https://lists.freedesktop.org/archives/igt-dev/2026-May/111026.html
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] drm/atomic: introduce PAGE_FLIP_EVENT property
2026-05-30 17:14 [PATCH] drm/atomic: introduce PAGE_FLIP_EVENT property Simon Ser
2026-05-31 9:10 ` Xaver Hugl
2026-05-31 9:26 ` Simon Ser
@ 2026-06-16 11:15 ` Pekka Paalanen
2 siblings, 0 replies; 4+ messages in thread
From: Pekka Paalanen @ 2026-06-16 11:15 UTC (permalink / raw)
To: Simon Ser
Cc: dri-devel, wayland-devel, Daniel Stone, Michel Dänzer,
Christian König, Simona Vetter
[-- Attachment #1: Type: text/plain, Size: 8221 bytes --]
On Sat, 30 May 2026 17:14:44 +0000
Simon Ser <contact@emersion.fr> wrote:
> Currently user-space can only request page-flip events for all CRTCs included
> in an atomic commit. This is cumbersome with multi-CRTC commits: when moving a
> plane from a different CRTC, or when disabling a plane, user-space has no way
> to opt-out of the page-flip events.
>
> Additionally, page-flip events are invalid for already-disable planes, so
Hi Simon,
do you mean CRTCs? I find "already disabled" to be not really clear
that you mean off->off transition.
> user-space needs to add special cases [1]. Libraries cannot add planes to the
> commit without risking causing unexpected page-flip events for the
> compositor [2].
If a library adds a plane that is currently associated with another
CRTC, would it not be a logic error in userspace if it didn't expect
that CRTC to be involved? Mostly likely if it succeeds, the plane
would disappear from its old CRTC unintended.
If a CRTC is unexpectedly involved, userspace risks EBUSY when it wants
to update that CRTC for real.
> Figuring out what CRTCs get implicitly included in a commit is
> non-trivial [3].
Yes, but is this actually helpful rather than making the failures more
rare and harder to debug?
> Introduce a new PAGE_FLIP_EVENT CRTC property so that user-space can select
> explicitly which CRTCs will get page-flip events. The property is very
> similar to IN_FENCE_FD/OUT_FENCE_PTR: it always reads as zero, and 1 can
> be written to request an event.
>
> A user-space implementation is available at [4].
>
> [1]: https://github.com/ValveSoftware/gamescope/blob/67fcb3aebae0ae1eb2d1cff60f29e6d9fe1d128f/src/Backends/DRMBackend.cpp#L2897
> [2]: https://gitlab.freedesktop.org/emersion/libliftoff/-/merge_requests/85
> [3]: https://lore.kernel.org/dri-devel/20250501112945.6448-1-contact@emersion.fr/
> [4]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/5387
>
> Signed-off-by: Simon Ser <contact@emersion.fr>
> Cc: Daniel Stone <daniel@fooishbar.org>
> Cc: Michel Dänzer <michel.daenzer@mailbox.org>
> Cc: Pekka Paalanen <pekka.paalanen@collabora.com>
> Cc: Christian König <christian.koenig@amd.com>
> Cc: Simona Vetter <simona@ffwll.ch>
> ---
> drivers/gpu/drm/drm_atomic_uapi.c | 17 +++++++++++++++--
> drivers/gpu/drm/drm_crtc.c | 7 +++++++
> drivers/gpu/drm/drm_mode_config.c | 6 ++++++
> include/drm/drm_crtc.h | 6 ++++++
> include/drm/drm_mode_config.h | 4 ++++
> 5 files changed, 38 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index 6441b55cc274..21f2b0df4f63 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -466,6 +466,14 @@ static int drm_atomic_crtc_set_property(struct drm_crtc *crtc,
> return -EFAULT;
>
> set_out_fence_for_crtc(state->state, crtc, fence_ptr);
> + } else if (property == config->prop_page_flip_event) {
> + if (val != 1) {
> + drm_dbg_atomic(crtc->dev,
> + "[CRTC:%d:%s] PAGE_FLIP_EVENT can only be set to 1",
> + crtc->base.id, crtc->name);
> + return -EINVAL;
> + }
> + state->page_flip_event_requested = val;
> } else if (property == crtc->scaling_filter_property) {
> state->scaling_filter = val;
> } else if (property == crtc->sharpness_strength_property) {
> @@ -507,6 +515,8 @@ drm_atomic_crtc_get_property(struct drm_crtc *crtc,
> *val = state->background_color;
> else if (property == config->prop_out_fence_ptr)
> *val = 0;
> + else if (property == config->prop_page_flip_event)
> + *val = 0;
> else if (property == crtc->scaling_filter_property)
> *val = state->scaling_filter;
> else if (property == crtc->sharpness_strength_property)
> @@ -1385,6 +1395,7 @@ static int prepare_signaling(struct drm_device *dev,
> struct drm_connector *conn;
> struct drm_connector_state *conn_state;
> int i, c = 0, ret;
> + bool page_flip_event_requested;
>
> if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY)
> return 0;
> @@ -1392,9 +1403,11 @@ static int prepare_signaling(struct drm_device *dev,
> for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
> s32 __user *fence_ptr;
>
> + page_flip_event_requested = arg->flags & DRM_MODE_PAGE_FLIP_EVENT ||
> + crtc_state->page_flip_event_requested;
> fence_ptr = get_out_fence_for_crtc(crtc_state->state, crtc);
>
> - if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT || fence_ptr) {
> + if (page_flip_event_requested || fence_ptr) {
> struct drm_pending_vblank_event *e;
>
> e = create_vblank_event(crtc, arg->user_data);
> @@ -1404,7 +1417,7 @@ static int prepare_signaling(struct drm_device *dev,
> crtc_state->event = e;
> }
>
> - if (arg->flags & DRM_MODE_PAGE_FLIP_EVENT) {
> + if (page_flip_event_requested) {
> struct drm_pending_vblank_event *e = crtc_state->event;
>
> if (!file_priv)
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 63ead8ba6756..5ad6681bd47c 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -248,6 +248,11 @@ struct dma_fence *drm_crtc_create_fence(struct drm_crtc *crtc)
> * The sharpness effect takes place post blending on the final composed output.
> * If the feature is disabled, the content remains same without any sharpening effect
> * and when this feature is applied, it enhances the clarity of the content.
> + * PAGE_FLIP_EVENT:
> + * Atomic property for requesting a page-flip event on this CRTC.
> + *
> + * The value of this property is an integer value which always reads as
> + * zero and can be written with 1 to request the event.
It took me a while to realise; should probably explain here that if one
uses this, then they would not use DRM_MODE_PAGE_FLIP_EVENT at the same
time.
Does this allow asking for an event for a CRTC off->off
transition?
Thanks,
pq
> */
>
> __printf(6, 0)
> @@ -322,6 +327,8 @@ static int __drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *
> config->prop_out_fence_ptr, 0);
> drm_object_attach_property(&crtc->base,
> config->prop_vrr_enabled, 0);
> + drm_object_attach_property(&crtc->base,
> + config->prop_page_flip_event, 0);
> }
>
> return 0;
> diff --git a/drivers/gpu/drm/drm_mode_config.c b/drivers/gpu/drm/drm_mode_config.c
> index f432f485a914..688937d2e1ec 100644
> --- a/drivers/gpu/drm/drm_mode_config.c
> +++ b/drivers/gpu/drm/drm_mode_config.c
> @@ -496,6 +496,12 @@ static int drm_mode_create_standard_properties(struct drm_device *dev)
> return -ENOMEM;
> dev->mode_config.prop_out_fence_ptr = prop;
>
> + prop = drm_property_create_range(dev, DRM_MODE_PROP_ATOMIC,
> + "PAGE_FLIP_EVENT", 0, 1);
> + if (!prop)
> + return -ENOMEM;
> + dev->mode_config.prop_page_flip_event = prop;
> +
> prop = drm_property_create_object(dev, DRM_MODE_PROP_ATOMIC,
> "CRTC_ID", DRM_MODE_OBJECT_CRTC);
> if (!prop)
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index 152349f973e3..b0f9130d263a 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -311,6 +311,12 @@ struct drm_crtc_state {
> */
> bool vrr_enabled;
>
> + /**
> + * @page_flip_event_requested: indicates whether a page-flip event has
> + * been requested on this CRTC.
> + */
> + bool page_flip_event_requested;
> +
> /**
> * @self_refresh_active:
> *
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index d8f5b7e9673e..13f39677c32f 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -670,6 +670,10 @@ struct drm_mode_config {
> * value of type s32, and then cast that pointer to u64.
> */
> struct drm_property *prop_out_fence_ptr;
> + /**
> + * @page_flip_event_property: property to request page-flip events.
> + */
> + struct drm_property *prop_page_flip_event;
> /**
> * @prop_crtc_id: Default atomic plane property to specify the
> * &drm_crtc.
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-06-16 11:15 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-30 17:14 [PATCH] drm/atomic: introduce PAGE_FLIP_EVENT property Simon Ser
2026-05-31 9:10 ` Xaver Hugl
2026-05-31 9:26 ` Simon Ser
2026-06-16 11:15 ` Pekka Paalanen
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.