summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
authorPhilip Langdale <philipl@overt.org>2022-04-03 20:08:33 -0700
committerPhilip Langdale <github.philipl@overt.org>2022-04-05 20:56:36 -0700
commit73a06ffae663e9fb78c5dff4b6bd01a637296a69 (patch)
tree22672b7d07e0ed0c53ea4817015481143f0b6d6d /video/out
parentf61eda0f5e9f8085003c4c31111db525a438cbc1 (diff)
downloadmpv-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/out')
-rw-r--r--video/out/drm_atomic.c6
-rw-r--r--video/out/drm_atomic.h1
-rw-r--r--video/out/drm_common.c3
-rw-r--r--video/out/drm_common.h1
-rw-r--r--video/out/opengl/context_drm_egl.c18
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);