Commit 4b4af74a authored by Simon Ser's avatar Simon Ser
Browse files

drm: allow DRM_MODE_PAGE_FLIP_ASYNC for atomic commits



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: default avatarSimon Ser <contact@emersion.fr>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Co-developed-by: default avatarAndré Almeida <andrealmeid@igalia.com>
Signed-off-by: default avatarAndré Almeida <andrealmeid@igalia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20231122161941.320564-3-andrealmeid@igalia.com
parent 0e26cc72
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -1368,6 +1368,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)
{
@@ -1409,11 +1421,15 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
	}

	if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) {
		if (!dev->mode_config.async_page_flip) {
			drm_dbg_atomic(dev,
			       "commit failed: invalid flag DRM_MODE_PAGE_FLIP_ASYNC\n");
				       "commit failed: DRM_MODE_PAGE_FLIP_ASYNC not supported\n");
			return -EINVAL;
		}

		async_flip = true;
	}

	/* can't test and expect an event at the same time. */
	if ((arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) &&
			(arg->flags & DRM_MODE_PAGE_FLIP_EVENT)) {
@@ -1514,6 +1530,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) {
+9 −0
Original line number Diff line number Diff line
@@ -957,6 +957,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