diff options
author | Anton Kindestam <antonki@kth.se> | 2018-06-02 12:53:54 +0200 |
---|---|---|
committer | Jan Ekström <jeebjp@gmail.com> | 2018-07-09 02:17:47 +0300 |
commit | 7beee68f8d8617557990a5f860d9d1f99c4ba009 (patch) | |
tree | 592bd1673b1edd902746e4bf39d9c7406d69f987 /video/out/opengl | |
parent | 1298b9d201fc61cfffc6f82d78ae27fc294655b7 (diff) | |
download | mpv-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')
-rw-r--r-- | video/out/opengl/context_drm_egl.c | 56 |
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; |