summaryrefslogtreecommitdiffstats
path: root/video/out/opengl/context_drm_egl.c
diff options
context:
space:
mode:
Diffstat (limited to 'video/out/opengl/context_drm_egl.c')
-rw-r--r--video/out/opengl/context_drm_egl.c205
1 files changed, 107 insertions, 98 deletions
diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c
index 1ba7f5dd05..6aa3d95e79 100644
--- a/video/out/opengl/context_drm_egl.c
+++ b/video/out/opengl/context_drm_egl.c
@@ -81,7 +81,7 @@ struct priv {
struct vt_switcher vt_switcher;
struct mpv_opengl_drm_params drm_params;
- struct mpv_opengl_drm_osd_size osd_size;
+ struct mpv_opengl_drm_draw_surface_size draw_surface_size;
};
// Not general. Limited to only the formats being used in this module
@@ -195,11 +195,11 @@ static bool init_gbm(struct ra_ctx *ctx)
}
MP_VERBOSE(ctx->vo, "Initializing GBM surface (%d x %d)\n",
- p->osd_size.width, p->osd_size.height);
+ p->draw_surface_size.width, p->draw_surface_size.height);
p->gbm.surface = gbm_surface_create(
p->gbm.device,
- p->osd_size.width,
- p->osd_size.height,
+ p->draw_surface_size.width,
+ p->draw_surface_size.height,
p->gbm_format,
GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
if (!p->gbm.surface) {
@@ -252,53 +252,54 @@ 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) {
- if (drm_object_set_property(request, atomic_ctx->connector, "CRTC_ID", p->kms->crtc_id) < 0) {
- MP_ERR(ctx->vo, "Could not set CRTC_ID on connector\n");
- return false;
- }
+ if (!request) {
+ MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
+ return false;
+ }
- uint32_t blob_id;
- if (drmModeCreatePropertyBlob(p->kms->fd, &p->kms->mode, sizeof(drmModeModeInfo),
- &blob_id) != 0) {
- MP_ERR(ctx->vo, "Failed to create DRM mode blob\n");
- return false;
- }
- if (drm_object_set_property(request, atomic_ctx->crtc, "MODE_ID", blob_id) < 0) {
- MP_ERR(ctx->vo, "Could not set MODE_ID on crtc\n");
- return false;
- }
- if (drm_object_set_property(request, atomic_ctx->crtc, "ACTIVE", 1) < 0) {
- MP_ERR(ctx->vo, "Could not set ACTIVE on crtc\n");
- return false;
- }
+ if (drm_object_set_property(request, atomic_ctx->connector, "CRTC_ID", p->kms->crtc_id) < 0) {
+ MP_ERR(ctx->vo, "Could not set CRTC_ID on connector\n");
+ return false;
+ }
- drm_object_set_property(request, atomic_ctx->osd_plane, "FB_ID", p->fb->id);
- drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_ID", p->kms->crtc_id);
- 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", p->kms->mode.hdisplay);
- drm_object_set_property(request, atomic_ctx->osd_plane, "CRTC_H", p->kms->mode.vdisplay);
-
- int ret = drmModeAtomicCommit(p->kms->fd, request, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
- if (ret) {
- MP_ERR(ctx->vo, "Failed to commit ModeSetting atomic request (%d)\n", ret);
- drmModeAtomicFree(request);
- return false;
- }
+ if (!drm_mode_ensure_blob(p->kms->fd, &p->kms->mode)) {
+ MP_ERR(ctx->vo, "Failed to create DRM mode blob\n");
+ goto err;
+ }
+ 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;
+ }
+ if (drm_object_set_property(request, atomic_ctx->crtc, "ACTIVE", 1) < 0) {
+ MP_ERR(ctx->vo, "Could not set ACTIVE on crtc\n");
+ goto err;
+ }
- drmModeAtomicFree(request);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "FB_ID", p->fb->id);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "CRTC_ID", p->kms->crtc_id);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "SRC_X", 0);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "SRC_Y", 0);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "SRC_W", p->draw_surface_size.width << 16);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "SRC_H", p->draw_surface_size.height << 16);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "CRTC_X", 0);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "CRTC_Y", 0);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "CRTC_W", p->kms->mode.mode.hdisplay);
+ drm_object_set_property(request, atomic_ctx->draw_plane, "CRTC_H", p->kms->mode.mode.vdisplay);
- return ret == 0;
- } else {
- MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
- }
+ int ret = drmModeAtomicCommit(p->kms->fd, request, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+ if (ret)
+ MP_ERR(ctx->vo, "Failed to commit ModeSetting atomic request (%d)\n", ret);
+ drmModeAtomicFree(request);
+ return ret == 0;
+
+ err:
+ drmModeAtomicFree(request);
return false;
}
@@ -308,32 +309,22 @@ static bool crtc_release_atomic(struct ra_ctx *ctx)
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 create DRM mode blob\n");
- return false;
- }
- 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);
+ if (!request) {
+ MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
+ return false;
+ }
- int ret = drmModeAtomicCommit(p->kms->fd, request, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
+ if (!drm_atomic_restore_old_state(request, atomic_ctx)) {
+ MP_WARN(ctx->vo, "Got error while restoring old state\n");
+ }
- if (ret)
- MP_WARN(ctx->vo, "Failed to commit ModeSetting atomic request (%d)\n", ret);
+ int ret = drmModeAtomicCommit(p->kms->fd, request, DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
- drmModeAtomicFree(request);
+ if (ret)
+ MP_WARN(ctx->vo, "Failed to commit ModeSetting atomic request (%d)\n", ret);
- return ret == 0;
- } else {
- MP_ERR(ctx->vo, "Failed to allocate drm atomic request\n");
- }
-
- return false;
+ drmModeAtomicFree(request);
+ return ret == 0;
}
static bool crtc_setup(struct ra_ctx *ctx)
@@ -341,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;
}
@@ -373,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;
}
}
@@ -453,9 +446,9 @@ static void drm_egl_swap_buffers(struct ra_ctx *ctx)
update_framebuffer_from_bo(ctx, p->gbm.next_bo);
if (atomic_ctx) {
- drm_object_set_property(atomic_ctx->request, atomic_ctx->osd_plane, "FB_ID", p->fb->id);
- drm_object_set_property(atomic_ctx->request, atomic_ctx->osd_plane, "CRTC_ID", atomic_ctx->crtc->id);
- drm_object_set_property(atomic_ctx->request, atomic_ctx->osd_plane, "ZPOS", 1);
+ drm_object_set_property(atomic_ctx->request, atomic_ctx->draw_plane, "FB_ID", p->fb->id);
+ drm_object_set_property(atomic_ctx->request, atomic_ctx->draw_plane, "CRTC_ID", atomic_ctx->crtc->id);
+ drm_object_set_property(atomic_ctx->request, atomic_ctx->draw_plane, "ZPOS", 1);
ret = drmModeAtomicCommit(p->kms->fd, atomic_ctx->request,
DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, NULL);
@@ -520,30 +513,32 @@ static void drm_egl_uninit(struct ra_ctx *ctx)
p->egl.context = EGL_NO_CONTEXT;
eglDestroyContext(p->egl.display, p->egl.context);
+ close(p->drm_params.render_fd);
+
if (p->kms) {
kms_destroy(p->kms);
p->kms = 0;
}
}
-// If the OSD plane supports ARGB we want to use that, but if it doesn't we fall
-// back on XRGB. If the driver does not support atomic there is no particular
-// reason to be using ARGB (drmprime hwdec will not work without atomic,
-// anyway), so we fall back to XRGB (another reason is that we do not have the
-// convenient atomic_ctx and its convenient plane fields).
+// If the draw plane supports ARGB we want to use that, but if it doesn't we
+// fall back on XRGB. If we do not have atomic there is no particular reason to
+// be using ARGB (drmprime hwdec will not work without atomic, anyway), so we
+// fall back to XRGB (another reason is that we do not have the convenient
+// atomic_ctx and its convenient plane fields).
static bool probe_gbm_format(struct ra_ctx *ctx, uint32_t argb_format, uint32_t xrgb_format)
{
struct priv *p = ctx->priv;
if (!p->kms->atomic_context) {
p->gbm_format = xrgb_format;
- MP_VERBOSE(ctx->vo, "Not using DRM Atomic: Use %s for OSD plane.\n",
+ MP_VERBOSE(ctx->vo, "Not using DRM Atomic: Use %s for draw plane.\n",
gbm_format_to_string(xrgb_format));
return true;
}
drmModePlane *drmplane =
- drmModeGetPlane(p->kms->fd, p->kms->atomic_context->osd_plane->id);
+ drmModeGetPlane(p->kms->fd, p->kms->atomic_context->draw_plane->id);
bool have_argb = false;
bool have_xrgb = false;
bool result = false;
@@ -557,11 +552,11 @@ static bool probe_gbm_format(struct ra_ctx *ctx, uint32_t argb_format, uint32_t
if (have_argb) {
p->gbm_format = argb_format;
- MP_VERBOSE(ctx->vo, "%s supported by OSD plane.\n", gbm_format_to_string(argb_format));
+ MP_VERBOSE(ctx->vo, "%s supported by draw plane.\n", gbm_format_to_string(argb_format));
result = true;
} else if (have_xrgb) {
p->gbm_format = xrgb_format;
- MP_VERBOSE(ctx->vo, "%s not supported by OSD plane: Falling back to %s.\n",
+ MP_VERBOSE(ctx->vo, "%s not supported by draw plane: Falling back to %s.\n",
gbm_format_to_string(argb_format), gbm_format_to_string(xrgb_format));
result = true;
}
@@ -591,25 +586,25 @@ static bool drm_egl_init(struct ra_ctx *ctx)
MP_VERBOSE(ctx, "Initializing KMS\n");
p->kms = kms_create(ctx->log, ctx->vo->opts->drm_opts->drm_connector_spec,
ctx->vo->opts->drm_opts->drm_mode_id,
- ctx->vo->opts->drm_opts->drm_osd_plane_id,
- ctx->vo->opts->drm_opts->drm_video_plane_id);
+ ctx->vo->opts->drm_opts->drm_draw_plane,
+ ctx->vo->opts->drm_opts->drm_drmprime_video_plane);
if (!p->kms) {
MP_ERR(ctx, "Failed to create KMS.\n");
return false;
}
- if (ctx->vo->opts->drm_opts->drm_osd_size.wh_valid) {
+ if (ctx->vo->opts->drm_opts->drm_draw_surface_size.wh_valid) {
if (p->kms->atomic_context) {
- 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;
+ p->draw_surface_size.width = ctx->vo->opts->drm_opts->drm_draw_surface_size.w;
+ p->draw_surface_size.height = ctx->vo->opts->drm_opts->drm_draw_surface_size.h;
} else {
- p->osd_size.width = p->kms->mode.hdisplay;
- p->osd_size.height = p->kms->mode.vdisplay;
- MP_WARN(ctx, "Setting OSD size is only available with DRM atomic, defaulting to screen resolution\n");
+ p->draw_surface_size.width = p->kms->mode.mode.hdisplay;
+ p->draw_surface_size.height = p->kms->mode.mode.vdisplay;
+ MP_WARN(ctx, "Setting draw plane 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->draw_surface_size.width = p->kms->mode.mode.hdisplay;
+ p->draw_surface_size.height = p->kms->mode.mode.vdisplay;
}
uint32_t argb_format;
@@ -623,7 +618,7 @@ static bool drm_egl_init(struct ra_ctx *ctx)
}
if (!probe_gbm_format(ctx, argb_format, xrgb_format)) {
- MP_ERR(ctx->vo, "No suitable format found on DRM primary plane (tried: %s and %s).\n",
+ MP_ERR(ctx->vo, "No suitable format found on draw plane (tried: %s and %s).\n",
gbm_format_to_string(argb_format), gbm_format_to_string(xrgb_format));
return false;
}
@@ -671,6 +666,20 @@ static bool drm_egl_init(struct ra_ctx *ctx)
p->drm_params.connector_id = p->kms->connector->connector_id;
if (p->kms->atomic_context)
p->drm_params.atomic_request_ptr = &p->kms->atomic_context->request;
+ char *rendernode_path = drmGetRenderDeviceNameFromFd(p->kms->fd);
+ if (rendernode_path) {
+ MP_VERBOSE(ctx, "Opening render node \"%s\"\n", rendernode_path);
+ p->drm_params.render_fd = open(rendernode_path, O_RDWR | O_CLOEXEC);
+ if (p->drm_params.render_fd < 0) {
+ MP_WARN(ctx, "Cannot open render node \"%s\": %s. VAAPI hwdec will be disabled\n",
+ rendernode_path, mp_strerror(errno));
+ }
+ free(rendernode_path);
+ } else {
+ p->drm_params.render_fd = -1;
+ MP_VERBOSE(ctx, "Could not find path to render node. VAAPI hwdec will be disabled\n");
+ }
+
struct ra_gl_ctx_params params = {
.swap_buffers = drm_egl_swap_buffers,
.external_swapchain = p->kms->atomic_context ? &drm_atomic_swapchain :
@@ -680,7 +689,7 @@ static bool drm_egl_init(struct ra_ctx *ctx)
return false;
ra_add_native_resource(ctx->ra, "drm_params", &p->drm_params);
- ra_add_native_resource(ctx->ra, "drm_osd_size", &p->osd_size);
+ ra_add_native_resource(ctx->ra, "drm_draw_surface_size", &p->draw_surface_size);
return true;
}