summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/context_drm_egl.c
diff options
context:
space:
mode:
authorAnton Kindestam <antonki@kth.se>2018-06-02 12:53:54 +0200
committerJan Ekström <jeebjp@gmail.com>2018-07-09 02:17:47 +0300
commit7beee68f8d8617557990a5f860d9d1f99c4ba009 (patch)
tree592bd1673b1edd902746e4bf39d9c7406d69f987 /video/out/opengl/context_drm_egl.c
parent1298b9d201fc61cfffc6f82d78ae27fc294655b7 (diff)
downloadmpv-7beee68f8d8617557990a5f860d9d1f99c4ba009.tar.bz2
mpv-7beee68f8d8617557990a5f860d9d1f99c4ba009.tar.xz
context_drm_egl: Fix CRTC setup and release code when using atomic
The previous code did not save enough information about the old state, and could end up changing what plane the fbcon:s FB got attached to, or in worse case causing a blank screen (observed in some multi-screen setups on Sandy Bridge). In addition refactor the handling of drmModeModeInfo property blobs to not leak, as well as enable reuse of already created blobs.
Diffstat (limited to 'video/out/opengl/context_drm_egl.c')
-rw-r--r--video/out/opengl/context_drm_egl.c56
1 files changed, 23 insertions, 33 deletions
diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c
index c101a5b809..52774d8170 100644
--- a/video/out/opengl/context_drm_egl.c
+++ b/video/out/opengl/context_drm_egl.c
@@ -252,6 +252,10 @@ static bool crtc_setup_atomic(struct ra_ctx *ctx)
struct priv *p = ctx->priv;
struct drm_atomic_context *atomic_ctx = p->kms->atomic_context;
+ if (!drm_atomic_save_old_state(atomic_ctx)) {
+ MP_WARN(ctx->vo, "Failed to save old DRM atomic state\n");
+ }
+
drmModeAtomicReqPtr request = drmModeAtomicAlloc();
if (!request) {
MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
@@ -263,14 +267,11 @@ static bool crtc_setup_atomic(struct ra_ctx *ctx)
return false;
}
- uint32_t blob_id = 0;
- if (drmModeCreatePropertyBlob(p->kms->fd, &p->kms->mode, sizeof(drmModeModeInfo),
- &blob_id) != 0) {
+ if (!drm_mode_ensure_blob(p->kms->fd, &p->kms->mode)) {
MP_ERR(ctx->vo, "Failed to create DRM mode blob\n");
- blob_id = 0;
goto err;
}
- if (drm_object_set_property(request, atomic_ctx->crtc, "MODE_ID", blob_id) < 0) {
+ if (drm_object_set_property(request, atomic_ctx->crtc, "MODE_ID", p->kms->mode.blob_id) < 0) {
MP_ERR(ctx->vo, "Could not set MODE_ID on crtc\n");
goto err;
}
@@ -287,8 +288,8 @@ static bool crtc_setup_atomic(struct ra_ctx *ctx)
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", p->kms->mode.hdisplay);
- drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_H", p->kms->mode.vdisplay);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_W", p->kms->mode.mode.hdisplay);
+ drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_H", p->kms->mode.mode.vdisplay);
int ret = drmModeAtomicCommit(p->kms->fd, request, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
if (ret)
@@ -298,8 +299,6 @@ static bool crtc_setup_atomic(struct ra_ctx *ctx)
return ret == 0;
err:
- if (blob_id)
- drmModeDestroyPropertyBlob(p->kms->fd, blob_id);
drmModeAtomicFree(request);
return false;
}
@@ -314,17 +313,10 @@ static bool crtc_release_atomic(struct ra_ctx *ctx)
MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
return false;
}
- 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 create DRM mode blob\n");
- goto err;
+ if (!drm_atomic_restore_old_state(request, atomic_ctx)) {
+ MP_WARN(ctx->vo, "Got error while restoring old state\n");
}
- 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_ALLOW_MODESET, NULL);
@@ -333,10 +325,6 @@ static bool crtc_release_atomic(struct ra_ctx *ctx)
drmModeAtomicFree(request);
return ret == 0;
-
- err:
- drmModeAtomicFree(request);
- return false;
}
static bool crtc_setup(struct ra_ctx *ctx)
@@ -344,16 +332,16 @@ 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);
if (p->kms->atomic_context) {
int ret = crtc_setup_atomic(ctx);
p->active = true;
return ret;
} else {
+ 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->kms->mode.mode);
p->active = true;
return ret == 0;
}
@@ -376,19 +364,21 @@ static void crtc_release(struct ra_ctx *ctx)
}
}
- if (p->old_crtc) {
- if (p->kms->atomic_context) {
+ if (p->kms->atomic_context) {
+ if (p->kms->atomic_context->old_state.saved) {
if (!crtc_release_atomic(ctx))
MP_ERR(ctx->vo, "Failed to restore previous mode\n");
- } else {
+ }
+ } else {
+ 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);
+ p->old_crtc = NULL;
}
- drmModeFreeCrtc(p->old_crtc);
- p->old_crtc = NULL;
}
}
@@ -606,13 +596,13 @@ static bool drm_egl_init(struct ra_ctx *ctx)
p->osd_size.width = ctx->vo->opts->drm_opts->drm_osd_size.w;
p->osd_size.height = ctx->vo->opts->drm_opts->drm_osd_size.h;
} else {
- p->osd_size.width = p->kms->mode.hdisplay;
- p->osd_size.height = p->kms->mode.vdisplay;
+ p->osd_size.width = p->kms->mode.mode.hdisplay;
+ p->osd_size.height = p->kms->mode.mode.vdisplay;
MP_WARN(ctx, "Setting OSD size is only available with DRM atomic, defaulting to screen resolution\n");
}
} else {
- p->osd_size.width = p->kms->mode.hdisplay;
- p->osd_size.height = p->kms->mode.vdisplay;
+ p->osd_size.width = p->kms->mode.mode.hdisplay;
+ p->osd_size.height = p->kms->mode.mode.vdisplay;
}
uint32_t argb_format;