summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLongChair <longchair@hotmail.com>2018-04-07 08:56:59 +0200
committerJan Ekström <jeebjp@gmail.com>2018-05-01 20:48:02 +0300
commit1ccc56eff0242123ba448638f4cc534fb69e3024 (patch)
tree241e02d33fc953fa400ee120e4645c1580d2ca75
parented94f8dc00dd75bf5d88bdf73b9d69a579c0f8ef (diff)
downloadmpv-1ccc56eff0242123ba448638f4cc534fb69e3024.tar.bz2
mpv-1ccc56eff0242123ba448638f4cc534fb69e3024.tar.xz
drm/atomic: add atomic modesetting.
This commit allows to add atomic modesetting when using the atomic renderer. This is actually needed when using and osd with a smaller size than screen resolution. It will also make the drm atomic path more consistent
-rw-r--r--video/out/opengl/context_drm_egl.c115
1 files changed, 104 insertions, 11 deletions
diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c
index c0f7fa244e..1fddbb1c37 100644
--- a/video/out/opengl/context_drm_egl.c
+++ b/video/out/opengl/context_drm_egl.c
@@ -247,17 +247,105 @@ static void update_framebuffer_from_bo(struct ra_ctx *ctx, struct gbm_bo *bo)
p->fb = fb;
}
+static bool crtc_setup_atomic(struct ra_ctx *ctx, drmModeModeInfo mode)
+{
+ struct priv *p = ctx->priv;
+
+ struct drm_atomic_context *atomic_ctx = p->kms->atomic_context;
+ drmModeAtomicReqPtr request = drmModeAtomicAlloc();
+ if (request) {
+ drm_object_set_property(request, atomic_ctx->connector, "CRTC_ID", p->kms->crtc_id);
+
+ uint32_t blob_id;
+ if (drmModeCreatePropertyBlob(p->kms->fd, &mode, sizeof(drmModeModeInfo),
+ &blob_id) != 0) {
+ MP_ERR(ctx->vo, "Failed to DRM mode blob\n");
+ return 0;
+ }
+ drm_object_set_property(request, atomic_ctx->crtc, "MODE_ID", blob_id);
+ drm_object_set_property(request, atomic_ctx->crtc, "ACTIVE", 1);
+
+ drm_object_set_property(request, atomic_ctx->osd_plane, "SRC_X", 0);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "SRC_Y", 0);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "SRC_W", p->osd_size.width << 16);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "SRC_H", p->osd_size.height << 16);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_X", 0);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_Y", 0);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_W", mode.hdisplay);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_H", mode.vdisplay);
+
+ int ret = drmModeAtomicCommit(p->kms->fd, request,
+ DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT
+ | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ if (ret)
+ MP_WARN(ctx->vo, "Failed to commit ModeSetting atomic request (%d)\n", ret);
+
+ drmModeAtomicFree(request);
+
+ return ret == 0;
+ } else {
+ MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
+ }
+
+ return false;
+}
+
+static bool crtc_release_atomic(struct ra_ctx *ctx)
+{
+ struct priv *p = ctx->priv;
+
+ struct drm_atomic_context *atomic_ctx = p->kms->atomic_context;
+ drmModeAtomicReqPtr request = drmModeAtomicAlloc();
+ if (request) {
+ drm_object_set_property(request, atomic_ctx->connector, "CRTC_ID", p->old_crtc->crtc_id);
+
+ uint32_t blob_id;
+ if (drmModeCreatePropertyBlob(p->kms->fd, &p->old_crtc->mode, sizeof(drmModeModeInfo),
+ &blob_id) != 0) {
+ MP_ERR(ctx->vo, "Failed to DRM mode blob\n");
+ return 0;
+ }
+ drm_object_set_property(request, atomic_ctx->crtc, "MODE_ID", blob_id);
+ drm_object_set_property(request, atomic_ctx->crtc, "ACTIVE", 1);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "FB_ID", p->old_crtc->buffer_id);
+
+ int ret = drmModeAtomicCommit(p->kms->fd, request,
+ DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT
+ | DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+
+ if (ret)
+ MP_WARN(ctx->vo, "Failed to commit ModeSetting atomic request (%d)\n", ret);
+
+ drmModeAtomicFree(request);
+
+ return ret == 0;
+ } else {
+ MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
+ }
+
+ return false;
+}
+
static bool crtc_setup(struct ra_ctx *ctx)
{
struct priv *p = ctx->priv;
if (p->active)
return true;
p->old_crtc = drmModeGetCrtc(p->kms->fd, p->kms->crtc_id);
- int ret = drmModeSetCrtc(p->kms->fd, p->kms->crtc_id, p->fb->id,
- 0, 0, &p->kms->connector->connector_id, 1,
- &p->kms->mode);
- p->active = true;
- return ret == 0;
+
+ if (p->kms->atomic_context) {
+ int ret = crtc_setup_atomic(ctx, p->kms->mode);
+ p->active = true;
+ return ret;
+
+ } else {
+ int ret = drmModeSetCrtc(p->kms->fd, p->kms->crtc_id, p->fb->id,
+ 0, 0, &p->kms->connector->connector_id, 1,
+ &p->kms->mode);
+ p->active = true;
+ return ret == 0;
+ }
}
static void crtc_release(struct ra_ctx *ctx)
@@ -278,12 +366,17 @@ static void crtc_release(struct ra_ctx *ctx)
}
if (p->old_crtc) {
- drmModeSetCrtc(p->kms->fd,
- p->old_crtc->crtc_id, p->old_crtc->buffer_id,
- p->old_crtc->x, p->old_crtc->y,
- &p->kms->connector->connector_id, 1,
- &p->old_crtc->mode);
- drmModeFreeCrtc(p->old_crtc);
+ if (p->kms->atomic_context) {
+ if (!crtc_release_atomic(ctx))
+ MP_ERR(ctx->vo, "Failed to restore previous mode\n");
+ } else {
+ drmModeSetCrtc(p->kms->fd,
+ p->old_crtc->crtc_id, p->old_crtc->buffer_id,
+ p->old_crtc->x, p->old_crtc->y,
+ &p->kms->connector->connector_id, 1,
+ &p->old_crtc->mode);
+ }
+ drmModeFreeCrtc(p->old_crtc);
p->old_crtc = NULL;
}
}