mirror of
https://github.com/mpv-player/mpv
synced 2024-12-31 19:52:16 +00:00
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.
This commit is contained in:
parent
f61eda0f5e
commit
73a06ffae6
@ -647,6 +647,18 @@ Available video output drivers are:
|
||||
Note: this option is only available with DRM atomic support.
|
||||
(default: display resolution)
|
||||
|
||||
``--drm-vrr-enabled=<no|yes|auto>``
|
||||
Toggle use of Variable Refresh Rate (VRR), aka Freesync or Adapative Sync
|
||||
on compatible systems. VRR allows for the display to be refreshed at any
|
||||
rate within a range (usually ~40Hz-60Hz for 60Hz displays). This can help
|
||||
with playback of 24/25/50fps content. Support depends on the use of a
|
||||
compatible monitor, GPU, and a sufficiently new kernel with drivers
|
||||
that support the feature.
|
||||
|
||||
:no: Do not attempt to enable VRR. (default)
|
||||
:yes: Attempt to enable VRR, whether the capability is reported or not.
|
||||
:auto: Attempt to enable VRR if support is reported.
|
||||
|
||||
``mediacodec_embed`` (Android)
|
||||
Renders ``IMGFMT_MEDIACODEC`` frames directly to an ``android.view.Surface``.
|
||||
Requires ``--hwdec=mediacodec`` for hardware decoding, along with
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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),
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user