diff options
Diffstat (limited to 'video/out/opengl/context_drm_egl.c')
-rw-r--r-- | video/out/opengl/context_drm_egl.c | 205 |
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; } |