diff options
author | Philip Langdale <philipl@overt.org> | 2022-04-03 20:08:33 -0700 |
---|---|---|
committer | Philip Langdale <github.philipl@overt.org> | 2022-04-05 20:56:36 -0700 |
commit | 73a06ffae663e9fb78c5dff4b6bd01a637296a69 (patch) | |
tree | 22672b7d07e0ed0c53ea4817015481143f0b6d6d /video | |
parent | f61eda0f5e9f8085003c4c31111db525a438cbc1 (diff) | |
download | mpv-73a06ffae663e9fb78c5dff4b6bd01a637296a69.tar.bz2 mpv-73a06ffae663e9fb78c5dff4b6bd01a637296a69.tar.xz |
drm: context_drm_egl: add support for enabling VRR
Variable Refresh Rate (VRR), aka Freesync or Adaptive Sync can be used
with DRM by setting the VRR_ENABLED property on a crtc if the
connector reports that it is VRR_CAPABLE. This is a useful feature
for us as it is common to play 24/25/50 fps content on displays that
are nominally locked to 60Hz. VRR can allow this content to play at
native framerates.
This is a simple change as we just need to check the capability
and set the enabled property if requested by the user. I've defaulted
it to disabled for now, but it might make sense to default to auto
in the long term.
Diffstat (limited to 'video')
-rw-r--r-- | video/out/drm_atomic.c | 6 | ||||
-rw-r--r-- | video/out/drm_atomic.h | 1 | ||||
-rw-r--r-- | video/out/drm_common.c | 3 | ||||
-rw-r--r-- | video/out/drm_common.h | 1 | ||||
-rw-r--r-- | video/out/opengl/context_drm_egl.c | 18 |
5 files changed, 29 insertions, 0 deletions
diff --git a/video/out/drm_atomic.c b/video/out/drm_atomic.c index bf7012c155..e615d2f9c7 100644 --- a/video/out/drm_atomic.c +++ b/video/out/drm_atomic.c @@ -389,6 +389,9 @@ bool drm_atomic_save_old_state(struct drm_atomic_context *ctx) if (0 > drm_object_get_property(ctx->crtc, "ACTIVE", &ctx->old_state.crtc.active)) ret = false; + // This property was added in kernel 5.0. We will just ignore any errors. + drm_object_get_property(ctx->crtc, "VRR_ENABLED", &ctx->old_state.crtc.vrr_enabled); + if (0 > drm_object_get_property(ctx->connector, "CRTC_ID", &ctx->old_state.connector.crtc_id)) ret = false; @@ -412,6 +415,9 @@ bool drm_atomic_restore_old_state(drmModeAtomicReqPtr request, struct drm_atomic if (0 > drm_object_set_property(request, ctx->connector, "CRTC_ID", ctx->old_state.connector.crtc_id)) ret = false; + // This property was added in kernel 5.0. We will just ignore any errors. + drm_object_set_property(request, ctx->crtc, "VRR_ENABLED", ctx->old_state.crtc.vrr_enabled); + if (!drm_mode_ensure_blob(ctx->fd, &ctx->old_state.crtc.mode)) ret = false; if (0 > drm_object_set_property(request, ctx->crtc, "MODE_ID", ctx->old_state.crtc.mode.blob_id)) diff --git a/video/out/drm_atomic.h b/video/out/drm_atomic.h index 5b2dc5976d..32e56c7f97 100644 --- a/video/out/drm_atomic.h +++ b/video/out/drm_atomic.h @@ -56,6 +56,7 @@ struct drm_atomic_state { struct { struct drm_mode mode; uint64_t active; + uint64_t vrr_enabled; } crtc; struct drm_atomic_plane_state draw_plane; struct drm_atomic_plane_state drmprime_video_plane; diff --git a/video/out/drm_common.c b/video/out/drm_common.c index aa86b7750b..dad9aaf2fb 100644 --- a/video/out/drm_common.c +++ b/video/out/drm_common.c @@ -98,6 +98,8 @@ const struct m_sub_options drm_conf = { {"drm-osd-plane-id", OPT_REPLACED("drm-draw-plane")}, {"drm-video-plane-id", OPT_REPLACED("drm-drmprime-video-plane")}, {"drm-osd-size", OPT_REPLACED("drm-draw-surface-size")}, + {"drm-vrr-enabled", OPT_CHOICE(drm_vrr_enabled, + {"no", 0}, {"yes", 1}, {"auto", -1})}, {0}, }, .defaults = &(const struct drm_opts) { @@ -105,6 +107,7 @@ const struct m_sub_options drm_conf = { .drm_atomic = 1, .drm_draw_plane = DRM_OPTS_PRIMARY_PLANE, .drm_drmprime_video_plane = DRM_OPTS_OVERLAY_PLANE, + .drm_vrr_enabled = 0, }, .size = sizeof(struct drm_opts), }; diff --git a/video/out/drm_common.h b/video/out/drm_common.h index d8a550e4f1..5d884e3c80 100644 --- a/video/out/drm_common.h +++ b/video/out/drm_common.h @@ -57,6 +57,7 @@ struct drm_opts { int drm_drmprime_video_plane; int drm_format; struct m_geometry drm_draw_surface_size; + int drm_vrr_enabled; }; struct drm_vsync_tuple { diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c index a7f99cfd0d..b571ca7057 100644 --- a/video/out/opengl/context_drm_egl.c +++ b/video/out/opengl/context_drm_egl.c @@ -372,6 +372,24 @@ static bool crtc_setup_atomic(struct ra_ctx *ctx) goto err; } + /* + * VRR related properties were added in kernel 5.0. We will not fail if we + * cannot query or set the value, but we will log as appropriate. + */ + uint64_t vrr_capable = 0; + drm_object_get_property(atomic_ctx->connector, "VRR_CAPABLE", &vrr_capable); + MP_VERBOSE(ctx->vo, "crtc is%s VRR capable\n", vrr_capable ? "" : " not"); + + uint64_t vrr_requested = ctx->vo->opts->drm_opts->drm_vrr_enabled; + if (vrr_requested == 1 || (vrr_capable && vrr_requested == -1)) { + if (drm_object_set_property(request, atomic_ctx->crtc, "VRR_ENABLED", 1) < 0) { + MP_WARN(ctx->vo, "Could not enable VRR on crtc\n"); + } else { + MP_VERBOSE(ctx->vo, "Enabled VRR on crtc\n"); + } + } + + drm_object_set_property(request, atomic_ctx->draw_plane, "FB_ID", p->fb->id); drm_object_set_property(request, atomic_ctx->draw_plane, "CRTC_ID", p->kms->crtc_id); drm_object_set_property(request, atomic_ctx->draw_plane, "SRC_X", 0); |