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

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
...@@ -1368,6 +1368,18 @@ static void complete_signaling(struct drm_device *dev, ...@@ -1368,6 +1368,18 @@ static void complete_signaling(struct drm_device *dev,
kfree(fence_state); 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, int drm_mode_atomic_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv) void *data, struct drm_file *file_priv)
{ {
...@@ -1409,9 +1421,13 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, ...@@ -1409,9 +1421,13 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
} }
if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) { if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC) {
drm_dbg_atomic(dev, if (!dev->mode_config.async_page_flip) {
"commit failed: invalid flag DRM_MODE_PAGE_FLIP_ASYNC\n"); drm_dbg_atomic(dev,
return -EINVAL; "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. */ /* can't test and expect an event at the same time. */
...@@ -1514,6 +1530,9 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, ...@@ -1514,6 +1530,9 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
if (ret) if (ret)
goto out; goto out;
if (arg->flags & DRM_MODE_PAGE_FLIP_ASYNC)
set_async_flip(state);
if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) { if (arg->flags & DRM_MODE_ATOMIC_TEST_ONLY) {
ret = drm_atomic_check_only(state); ret = drm_atomic_check_only(state);
} else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
......
...@@ -957,6 +957,15 @@ struct hdr_output_metadata { ...@@ -957,6 +957,15 @@ struct hdr_output_metadata {
* Request that the page-flip is performed as soon as possible, ie. with no * 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 * delay due to waiting for vblank. This may cause tearing to be visible on
* the screen. * 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_ASYNC 0x02
#define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment