diff --git a/video/out/drm_atomic.c b/video/out/drm_atomic.c index e6f7cdbd7e7cb..3cdbd5183a074 100644 --- a/video/out/drm_atomic.c +++ b/video/out/drm_atomic.c @@ -137,6 +137,75 @@ void drm_object_print_info(struct mp_log *log, struct drm_object *object) (long long)object->props->prop_values[i]); } +static int drm_atomic_get_plane_id_by_type(const drmModePlaneRes *plane_res, int crtc_index) +{ + drmModePlane *drmplane = NULL; + + for (unsigned int j = 0; j < plane_res->count_planes; j++) { + drmplane = drmModeGetPlane(ctx->fd, plane_res->planes[j]); + if (drmplane->possible_crtcs & (1 << crtc_index)) { + plane = drm_object_create(log, ctx->fd, drmplane->plane_id, + DRM_MODE_OBJECT_PLANE); + + if (plane) { + if (drm_object_get_property(plane, "TYPE", &value) == -EINVAL) { + mp_err(log, "Unable to retrieve type property from plane %d\n", j); + goto fail; + } else { + if (value == plane_type) + return drmplane->plane_id; + + drm_object_free(plane); + plane = NULL; + } + } else { + mp_err(log, "Failed to create Plane object from plane ID %d\n", + drmplane->plane_id); + goto fail; + } + } + drmModeFreePlane(drmplane); + drmplane = NULL; + } +} + +static int drm_atomic_get_plane_id_by_idx(const drmModePlaneRes *plane_res, int crtc_index) +{ + int layercount = -1; + + for (unsigned int j = 0; j < plane_res->count_planes; j++) { + drmplane = drmModeGetPlane(ctx->fd, plane_res->planes[j]); + if (drmplane->possible_crtcs & (1 << crtc_index)) { + plane = drm_object_create(log, ctx->fd, drmplane->plane_id, + DRM_MODE_OBJECT_PLANE); + + if (plane) { + if (drm_object_get_property(plane, "TYPE", &value) == -EINVAL) { + mp_err(log, "Unable to retrieve type property from plane %d\n", j); + goto fail; + } else { + if (value == DRM_PLANE_TYPE_CURSOR) // Skip cursor planes + continue; + + layercount++; + + if (layercount == plane_idx) + return drmplane->plane_id; + + drm_object_free(plane); + plane = NULL; + } + } else { + mp_err(log, "Failed to create Plane object from plane ID %d\n", + drmplane->plane_id); + goto fail; + } + } + drmModeFreePlane(drmplane); + drmplane = NULL; + } +} + struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, int crtc_id, int connector_id, int osd_plane_id, int video_plane_id) { @@ -198,8 +267,7 @@ struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, } for (unsigned int j = 0; j < plane_res->count_planes; j++) { - - drmplane = drmModeGetPlane (ctx->fd, plane_res->planes[j]); + drmplane = drmModeGetPlane(ctx->fd, plane_res->planes[j]); if (drmplane->possible_crtcs & (1 << crtc_index)) { plane = drm_object_create(log, ctx->fd, drmplane->plane_id, DRM_MODE_OBJECT_PLANE); @@ -282,8 +350,6 @@ struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, drmModeFreeResources(res); if (plane_res) drmModeFreePlaneResources(plane_res); - if (drmplane) - drmModeFreePlane(drmplane); if (plane) drm_object_free(plane); return NULL; diff --git a/video/out/drm_common.c b/video/out/drm_common.c index df06744fbe6bd..426dc54932a32 100644 --- a/video/out/drm_common.c +++ b/video/out/drm_common.c @@ -47,8 +47,12 @@ const struct m_sub_options drm_conf = { OPT_STRING_VALIDATE("drm-connector", drm_connector_spec, 0, drm_validate_connector_opt), OPT_INT("drm-mode", drm_mode_id, 0), - OPT_INT("drm-osd-plane-id", drm_osd_plane_id, 0), - OPT_INT("drm-video-plane-id", drm_video_plane_id, 0), + OPT_CHOICE_OR_INT("drm-osd-plane-id", drm_osd_plane_id, 0, 0, INT_MAX, + ({"primary", DRM_OPTS_PRIMARY_PLANE}, + {"overlay", DRM_OPTS_OVERLAY_PLANE})), + OPT_CHOICE_OR_INT("drm-video-plane-id", drm_video_plane_id, 0, INT_MAX, + ({"primary", DRM_OPTS_PRIMARY_PLANE}, + {"overlay", DRM_OPTS_OVERLAY_PLANE})), OPT_CHOICE("drm-format", drm_format, 0, ({"xrgb8888", DRM_OPTS_FORMAT_XRGB8888}, {"xrgb2101010", DRM_OPTS_FORMAT_XRGB2101010})), @@ -56,8 +60,8 @@ const struct m_sub_options drm_conf = { {0}, }, .defaults = &(const struct drm_opts) { - .drm_osd_plane_id = -1, - .drm_video_plane_id = -1, + .drm_osd_plane_id = DRM_OPTS_PRIMARY_PLANE, + .drm_video_plane_id = DRM_OPTS_OVERLAY_PLANE, }, .size = sizeof(struct drm_opts), }; diff --git a/video/out/drm_common.h b/video/out/drm_common.h index 4d1e2a9e3f04d..e0a3fccad46fd 100644 --- a/video/out/drm_common.h +++ b/video/out/drm_common.h @@ -27,6 +27,9 @@ #define DRM_OPTS_FORMAT_XRGB8888 0 #define DRM_OPTS_FORMAT_XRGB2101010 1 +#define DRM_OPTS_FIRST_PRIMARY_PLANE -1 +#define DRM_OPTS_FIRST_OVERLAY_PLANE -2 + struct kms { struct mp_log *log; int fd;