1
0
mirror of https://github.com/mpv-player/mpv synced 2025-02-11 17:37:01 +00:00

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
This commit is contained in:
LongChair 2018-04-07 08:56:59 +02:00 committed by Jan Ekström
parent ed94f8dc00
commit 1ccc56eff0

View File

@ -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,11 +366,16 @@ 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);
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;
}