From ed94f8dc00dd75bf5d88bdf73b9d69a579c0f8ef Mon Sep 17 00:00:00 2001 From: LongChair Date: Sun, 29 Apr 2018 17:46:23 +0200 Subject: drm/atomic: refactor planes names We are currently using primary / overlay planes drm objects, assuming that primary plane is osd and overlay plane is video. This commit is doing two things : - replace the primary / overlay planes members with osd and video planes member without the assumption - Add two more options to determine which one of the primary / overlay is associated to osd / video. - It will default osd to overlay and video to primary if unspecified --- DOCS/man/vo.rst | 14 +++++++ video/out/drm_atomic.c | 73 +++++++++++++++++++++++------------ video/out/drm_atomic.h | 7 ++-- video/out/drm_common.c | 11 ++++-- video/out/drm_common.h | 5 ++- video/out/opengl/context_drm_egl.c | 11 +++--- video/out/opengl/hwdec_drmprime_drm.c | 34 ++++++++-------- video/out/vo_drm.c | 3 +- 8 files changed, 103 insertions(+), 55 deletions(-) diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst index 96ab1f7cf9..3fb2567b7d 100644 --- a/DOCS/man/vo.rst +++ b/DOCS/man/vo.rst @@ -488,6 +488,20 @@ Available video output drivers are: Mode ID to use (resolution and frame rate). (default: 0) + ``--drm-osd-plane-id=`` + Select the DRM planed index to use for OSD (or OSD and video). + Index is zero based, and related to crtc. + When using this option with drm_prime renderer, it will only affect + the OSD contents. Otherwise it will set OSD & video plane. + (default: primary plane) + + ``--drm-video-plane-id=`` + Select the DRM planed index to use for video layer. + Index is zero based, and related to crtc. + This option only has effect when using the drm_prime renderer (which + supports several layers) together with ``vo=gpu`` and ``gpu-context=drm``. + (default: first overlay plane) + ``--drm-format=`` Select the DRM format to use (default: xrgb8888). This allows you to choose the bit depth of the DRM mode. xrgb8888 is your usual 24 bit per diff --git a/video/out/drm_atomic.c b/video/out/drm_atomic.c index fb63c2b277..84c46beb82 100644 --- a/video/out/drm_atomic.c +++ b/video/out/drm_atomic.c @@ -137,8 +137,8 @@ void drm_object_print_info(struct mp_log *log, struct drm_object *object) (long long)object->props->prop_values[i]); } -struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, - int crtc_id, int connector_id, int overlay_id) +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) { drmModePlane *drmplane = NULL; drmModePlaneRes *plane_res = NULL; @@ -146,7 +146,10 @@ struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, struct drm_object *plane = NULL; struct drm_atomic_context *ctx; int crtc_index = -1; - int layercount = 0; + int layercount = -1; + int primary_id = 0; + int overlay_id = 0; + uint64_t value; res = drmModeGetResources(fd); @@ -206,20 +209,26 @@ struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, mp_err(log, "Unable to retrieve type property from plane %d\n", j); goto fail; } else { - if ((value == DRM_PLANE_TYPE_OVERLAY) && - (layercount == overlay_id)) { - ctx->overlay_plane = plane; - } - else if (value == DRM_PLANE_TYPE_PRIMARY) { - ctx->primary_plane = plane; + layercount++; + + if ((!primary_id) && (value == DRM_PLANE_TYPE_PRIMARY)) + primary_id = drmplane->plane_id; + + if ((!overlay_id) && (value == DRM_PLANE_TYPE_OVERLAY)) + overlay_id = drmplane->plane_id; + + if (layercount == osd_plane_id) { + ctx->osd_plane = plane; + continue; } - else { - drm_object_free(plane); - plane = NULL; + + if (layercount == video_plane_id) { + ctx->video_plane = plane; + continue; } - if (value == DRM_PLANE_TYPE_OVERLAY) - layercount++; + drm_object_free(plane); + plane = NULL; } } else { mp_err(log, "Failed to create Plane object from plane ID %d\n", @@ -231,18 +240,34 @@ struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, drmplane = NULL; } - if (!ctx->primary_plane) { - mp_err(log, "Failed to find primary plane\n"); - goto fail; + // default OSD plane to primary if unspecified + if (!ctx->osd_plane) { + if (primary_id) { + mp_verbose(log, "Using default plane %d for OSD\n", primary_id); + ctx->osd_plane = drm_object_create(log, ctx->fd, primary_id, DRM_MODE_OBJECT_PLANE); + } else { + mp_err(log, "Failed to find OSD plane with id=%d\n", osd_plane_id); + goto fail; + } + } else { + mp_verbose(log, "Found OSD plane with ID %d\n", ctx->osd_plane->id); } - if (!ctx->overlay_plane) { - mp_err(log, "Failed to find overlay plane with id=%d\n", overlay_id); - goto fail; + // default video plane to overlay if unspecified + if (!ctx->video_plane) { + if (overlay_id) { + mp_verbose(log, "Using default plane %d for video\n", overlay_id); + ctx->video_plane = drm_object_create(log, ctx->fd, overlay_id, DRM_MODE_OBJECT_PLANE); + } else { + mp_err(log, "Failed to find video plane with id=%d\n", video_plane_id); + goto fail; + } + } else { + mp_verbose(log, "Found video plane with ID %d\n", ctx->video_plane->id); } - mp_verbose(log, "Found Primary plane with ID %d, overlay with ID %d\n", - ctx->primary_plane->id, ctx->overlay_plane->id); + mp_verbose(log, "Found Video plane with ID %d, OSD with ID %d\n", + ctx->video_plane->id, ctx->osd_plane->id); drmModeFreePlaneResources(plane_res); drmModeFreeResources(res); @@ -265,7 +290,7 @@ void drm_atomic_destroy_context(struct drm_atomic_context *ctx) { drm_object_free(ctx->crtc); drm_object_free(ctx->connector); - drm_object_free(ctx->primary_plane); - drm_object_free(ctx->overlay_plane); + drm_object_free(ctx->osd_plane); + drm_object_free(ctx->video_plane); talloc_free(ctx); } diff --git a/video/out/drm_atomic.h b/video/out/drm_atomic.h index d4d5707274..01246baf36 100644 --- a/video/out/drm_atomic.h +++ b/video/out/drm_atomic.h @@ -37,8 +37,8 @@ struct drm_atomic_context { struct drm_object *crtc; struct drm_object *connector; - struct drm_object *primary_plane; - struct drm_object *overlay_plane; + struct drm_object *osd_plane; + struct drm_object *video_plane; drmModeAtomicReq *request; }; @@ -52,7 +52,8 @@ drmModePropertyBlobPtr drm_object_get_property_blob(struct drm_object *object, c struct drm_object * drm_object_create(struct mp_log *log, int fd, uint32_t object_id, uint32_t type); void drm_object_free(struct drm_object *object); void drm_object_print_info(struct mp_log *log, struct drm_object *object); -struct drm_atomic_context *drm_atomic_create_context(struct mp_log *log, int fd, int crtc_id, int connector_id, int overlay_id); +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); void drm_atomic_destroy_context(struct drm_atomic_context *ctx); #endif // MP_DRMATOMIC_H diff --git a/video/out/drm_common.c b/video/out/drm_common.c index e0b0581834..3393954a5e 100644 --- a/video/out/drm_common.c +++ b/video/out/drm_common.c @@ -47,13 +47,18 @@ 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-overlay", drm_overlay_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("drm-format", drm_format, 0, ({"xrgb8888", DRM_OPTS_FORMAT_XRGB8888}, {"xrgb2101010", DRM_OPTS_FORMAT_XRGB2101010})), OPT_SIZE_BOX("drm-osd-size", drm_osd_size, 0), {0}, }, + .defaults = &(const struct drm_opts) { + .drm_osd_plane_id = -1, + .drm_video_plane_id = -1, + }, .size = sizeof(struct drm_opts), }; @@ -238,7 +243,7 @@ static void parse_connector_spec(struct mp_log *log, struct kms *kms_create(struct mp_log *log, const char *connector_spec, - int mode_id, int overlay_id) + int mode_id, int osd_plane_id, int video_plane_id) { int card_no = -1; char *connector_name = NULL; @@ -286,7 +291,7 @@ struct kms *kms_create(struct mp_log *log, const char *connector_spec, } else { mp_verbose(log, "DRM Atomic support found\n"); kms->atomic_context = drm_atomic_create_context(kms->log, kms->fd, kms->crtc_id, - kms->connector->connector_id, overlay_id); + kms->connector->connector_id, osd_plane_id, video_plane_id); if (!kms->atomic_context) { mp_err(log, "Failed to create DRM atomic context\n"); goto err; diff --git a/video/out/drm_common.h b/video/out/drm_common.h index 16064a47fb..4d1e2a9e3f 100644 --- a/video/out/drm_common.h +++ b/video/out/drm_common.h @@ -48,7 +48,8 @@ struct vt_switcher { struct drm_opts { char *drm_connector_spec; int drm_mode_id; - int drm_overlay_id; + int drm_osd_plane_id; + int drm_video_plane_id; int drm_format; struct m_geometry drm_osd_size; }; @@ -64,7 +65,7 @@ void vt_switcher_release(struct vt_switcher *s, void (*handler)(void*), void *user_data); struct kms *kms_create(struct mp_log *log, const char *connector_spec, - int mode_id, int overlay_id); + int mode_id, int osd_plane_id, int video_plane_id); void kms_destroy(struct kms *kms); double kms_get_display_fps(const struct kms *kms); diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c index 27b1ab968a..c0f7fa244e 100644 --- a/video/out/opengl/context_drm_egl.c +++ b/video/out/opengl/context_drm_egl.c @@ -352,9 +352,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->primary_plane, "FB_ID", p->fb->id); - drm_object_set_property(atomic_ctx->request, atomic_ctx->primary_plane, "CRTC_ID", atomic_ctx->crtc->id); - drm_object_set_property(atomic_ctx->request, atomic_ctx->primary_plane, "ZPOS", 1); + 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); ret = drmModeAtomicCommit(p->kms->fd, atomic_ctx->request, DRM_MODE_ATOMIC_NONBLOCK | DRM_MODE_PAGE_FLIP_EVENT, NULL); @@ -442,7 +442,7 @@ static bool probe_gbm_format(struct ra_ctx *ctx, uint32_t argb_format, uint32_t } drmModePlane *drmplane = - drmModeGetPlane(p->kms->fd, p->kms->atomic_context->primary_plane->id); + drmModeGetPlane(p->kms->fd, p->kms->atomic_context->osd_plane->id); bool have_argb = false; bool have_xrgb = false; bool result = false; @@ -490,7 +490,8 @@ 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_overlay_id); + ctx->vo->opts->drm_opts->drm_osd_plane_id, + ctx->vo->opts->drm_opts->drm_video_plane_id); if (!p->kms) { MP_ERR(ctx, "Failed to create KMS.\n"); return false; diff --git a/video/out/opengl/hwdec_drmprime_drm.c b/video/out/opengl/hwdec_drmprime_drm.c index f99550442a..2e1859f6bb 100644 --- a/video/out/opengl/hwdec_drmprime_drm.c +++ b/video/out/opengl/hwdec_drmprime_drm.c @@ -160,23 +160,23 @@ static int overlay_frame(struct ra_hwdec *hw, struct mp_image *hw_image, } if (request) { - drm_object_set_property(request, p->ctx->overlay_plane, "FB_ID", next_frame.fb.fb_id); - drm_object_set_property(request, p->ctx->overlay_plane, "CRTC_ID", p->ctx->crtc->id); - drm_object_set_property(request, p->ctx->overlay_plane, "SRC_X", p->src.x0 << 16); - drm_object_set_property(request, p->ctx->overlay_plane, "SRC_Y", p->src.y0 << 16); - drm_object_set_property(request, p->ctx->overlay_plane, "SRC_W", srcw << 16); - drm_object_set_property(request, p->ctx->overlay_plane, "SRC_H", srch << 16); - drm_object_set_property(request, p->ctx->overlay_plane, "CRTC_X", MP_ALIGN_DOWN(p->dst.x0, 2)); - drm_object_set_property(request, p->ctx->overlay_plane, "CRTC_Y", MP_ALIGN_DOWN(p->dst.y0, 2)); - drm_object_set_property(request, p->ctx->overlay_plane, "CRTC_W", dstw); - drm_object_set_property(request, p->ctx->overlay_plane, "CRTC_H", dsth); - drm_object_set_property(request, p->ctx->overlay_plane, "ZPOS", 0); + drm_object_set_property(request, p->ctx->video_plane, "FB_ID", next_frame.fb.fb_id); + drm_object_set_property(request, p->ctx->video_plane, "CRTC_ID", p->ctx->crtc->id); + drm_object_set_property(request, p->ctx->video_plane, "SRC_X", p->src.x0 << 16); + drm_object_set_property(request, p->ctx->video_plane, "SRC_Y", p->src.y0 << 16); + drm_object_set_property(request, p->ctx->video_plane, "SRC_W", srcw << 16); + drm_object_set_property(request, p->ctx->video_plane, "SRC_H", srch << 16); + drm_object_set_property(request, p->ctx->video_plane, "CRTC_X", MP_ALIGN_DOWN(p->dst.x0, 2)); + drm_object_set_property(request, p->ctx->video_plane, "CRTC_Y", MP_ALIGN_DOWN(p->dst.y0, 2)); + drm_object_set_property(request, p->ctx->video_plane, "CRTC_W", dstw); + drm_object_set_property(request, p->ctx->video_plane, "CRTC_H", dsth); + drm_object_set_property(request, p->ctx->video_plane, "ZPOS", 0); } else { - ret = drmModeSetPlane(p->ctx->fd, p->ctx->overlay_plane->id, p->ctx->crtc->id, next_frame.fb.fb_id, 0, + ret = drmModeSetPlane(p->ctx->fd, p->ctx->video_plane->id, p->ctx->crtc->id, next_frame.fb.fb_id, 0, MP_ALIGN_DOWN(p->dst.x0, 2), MP_ALIGN_DOWN(p->dst.y0, 2), dstw, dsth, p->src.x0 << 16, p->src.y0 << 16 , srcw << 16, srch << 16); if (ret < 0) { - MP_ERR(hw, "Failed to set the plane %d (buffer %d).\n", p->ctx->overlay_plane->id, + MP_ERR(hw, "Failed to set the plane %d (buffer %d).\n", p->ctx->video_plane->id, next_frame.fb.fb_id); goto fail; } @@ -210,13 +210,14 @@ static void uninit(struct ra_hwdec *hw) static int init(struct ra_hwdec *hw) { struct priv *p = hw->priv; - int drm_overlay; + int osd_plane_id, video_plane_id; p->log = hw->log; void *tmp = talloc_new(NULL); struct drm_opts *opts = mp_get_config_group(tmp, hw->global, &drm_conf); - drm_overlay = opts->drm_overlay_id; + osd_plane_id = opts->drm_osd_plane_id; + video_plane_id = opts->drm_video_plane_id; talloc_free(tmp); struct mpv_opengl_drm_params *drm_params; @@ -224,7 +225,7 @@ static int init(struct ra_hwdec *hw) drm_params = ra_get_native_resource(hw->ra, "drm_params"); if (drm_params) { p->ctx = drm_atomic_create_context(p->log, drm_params->fd, drm_params->crtc_id, - drm_params->connector_id, drm_overlay); + drm_params->connector_id, osd_plane_id, video_plane_id); if (!p->ctx) { mp_err(p->log, "Failed to retrieve DRM atomic context.\n"); goto err; @@ -242,7 +243,6 @@ static int init(struct ra_hwdec *hw) drmModeFreeCrtc(crtc); } - uint64_t has_prime; if (drmGetCap(p->ctx->fd, DRM_CAP_PRIME, &has_prime) < 0) { MP_ERR(hw, "Card does not support prime handles.\n"); diff --git a/video/out/vo_drm.c b/video/out/vo_drm.c index b25f036256..ed41d2aab0 100644 --- a/video/out/vo_drm.c +++ b/video/out/vo_drm.c @@ -420,7 +420,8 @@ static int preinit(struct vo *vo) p->kms = kms_create( vo->log, vo->opts->drm_opts->drm_connector_spec, vo->opts->drm_opts->drm_mode_id, - vo->opts->drm_opts->drm_overlay_id); + vo->opts->drm_opts->drm_osd_plane_id, + vo->opts->drm_opts->drm_video_plane_id); if (!p->kms) { MP_ERR(vo, "Failed to create KMS.\n"); goto err; -- cgit v1.2.3