Re: Are the stable/staging/unstable protocol distinctions useful?
On Thu, 6 Jul 2023 18:44:16 -0400 Neal Gompa wrote: > Hey everyone, > > There's something I've been ruminating on for a few years now: the > state of wayland-protocols. > > I've noticed that over the course of the existence of > wayland-protocols, only three have made it into "stable": > presentation-time, viewporter, and xdg-shell. > > But basically no useful Wayland environment relies only on those three > protocols, and many protocols have been broadly adopted in staging and > unstable. For example: everyone implements relative-pointer (unstable) > and almost everyone implements xdg-activation (staging). > > There are many "unstable" wayland protocols that are so broadly > adopted that they basically aren't going to change anymore. A good > chunk of the "staging" protocols have no implementers (per > wayland.app). Right. See e.g. https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/223 https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/221#note_1985498 > So what I'm wondering now is: are the distinctions useful? And if so, > how are they useful? If they aren't useful, can we get rid of them? The distinction they make is: - unstable/staging are kind of incubating, meaning they have higher chance to need a new backward-incompatible revision than stable - unstable/staging have a higher chance to lose support after being implemented than stable "Higher chance" also implies that suggestions to do so are more acceptable than in stable. That means that the incentive to bend over backwards to work around any design warts is much lower. The difference between unstable and staging was just the process on how an extension shall be declared stable. Unstable mandated a final world-breaking change while staging does not. Today, I think both are equal in that we would always use the staging process. Our failure here is that there is no clear criteria when an extension needs to move to stable, so they have mostly been forgotten since stuff works already. > Now, that may seem nuts, but here me out! Every wayland protocol that > has been merged is already versioned. Every wayland protocol proposed > is supposed to already have at least two implementers (which as noted > earlier, a number of existing protocols lack). > > Between the versioned protocols and the requirement for implementers, > I don't see where the distinction helps anything. If anything, I've > seen examples of the distinction used as a deterrent by particular > compositor implementers despite the obvious need for them. > > Could we consider getting rid of the distinction? If we need to have > structural sorting in the repository, perhaps folders representing the > versions instead? Or maybe some other categorization that doesn't > imply that something shouldn't be implemented. A good question. If staging prevents an extension from seeing interest, it will never prove the design either. OTOH, I suspect a concern was that people would jump to implementing something assuming it's final, and when upstream decides it doesn't work right and needs a breaking change, people could be upset. There are few extensions that probably shouldn't be newly implemented by anyone. Fullscreen-shell comes to mind. Nothing can be deleted, because it would break builds, so the directories will live on anyway, but it would be possible to realize the old directory structure at install time, like Sebastian recently suggested. I suppose a much more useful distinction than staging/stable would be a database indicating which software implements what extension. That has been on a wishlist for years, including recording project attitudes towards extensions (will never implement vs. ok but no-one did the work yet). wayland.app looks really nice, but I think the implementors list should also include client toolkits and perhaps version information. This was the plan that never came to fruition: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/blob/master/GOVERNANCE.md#3-protocol-adoption-documentation Thanks, pq pgp85dHzwCjkf.pgp Description: OpenPGP digital signature
Wayland Governance Meeting
This is a meeting annoucement. The Wayland Governance Meeting is semi-regular meeting to drive discussion on wayland-protocols forward. Agenda for the next meeting: ext-layer-shell ext-screencopy ext-foreign-toplevel ext-workspaces Link to the doodle: https://nuudel.digitalcourage.de/ckEBoLoIuGiO4VrU The final date will be annouced on Monday 10th of July. Notes of previous meetings can be found here: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/wikis/meetings In the interest of not having the meeting-link publically available, please contact me under victo...@system76.com, if you wish to participate. Best regards, Victoria Brekenfeld
[PATCH v5 1/6] drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits
From: Simon Ser If the driver supports it, allow user-space to supply the DRM_MODE_PAGE_FLIP_ASYNC flag to request an async page-flip. Set drm_crtc_state.async_flip accordingly. Document that drivers will reject atomic commits if an async flip isn't possible. This allows user-space to fall back to something else. For instance, Xorg falls back to a blit. Another option is to wait as close to the next vblank as possible before performing the page-flip to reduce latency. Signed-off-by: Simon Ser Reviewed-by: Alex Deucher Co-developed-by: André Almeida Signed-off-by: André Almeida --- v4: no changes --- drivers/gpu/drm/drm_atomic_uapi.c | 28 +--- include/uapi/drm/drm_mode.h | 9 + 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index d867e7f9f2cd..dfd4cf7169df 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -1286,6 +1286,18 @@ static void complete_signaling(struct drm_device *dev, kfree(fence_state); } +static void +set_async_flip(struct drm_atomic_state *state) +{ + struct drm_crtc *crtc; + struct drm_crtc_state *crtc_state; + int i; + + for_each_new_crtc_in_state(state, crtc, crtc_state, i) { + crtc_state->async_flip = true; + } +} + int drm_mode_atomic_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { @@ -1326,9 +1338,16 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, } if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) { - drm_dbg_atomic(dev, - "commit failed: invalid flag DRM_MODE_PAGE_FLIP_ASYNC\n"); - return -EINVAL; + if (!dev->mode_config.async_page_flip) { + drm_dbg_atomic(dev, + "commit failed: DRM_MODE_PAGE_FLIP_ASYNC not supported\n"); + return -EINVAL; + } + if (dev->mode_config.atomic_async_page_flip_not_supported) { + drm_dbg_atomic(dev, + "commit failed: DRM_MODE_PAGE_FLIP_ASYNC not supported with atomic\n"); + return -EINVAL; + } } /* can't test and expect an event at the same time. */ @@ -1426,6 +1445,9 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, if (ret) goto out; + if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) + set_async_flip(state); + if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { ret = drm_atomic_check_only(state); } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 46becedf5b2f..56342ba2c11a 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -949,6 +949,15 @@ struct hdr_output_metadata { * Request that the page-flip is performed as soon as possible, ie. with no * delay due to waiting for vblank. This may cause tearing to be visible on * the screen. + * + * When used with atomic uAPI, the driver will return an error if the hardware + * doesn't support performing an asynchronous page-flip for this update. + * User-space should handle this, e.g. by falling back to a regular page-flip. + * + * Note, some hardware might need to perform one last synchronous page-flip + * before being able to switch to asynchronous page-flips. As an exception, + * the driver will return success even though that first page-flip is not + * asynchronous. */ #define DRM_MODE_PAGE_FLIP_ASYNC 0x02 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4 -- 2.41.0
[PATCH v5 0/6] drm: Add support for atomic async page-flip
Hi, This work from me and Simon adds support for DRM_MODE_PAGE_FLIP_ASYNC through the atomic API. This feature is already available via the legacy API. The use case is to be able to present a new frame immediately (or as soon as possible), even if after missing a vblank. This might result in tearing, but it's useful when a high framerate is desired, such as for gaming. Differently from earlier versions, this one refuses to flip if any prop changes for async flips. The idea is that the fast path of immediate page flips doesn't play well with modeset changes, so only the fb_id can be changed. The exception is for mode_id changes, that might be referring to an identical mode (which would skip a modeset). This is done to make the async API more similar to the normal API. Thanks, André - User-space patch: https://github.com/Plagman/gamescope/pull/595 - IGT tests: https://gitlab.freedesktop.org/andrealmeid/igt-gpu-tools/-/tree/atomic_async_page_flip Changes from v4: - Documentation rewrote by Pekka Paalanen v4: https://lore.kernel.org/dri-devel/20230701020917.143394-1-andrealm...@igalia.com/ Changes from v3: - Add new patch to reject prop changes - Add a documentation clarifying the KMS atomic state set v3: https://lore.kernel.org/dri-devel/20220929184307.258331-1-cont...@emersion.fr/ André Almeida (1): drm: Refuse to async flip with atomic prop changes Pekka Paalanen (1): drm/doc: Define KMS atomic state set Simon Ser (4): drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits drm: introduce DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP drm: introduce drm_mode_config.atomic_async_page_flip_not_supported amd/display: indicate support for atomic async page-flips on DC Documentation/gpu/drm-uapi.rst | 41 ++ drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 1 + drivers/gpu/drm/drm_atomic_helper.c | 5 ++ drivers/gpu/drm/drm_atomic_uapi.c| 80 ++-- drivers/gpu/drm/drm_crtc_internal.h | 2 +- drivers/gpu/drm/drm_ioctl.c | 5 ++ drivers/gpu/drm/drm_mode_object.c| 2 +- drivers/gpu/drm/i915/display/intel_display.c | 1 + drivers/gpu/drm/nouveau/nouveau_display.c| 1 + include/drm/drm_mode_config.h| 11 +++ include/uapi/drm/drm.h | 10 ++- include/uapi/drm/drm_mode.h | 9 +++ 12 files changed, 159 insertions(+), 9 deletions(-) -- 2.41.0
[PATCH v5 2/6] drm: introduce DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP
From: Simon Ser This new kernel capability indicates whether async page-flips are supported via the atomic uAPI. DRM clients can use it to check for support before feeding DRM_MODE_PAGE_FLIP_ASYNC to the kernel. Make it clear that DRM_CAP_ASYNC_PAGE_FLIP is for legacy uAPI only. Signed-off-by: Simon Ser Reviewed-by: André Almeida Reviewed-by: Alex Deucher Signed-off-by: André Almeida --- v4: no changes --- drivers/gpu/drm/drm_ioctl.c | 5 + include/uapi/drm/drm.h | 10 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 7c9d66ee917d..8f756b99260d 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -302,6 +302,11 @@ static int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_ case DRM_CAP_CRTC_IN_VBLANK_EVENT: req->value = 1; break; + case DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP: + req->value = drm_core_check_feature(dev, DRIVER_ATOMIC) && +dev->mode_config.async_page_flip && + !dev->mode_config.atomic_async_page_flip_not_supported; + break; default: return -EINVAL; } diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h index a87ca2d4..54c558f81f3c 100644 --- a/include/uapi/drm/drm.h +++ b/include/uapi/drm/drm.h @@ -706,7 +706,8 @@ struct drm_gem_open { /** * DRM_CAP_ASYNC_PAGE_FLIP * - * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC. + * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for legacy + * page-flips. */ #define DRM_CAP_ASYNC_PAGE_FLIP0x7 /** @@ -767,6 +768,13 @@ struct drm_gem_open { * Documentation/gpu/drm-mm.rst, section "DRM Sync Objects". */ #define DRM_CAP_SYNCOBJ_TIMELINE 0x14 +/** + * DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP + * + * If set to 1, the driver supports &DRM_MODE_PAGE_FLIP_ASYNC for atomic + * commits. + */ +#define DRM_CAP_ATOMIC_ASYNC_PAGE_FLIP 0x15 /* DRM_IOCTL_GET_CAP ioctl argument type */ struct drm_get_cap { -- 2.41.0
[PATCH v5 3/6] drm: introduce drm_mode_config.atomic_async_page_flip_not_supported
From: Simon Ser This new field indicates whether the driver has the necessary logic to support async page-flips via the atomic uAPI. This is leveraged by the next commit to allow user-space to use this functionality. All atomic drivers setting drm_mode_config.async_page_flip are updated to also set drm_mode_config.atomic_async_page_flip_not_supported. We will gradually check and update these drivers to properly handle drm_crtc_state.async_flip in their atomic logic. The goal of this negative flag is the same as fb_modifiers_not_supported: we want to eventually get rid of all drivers missing atomic support for async flips. New drivers should not set this flag, instead they should support atomic async flips (if they support async flips at all). IOW, we don't want more drivers with async flip support for legacy but not atomic. Signed-off-by: Simon Ser Reviewed-by: André Almeida Reviewed-by: Alex Deucher Signed-off-by: André Almeida --- v4: no changes --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 + drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c | 1 + drivers/gpu/drm/i915/display/intel_display.c | 1 + drivers/gpu/drm/nouveau/nouveau_display.c | 1 + include/drm/drm_mode_config.h | 11 +++ 5 files changed, 15 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 7acd73e5004f..258461826140 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3970,6 +3970,7 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) adev_to_drm(adev)->mode_config.prefer_shadow = 1; /* indicates support for immediate flip */ adev_to_drm(adev)->mode_config.async_page_flip = true; + adev_to_drm(adev)->mode_config.atomic_async_page_flip_not_supported = true; state = kzalloc(sizeof(*state), GFP_KERNEL); if (!state) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 29603561d501..8afb22b1e730 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -639,6 +639,7 @@ static int atmel_hlcdc_dc_modeset_init(struct drm_device *dev) dev->mode_config.max_height = dc->desc->max_height; dev->mode_config.funcs = &mode_config_funcs; dev->mode_config.async_page_flip = true; + dev->mode_config.atomic_async_page_flip_not_supported = true; return 0; } diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 0aae9a1eb3d5..a5c503ca9168 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -8318,6 +8318,7 @@ static void intel_mode_config_init(struct drm_i915_private *i915) mode_config->helper_private = &intel_mode_config_funcs; mode_config->async_page_flip = HAS_ASYNC_FLIPS(i915); + mode_config->atomic_async_page_flip_not_supported = true; /* * Maximum framebuffer dimensions, chosen to match diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index ec3487fc..f497dcd9e22f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -709,6 +709,7 @@ nouveau_display_create(struct drm_device *dev) dev->mode_config.async_page_flip = false; else dev->mode_config.async_page_flip = true; + dev->mode_config.atomic_async_page_flip_not_supported = true; drm_kms_helper_poll_init(dev); drm_kms_helper_poll_disable(dev); diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h index 973119a9176b..47b005671e6a 100644 --- a/include/drm/drm_mode_config.h +++ b/include/drm/drm_mode_config.h @@ -918,6 +918,17 @@ struct drm_mode_config { */ bool async_page_flip; + /** +* @atomic_async_page_flip_not_supported: +* +* If true, the driver does not support async page-flips with the +* atomic uAPI. This is only used by old drivers which haven't yet +* accomodated for &drm_crtc_state.async_flip in their atomic logic, +* even if they have &drm_mode_config.async_page_flip set to true. +* New drivers shall not set this flag. +*/ + bool atomic_async_page_flip_not_supported; + /** * @fb_modifiers_not_supported: * -- 2.41.0
[PATCH v5 4/6] amd/display: indicate support for atomic async page-flips on DC
From: Simon Ser amdgpu_dm_commit_planes() already sets the flip_immediate flag for async page-flips. This flag is used to set the UNP_FLIP_CONTROL register. Thus, no additional change is required to handle async page-flips with the atomic uAPI. Signed-off-by: Simon Ser Reviewed-by: André Almeida Reviewed-by: Alex Deucher Signed-off-by: André Almeida --- v4: no changes --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 258461826140..7acd73e5004f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3970,7 +3970,6 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev) adev_to_drm(adev)->mode_config.prefer_shadow = 1; /* indicates support for immediate flip */ adev_to_drm(adev)->mode_config.async_page_flip = true; - adev_to_drm(adev)->mode_config.atomic_async_page_flip_not_supported = true; state = kzalloc(sizeof(*state), GFP_KERNEL); if (!state) -- 2.41.0
[PATCH v5 5/6] drm: Refuse to async flip with atomic prop changes
Given that prop changes may lead to modesetting, which would defeat the fast path of the async flip, refuse any atomic prop change for async flips in atomic API. The only exceptions are the framebuffer ID to flip to and the mode ID, that could be referring to an identical mode. Signed-off-by: André Almeida --- v4: new patch --- drivers/gpu/drm/drm_atomic_helper.c | 5 +++ drivers/gpu/drm/drm_atomic_uapi.c | 52 +++-- drivers/gpu/drm/drm_crtc_internal.h | 2 +- drivers/gpu/drm/drm_mode_object.c | 2 +- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c index 2c2c9caf0be5..1e2973f0e1f6 100644 --- a/drivers/gpu/drm/drm_atomic_helper.c +++ b/drivers/gpu/drm/drm_atomic_helper.c @@ -629,6 +629,11 @@ drm_atomic_helper_check_modeset(struct drm_device *dev, WARN_ON(!drm_modeset_is_locked(&crtc->mutex)); if (!drm_mode_equal(&old_crtc_state->mode, &new_crtc_state->mode)) { + if (new_crtc_state->async_flip) { + drm_dbg_atomic(dev, "[CRTC:%d:%s] no mode changes allowed during async flip\n", + crtc->base.id, crtc->name); + return -EINVAL; + } drm_dbg_atomic(dev, "[CRTC:%d:%s] mode changed\n", crtc->base.id, crtc->name); new_crtc_state->mode_changed = true; diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c index dfd4cf7169df..536c21f53b5f 100644 --- a/drivers/gpu/drm/drm_atomic_uapi.c +++ b/drivers/gpu/drm/drm_atomic_uapi.c @@ -972,13 +972,28 @@ int drm_atomic_connector_commit_dpms(struct drm_atomic_state *state, return ret; } +static int drm_atomic_check_prop_changes(int ret, uint64_t old_val, uint64_t prop_value, +struct drm_property *prop) +{ + if (ret != 0 || old_val != prop_value) { + drm_dbg_atomic(prop->dev, + "[PROP:%d:%s] No prop can be changed during async flip\n", + prop->base.id, prop->name); + return -EINVAL; + } + + return 0; +} + int drm_atomic_set_property(struct drm_atomic_state *state, struct drm_file *file_priv, struct drm_mode_object *obj, struct drm_property *prop, - uint64_t prop_value) + uint64_t prop_value, + bool async_flip) { struct drm_mode_object *ref; + uint64_t old_val; int ret; if (!drm_property_change_valid_get(prop, prop_value, &ref)) @@ -995,6 +1010,13 @@ int drm_atomic_set_property(struct drm_atomic_state *state, break; } + if (async_flip) { + ret = drm_atomic_connector_get_property(connector, connector_state, + prop, &old_val); + ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop); + break; + } + ret = drm_atomic_connector_set_property(connector, connector_state, file_priv, prop, prop_value); @@ -1003,6 +1025,7 @@ int drm_atomic_set_property(struct drm_atomic_state *state, case DRM_MODE_OBJECT_CRTC: { struct drm_crtc *crtc = obj_to_crtc(obj); struct drm_crtc_state *crtc_state; + struct drm_mode_config *config = &crtc->dev->mode_config; crtc_state = drm_atomic_get_crtc_state(state, crtc); if (IS_ERR(crtc_state)) { @@ -1010,6 +1033,18 @@ int drm_atomic_set_property(struct drm_atomic_state *state, break; } + /* +* We allow mode_id changes here for async flips, because we +* check later on drm_atomic_helper_check_modeset() callers if +* there are modeset changes or they are equal +*/ + if (async_flip && prop != config->prop_mode_id) { + ret = drm_atomic_crtc_get_property(crtc, crtc_state, + prop, &old_val); + ret = drm_atomic_check_prop_changes(ret, old_val, prop_value, prop); + break; + } + ret = drm_atomic_crtc_set_property(crtc, crtc_state, prop, prop_value); break; @@ -1017,6 +1052,7 @@ int drm_atomic_set_property(struct drm_atomic_state *state, case DRM_MODE_OBJECT_PLANE: { struct drm
[PATCH v5 6/6] drm/doc: Define KMS atomic state set
From: Pekka Paalanen Specify how the atomic state is maintained between userspace and kernel, plus the special case for async flips. Signed-off-by: Pekka Paalanen Signed-off-by: André Almeida --- v4: total rework by Pekka --- Documentation/gpu/drm-uapi.rst | 41 ++ 1 file changed, 41 insertions(+) diff --git a/Documentation/gpu/drm-uapi.rst b/Documentation/gpu/drm-uapi.rst index 65fb3036a580..6a1662c08901 100644 --- a/Documentation/gpu/drm-uapi.rst +++ b/Documentation/gpu/drm-uapi.rst @@ -486,3 +486,44 @@ and the CRTC index is its position in this array. .. kernel-doc:: include/uapi/drm/drm_mode.h :internal: + +KMS atomic state + + +An atomic commit can change multiple KMS properties in an atomic fashion, +without ever applying intermediate or partial state changes. Either the whole +commit succeeds or fails, and it will never be applied partially. This is the +fundamental improvement of the atomic API over the older non-atomic API which is +referred to as the "legacy API". Applying intermediate state could unexpectedly +fail, cause visible glitches, or delay reaching the final state. + +An atomic commit can be flagged with DRM_MODE_ATOMIC_TEST_ONLY, which means the +complete state change is validated but not applied. Userspace should use this +flag to validate any state change before asking to apply it. If validation fails +for any reason, userspace should attempt to fall back to another, perhaps +simpler, final state. This allows userspace to probe for various configurations +without causing visible glitches on screen and without the need to undo a +probing change. + +The changes recorded in an atomic commit apply on top the current KMS state in +the kernel. Hence, the complete new KMS state is the complete old KMS state with +the committed property settings done on top. The kernel will automatically avoid +no-operation changes, so it is safe and even expected for userspace to send +redundant property settings. No-operation changes do not count towards actually +needed changes, e.g. setting MODE_ID to a different blob with identical +contents as the current KMS state shall not be a modeset on its own. + +A "modeset" is a change in KMS state that might enable, disable, or temporarily +disrupt the emitted video signal, possibly causing visible glitches on screen. A +modeset may also take considerably more time to complete than other kinds of +changes, and the video sink might also need time to adapt to the new signal +properties. Therefore a modeset must be explicitly allowed with the flag +DRM_MODE_ATOMIC_ALLOW_MODESET. This in combination with +DRM_MODE_ATOMIC_TEST_ONLY allows userspace to determine if a state change is +likely to cause visible disruption on screen and avoid such changes when end +users do not expect them. + +An atomic commit with the flag DRM_MODE_PAGE_FLIP_ASYNC is allowed to +effectively change only the FB_ID property on any planes. No-operation changes +are ignored as always. Changing any other property will cause the commit to be +rejected. -- 2.41.0