Skip to content

Commit a9b09cc

Browse files
committed
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
1 parent 1ce5726 commit a9b09cc

File tree

1 file changed

+104
-11
lines changed

1 file changed

+104
-11
lines changed

video/out/opengl/context_drm_egl.c

Lines changed: 104 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -247,17 +247,105 @@ static void update_framebuffer_from_bo(struct ra_ctx *ctx, struct gbm_bo *bo)
247247
p->fb = fb;
248248
}
249249

250+
static bool crtc_setup_atomic(struct ra_ctx *ctx, drmModeModeInfo mode)
251+
{
252+
struct priv *p = ctx->priv;
253+
254+
struct drm_atomic_context *atomic_ctx = p->kms->atomic_context;
255+
drmModeAtomicReqPtr request = drmModeAtomicAlloc();
256+
if (request) {
257+
drm_object_set_property(request, atomic_ctx->connector, "CRTC_ID", p->kms->crtc_id);
258+
259+
uint32_t blob_id;
260+
if (drmModeCreatePropertyBlob(p->kms->fd, &mode, sizeof(drmModeModeInfo),
261+
&blob_id) != 0) {
262+
MP_ERR(ctx->vo, "Failed to DRM mode blob\n");
263+
return 0;
264+
}
265+
drm_object_set_property(request, atomic_ctx->crtc, "MODE_ID", blob_id);
266+
drm_object_set_property(request, atomic_ctx->crtc, "ACTIVE", 1);
267+
268+
drm_object_set_property(request, atomic_ctx->osd_plane, "SRC_X", 0);
269+
drm_object_set_property(request, atomic_ctx->osd_plane, "SRC_Y", 0);
270+
drm_object_set_property(request, atomic_ctx->osd_plane, "SRC_W", p->osd_size.width << 16);
271+
drm_object_set_property(request, atomic_ctx->osd_plane, "SRC_H", p->osd_size.height << 16);
272+
drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_X", 0);
273+
drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_Y", 0);
274+
drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_W", mode.hdisplay);
275+
drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_H", mode.vdisplay);
276+
277+
int ret = drmModeAtomicCommit(p->kms->fd, request,
278+
DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT
279+
| DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
280+
281+
if (ret)
282+
MP_WARN(ctx->vo, "Failed to commit ModeSetting atomic request (%d)\n", ret);
283+
284+
drmModeAtomicFree(request);
285+
286+
return ret == 0;
287+
} else {
288+
MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
289+
}
290+
291+
return false;
292+
}
293+
294+
static bool crtc_release_atomic(struct ra_ctx *ctx)
295+
{
296+
struct priv *p = ctx->priv;
297+
298+
struct drm_atomic_context *atomic_ctx = p->kms->atomic_context;
299+
drmModeAtomicReqPtr request = drmModeAtomicAlloc();
300+
if (request) {
301+
drm_object_set_property(request, atomic_ctx->connector, "CRTC_ID", p->old_crtc->crtc_id);
302+
303+
uint32_t blob_id;
304+
if (drmModeCreatePropertyBlob(p->kms->fd, &p->old_crtc->mode, sizeof(drmModeModeInfo),
305+
&blob_id) != 0) {
306+
MP_ERR(ctx->vo, "Failed to DRM mode blob\n");
307+
return 0;
308+
}
309+
drm_object_set_property(request, atomic_ctx->crtc, "MODE_ID", blob_id);
310+
drm_object_set_property(request, atomic_ctx->crtc, "ACTIVE", 1);
311+
drm_object_set_property(request, atomic_ctx->osd_plane, "FB_ID", p->old_crtc->buffer_id);
312+
313+
int ret = drmModeAtomicCommit(p->kms->fd, request,
314+
DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT
315+
| DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
316+
317+
if (ret)
318+
MP_WARN(ctx->vo, "Failed to commit ModeSetting atomic request (%d)\n", ret);
319+
320+
drmModeAtomicFree(request);
321+
322+
return ret == 0;
323+
} else {
324+
MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
325+
}
326+
327+
return false;
328+
}
329+
250330
static bool crtc_setup(struct ra_ctx *ctx)
251331
{
252332
struct priv *p = ctx->priv;
253333
if (p->active)
254334
return true;
255335
p->old_crtc = drmModeGetCrtc(p->kms->fd, p->kms->crtc_id);
256-
int ret = drmModeSetCrtc(p->kms->fd, p->kms->crtc_id, p->fb->id,
257-
0, 0, &p->kms->connector->connector_id, 1,
258-
&p->kms->mode);
259-
p->active = true;
260-
return ret == 0;
336+
337+
if (p->kms->atomic_context) {
338+
int ret = crtc_setup_atomic(ctx, p->kms->mode);
339+
p->active = true;
340+
return ret;
341+
342+
} else {
343+
int ret = drmModeSetCrtc(p->kms->fd, p->kms->crtc_id, p->fb->id,
344+
0, 0, &p->kms->connector->connector_id, 1,
345+
&p->kms->mode);
346+
p->active = true;
347+
return ret == 0;
348+
}
261349
}
262350

263351
static void crtc_release(struct ra_ctx *ctx)
@@ -278,12 +366,17 @@ static void crtc_release(struct ra_ctx *ctx)
278366
}
279367

280368
if (p->old_crtc) {
281-
drmModeSetCrtc(p->kms->fd,
282-
p->old_crtc->crtc_id, p->old_crtc->buffer_id,
283-
p->old_crtc->x, p->old_crtc->y,
284-
&p->kms->connector->connector_id, 1,
285-
&p->old_crtc->mode);
286-
drmModeFreeCrtc(p->old_crtc);
369+
if (p->kms->atomic_context) {
370+
if (!crtc_release_atomic(ctx))
371+
MP_ERR(ctx->vo, "Failed to restore previous mode\n");
372+
} else {
373+
drmModeSetCrtc(p->kms->fd,
374+
p->old_crtc->crtc_id, p->old_crtc->buffer_id,
375+
p->old_crtc->x, p->old_crtc->y,
376+
&p->kms->connector->connector_id, 1,
377+
&p->old_crtc->mode);
378+
}
379+
drmModeFreeCrtc(p->old_crtc);
287380
p->old_crtc = NULL;
288381
}
289382
}

0 commit comments

Comments
 (0)