From 403f489f6cccf8e6bf74ac1b57fa083759af60ec Mon Sep 17 00:00:00 2001 From: rr- Date: Tue, 4 Oct 2016 22:07:19 +0200 Subject: vo_drm: change CLI options + refactors - Change connector selection to accept human readable names (such as eDP-1, HDMI-A-2) rather than arbitrary numbers. - Change GPU selection to accept GPU number rather than device paths. - Merge connector and GPU selection into one --drm-connector. - Add support for --drm-connector=help. - Add support for --drm-* in EGL backend. - Refactor KMS; reduce state sharing across drm_common. --- DOCS/man/vo.rst | 14 +- options/options.c | 9 ++ options/options.h | 3 + video/out/drm_common.c | 290 +++++++++++++++++++++++++++---------- video/out/drm_common.h | 20 ++- video/out/opengl/context_drm_egl.c | 52 +++---- video/out/vo_drm.c | 74 +++------- 7 files changed, 293 insertions(+), 169 deletions(-) diff --git a/DOCS/man/vo.rst b/DOCS/man/vo.rst index f352c46608..34302f9a3f 100644 --- a/DOCS/man/vo.rst +++ b/DOCS/man/vo.rst @@ -495,13 +495,13 @@ Available video output drivers are: The following global options are supported by this video output: - ``--drm-connector=`` - Select the connector to use (usually this is a monitor.) If set to -1, - mpv renders the output on the first available connector. (default: -1) - - ``--drm-devpath=`` - Path to graphic card device. - (default: /dev/dri/card0) + ``--drm-connector=[.]`` + Select the connector to use (usually this is a monitor.) If ```` + is empty or ``auto``, mpv renders the output on the first available + connector. Use ``--drm-connector=help`` to get list of available + connectors. When using multiple graphic cards, use the ```` + argument to disambiguate. + (default: empty) ``--drm-mode=`` Mode ID to use (resolution, bit depth and frame rate). diff --git a/options/options.c b/options/options.c index 93a76e5d41..38f5d16721 100644 --- a/options/options.c +++ b/options/options.c @@ -48,6 +48,10 @@ #include "player/command.h" #include "stream/stream.h" +#if HAVE_DRM +#include "video/out/drm_common.h" +#endif + extern const char mp_help_text[]; static void print_version(struct mp_log *log) @@ -190,6 +194,11 @@ static const m_option_t mp_vo_opt_list[] = { #if HAVE_WIN32 OPT_STRING("vo-mmcss-profile", mmcss_profile, 0), #endif +#if HAVE_DRM + OPT_STRING_VALIDATE("drm-connector", drm_connector_spec, + 0, drm_validate_connector_opt), + OPT_INT("drm-mode", drm_mode_id, 0), +#endif {0} }; diff --git a/options/options.h b/options/options.h index db12742f2b..160223d3e1 100644 --- a/options/options.h +++ b/options/options.h @@ -51,6 +51,9 @@ typedef struct mp_vo_opts { struct sws_opts *sws_opts; // vo_opengl, vo_opengl_cb int hwdec_preload_api; + // vo_drm + char *drm_connector_spec; + int drm_mode_id; } mp_vo_opts; struct mp_cache_opts { diff --git a/video/out/drm_common.c b/video/out/drm_common.c index 8a4e017d28..44e017e4b2 100644 --- a/video/out/drm_common.c +++ b/video/out/drm_common.c @@ -16,9 +16,11 @@ */ #include +#include #include #include #include +#include #include #include @@ -35,71 +37,114 @@ #define HANDLER_RELEASE 1 #define RELEASE_SIGNAL SIGUSR1 #define ACQUIRE_SIGNAL SIGUSR2 +#define MAX_CONNECTOR_NAME_LEN 20 static int vt_switcher_pipe[2]; +static const char *connector_names[] = { + "Unknown", // DRM_MODE_CONNECTOR_Unknown + "VGA", // DRM_MODE_CONNECTOR_VGA + "DVI-I", // DRM_MODE_CONNECTOR_DVII + "DVI-D", // DRM_MODE_CONNECTOR_DVID + "DVI-A", // DRM_MODE_CONNECTOR_DVIA + "Composite", // DRM_MODE_CONNECTOR_Composite + "SVIDEO", // DRM_MODE_CONNECTOR_SVIDEO + "LVDS", // DRM_MODE_CONNECTOR_LVDS + "Component", // DRM_MODE_CONNECTOR_Component + "DIN", // DRM_MODE_CONNECTOR_9PinDIN + "DP", // DRM_MODE_CONNECTOR_DisplayPort + "HDMI-A", // DRM_MODE_CONNECTOR_HDMIA + "HDMI-B", // DRM_MODE_CONNECTOR_HDMIB + "TV", // DRM_MODE_CONNECTOR_TV + "eDP", // DRM_MODE_CONNECTOR_eDP + "Virtual", // DRM_MODE_CONNECTOR_VIRTUAL + "DSI", // DRM_MODE_CONNECTOR_DSI + "DPI", // DRM_MODE_CONNECTOR_DPI +}; + // KMS ------------------------------------------------------------------------ -static bool is_connector_valid(struct kms *kms, int connector_id, - drmModeConnector *connector, bool silent) +static void get_connector_name( + drmModeConnector *connector, char ret[MAX_CONNECTOR_NAME_LEN]) { - if (!connector) { - if (!silent) { - MP_ERR(kms, "Cannot get connector %d: %s\n", connector_id, - mp_strerror(errno)); - } - return false; - } + snprintf(ret, MAX_CONNECTOR_NAME_LEN, "%s-%d", + connector_names[connector->connector_type], + connector->connector_type_id); +} - if (connector->connection != DRM_MODE_CONNECTED) { - if (!silent) { - MP_ERR(kms, "Connector %d is disconnected\n", connector_id); - } - return false; +// Gets the first connector whose name matches the input parameter. +// The returned connector may be disconnected. +// Result must be freed with drmModeFreeConnector. +static drmModeConnector *get_connector_by_name(const struct kms *kms, + const drmModeRes *res, + const char *connector_name) +{ + for (int i = 0; i < res->count_connectors; i++) { + drmModeConnector *connector + = drmModeGetConnector(kms->fd, res->connectors[i]); + if (!connector) + continue; + char other_connector_name[MAX_CONNECTOR_NAME_LEN]; + get_connector_name(connector, other_connector_name); + if (!strcmp(connector_name, other_connector_name)) + return connector; + drmModeFreeConnector(connector); } + return NULL; +} - if (connector->count_modes == 0) { - if (!silent) { - MP_ERR(kms, "Connector %d has no valid modes\n", connector_id); +// Gets the first connected connector. +// Result must be freed with drmModeFreeConnector. +static drmModeConnector *get_first_connected_connector(const struct kms *kms, + const drmModeRes *res) +{ + for (int i = 0; i < res->count_connectors; i++) { + drmModeConnector *connector + = drmModeGetConnector(kms->fd, res->connectors[i]); + if (!connector) + continue; + if (connector->connection == DRM_MODE_CONNECTED + && connector->count_modes > 0) { + return connector; } - return false; + drmModeFreeConnector(connector); } - - return true; + return NULL; } -static bool setup_connector( - struct kms *kms, const drmModeRes *res, int connector_id) +static bool setup_connector(struct kms *kms, const drmModeRes *res, + const char *connector_name) { - drmModeConnector *connector = NULL; - if (connector_id == -1) { - // get the first connected connector - for (int i = 0; i < res->count_connectors; i++) { - connector = drmModeGetConnector(kms->fd, res->connectors[i]); - if (is_connector_valid(kms, i, connector, true)) { - connector_id = i; - break; - } - if (connector) { - drmModeFreeConnector(connector); - connector = NULL; - } + drmModeConnector *connector; + + if (connector_name + && strcmp(connector_name, "") + && strcmp(connector_name, "auto")) { + connector = get_connector_by_name(kms, res, connector_name); + if (!connector) { + MP_ERR(kms, "No connector with name %s found\n", connector_name); + kms_show_available_connectors(kms->log, kms->card_no); + return false; } - if (connector_id == -1) { + } else { + connector = get_first_connected_connector(kms, res); + if (!connector) { MP_ERR(kms, "No connected connectors found\n"); return false; } } - if (connector_id < 0 || connector_id >= res->count_connectors) { - MP_ERR(kms, "Bad connector ID. Max valid connector ID = %u\n", - res->count_connectors); + if (connector->connection != DRM_MODE_CONNECTED) { + drmModeFreeConnector(connector); + MP_ERR(kms, "Chosen connector is disconnected\n"); return false; } - connector = drmModeGetConnector(kms->fd, res->connectors[connector_id]); - if (!is_connector_valid(kms, connector_id, connector, false)) + if (connector->count_modes == 0) { + drmModeFreeConnector(connector); + MP_ERR(kms, "Chosen connector has no valid modes\n"); return false; + } kms->connector = connector; return true; @@ -130,8 +175,7 @@ static bool setup_crtc(struct kms *kms, const drmModeRes *res) drmModeFreeEncoder(encoder); } - MP_ERR(kms, - "Connector %u has no suitable CRTC\n", + MP_ERR(kms, "Connector %u has no suitable CRTC\n", kms->connector->connector_id); return false; } @@ -139,20 +183,10 @@ static bool setup_crtc(struct kms *kms, const drmModeRes *res) static bool setup_mode(struct kms *kms, int mode_id) { if (mode_id < 0 || mode_id >= kms->connector->count_modes) { - MP_ERR( - kms, - "Bad mode ID (max = %d).\n", - kms->connector->count_modes - 1); - - MP_INFO(kms, "Available modes:\n"); - for (unsigned int i = 0; i < kms->connector->count_modes; i++) { - MP_INFO(kms, - "Mode %d: %s (%dx%d)\n", - i, - kms->connector->modes[i].name, - kms->connector->modes[i].hdisplay, - kms->connector->modes[i].vdisplay); - } + MP_ERR(kms, "Bad mode ID (max = %d).\n", + kms->connector->count_modes - 1); + + kms_show_available_modes(kms->log, kms->connector); return false; } @@ -160,36 +194,66 @@ static bool setup_mode(struct kms *kms, int mode_id) return true; } +static int open_card(int card_no) +{ + char card_path[128]; + snprintf(card_path, sizeof(card_path), DRM_DEV_NAME, DRM_DIR_NAME, card_no); + return open(card_path, O_RDWR | O_CLOEXEC); +} -struct kms *kms_create(struct mp_log *log) +static void parse_connector_spec(struct mp_log *log, + const char *connector_spec, + int *card_no, char **connector_name) { - struct kms *ret = talloc(NULL, struct kms); - *ret = (struct kms) { - .log = mp_log_new(ret, log, "kms"), - .fd = -1, + if (!connector_spec) { + *card_no = 0; + *connector_name = NULL; + return; + } + char *dot_ptr = strchr(connector_spec, '.'); + if (dot_ptr) { + *card_no = atoi(connector_spec); + *connector_name = talloc_strdup(log, dot_ptr + 1); + } else { + *card_no = 0; + *connector_name = talloc_strdup(log, connector_spec); + } +} + + +struct kms *kms_create(struct mp_log *log, const char *connector_spec, + int mode_id) +{ + int card_no = -1; + char *connector_name = NULL; + parse_connector_spec(log, connector_spec, &card_no, &connector_name); + + struct kms *kms = talloc(NULL, struct kms); + *kms = (struct kms) { + .log = mp_log_new(kms, log, "kms"), + .fd = open_card(card_no), .connector = NULL, .encoder = NULL, .mode = { 0 }, .crtc_id = -1, + .card_no = card_no, }; - return ret; -} -bool kms_setup(struct kms *kms, const char *device_path, int connector_id, int mode_id) -{ - kms->fd = open(device_path, O_RDWR | O_CLOEXEC); + drmModeRes *res = NULL; + if (kms->fd < 0) { - MP_ERR(kms, "Cannot open \"%s\": %s.\n", device_path, mp_strerror(errno)); - return false; + mp_err(log, "Cannot open card \"%d\": %s.\n", + card_no, mp_strerror(errno)); + goto err; } - drmModeRes *res = drmModeGetResources(kms->fd); + res = drmModeGetResources(kms->fd); if (!res) { - MP_ERR(kms, "Cannot retrieve DRM resources: %s\n", mp_strerror(errno)); - return false; + mp_err(log, "Cannot retrieve DRM resources: %s\n", mp_strerror(errno)); + goto err; } - if (!setup_connector(kms, res, connector_id)) + if (!setup_connector(kms, res, connector_name)) goto err; if (!setup_crtc(kms, res)) goto err; @@ -197,11 +261,15 @@ bool kms_setup(struct kms *kms, const char *device_path, int connector_id, int m goto err; drmModeFreeResources(res); - return true; + return kms; err: - drmModeFreeResources(res); - return false; + if (res) + drmModeFreeResources(res); + if (connector_name) + talloc_free(connector_name); + kms_destroy(kms); + return NULL; } void kms_destroy(struct kms *kms) @@ -220,11 +288,81 @@ void kms_destroy(struct kms *kms) talloc_free(kms); } +void kms_show_available_modes( + struct mp_log *log, const drmModeConnector *connector) +{ + mp_info(log, "Available modes:\n"); + for (unsigned int i = 0; i < connector->count_modes; i++) { + mp_info(log, "Mode %d: %s (%dx%d)\n", i, + connector->modes[i].name, + connector->modes[i].hdisplay, + connector->modes[i].vdisplay); + } +} + +void kms_show_available_connectors(struct mp_log *log, int card_no) +{ + mp_info(log, "Available connectors for card %d:\n", card_no); + + int fd = open_card(card_no); + if (fd < 0) { + mp_err(log, "Failed to open card %d\n", card_no); + return; + } + + drmModeRes *res = drmModeGetResources(fd); + if (!res) { + mp_err(log, "Cannot retrieve DRM resources: %s\n", mp_strerror(errno)); + goto err; + } + + for (int i = 0; i < res->count_connectors; i++) { + drmModeConnector *connector + = drmModeGetConnector(fd, res->connectors[i]); + if (!connector) + continue; + char other_connector_name[MAX_CONNECTOR_NAME_LEN]; + get_connector_name(connector, other_connector_name); + mp_info(log, "%s (%s)\n", other_connector_name, + connector->connection == DRM_MODE_CONNECTED + ? "connected" + : "disconnected"); + drmModeFreeConnector(connector); + } + +err: + if (fd >= 0) + close(fd); + if (res) + drmModeFreeResources(res); +} + +void kms_show_available_cards_and_connectors(struct mp_log *log) +{ + for (int card_no = 0; card_no < DRM_MAX_MINOR; card_no++) { + int fd = open_card(card_no); + if (fd < 0) + break; + close(fd); + kms_show_available_connectors(log, card_no); + } +} + double kms_get_display_fps(const struct kms *kms) { return kms->mode.clock * 1000.0 / kms->mode.htotal / kms->mode.vtotal; } +int drm_validate_connector_opt(struct mp_log *log, const struct m_option *opt, + struct bstr name, struct bstr param) +{ + if (bstr_equals0(param, "help")) { + kms_show_available_cards_and_connectors(log); + return M_OPT_EXIT; + } + return 1; +} + // VT switcher ---------------------------------------------------------------- diff --git a/video/out/drm_common.h b/video/out/drm_common.h index 53ec9e35df..6796472cfc 100644 --- a/video/out/drm_common.h +++ b/video/out/drm_common.h @@ -21,6 +21,7 @@ #include #include #include +#include "options/m_option.h" struct kms { struct mp_log *log; @@ -29,6 +30,7 @@ struct kms { drmModeEncoder *encoder; drmModeModeInfo mode; uint32_t crtc_id; + int card_no; }; struct vt_switcher { @@ -43,12 +45,22 @@ void vt_switcher_destroy(struct vt_switcher *s); void vt_switcher_poll(struct vt_switcher *s, int timeout_ms); void vt_switcher_interrupt_poll(struct vt_switcher *s); -void vt_switcher_acquire(struct vt_switcher *s, void (*handler)(void*), void *user_data); -void vt_switcher_release(struct vt_switcher *s, void (*handler)(void*), void *user_data); +void vt_switcher_acquire(struct vt_switcher *s, void (*handler)(void*), + void *user_data); +void vt_switcher_release(struct vt_switcher *s, void (*handler)(void*), + void *user_data); -struct kms *kms_create(struct mp_log *log); -bool kms_setup(struct kms *kms, const char *device_path, int conn_id, int mode_id); +struct kms *kms_create(struct mp_log *log, const char *connector_spec, + int mode_id); void kms_destroy(struct kms *kms); double kms_get_display_fps(const struct kms *kms); +void kms_show_available_connectors(struct mp_log *log, int card_no); +void kms_show_available_modes(struct mp_log *log, + const drmModeConnector *connector); +void kms_show_available_cards_and_connectors(struct mp_log *log); + +int drm_validate_connector_opt(struct mp_log *log, const struct m_option *opt, + struct bstr name, struct bstr param); + #endif diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c index a6609681d3..e5fd7b8354 100644 --- a/video/out/opengl/context_drm_egl.c +++ b/video/out/opengl/context_drm_egl.c @@ -94,7 +94,8 @@ static bool init_egl(struct MPGLContext *ctx, int flags) &p->egl.context, &config)) return -1; MP_VERBOSE(ctx->vo, "Initializing EGL surface\n"); - p->egl.surface = eglCreateWindowSurface(p->egl.display, config, p->gbm.surface, NULL); + p->egl.surface + = eglCreateWindowSurface(p->egl.display, config, p->gbm.surface, NULL); if (p->egl.surface == EGL_NO_SURFACE) { MP_ERR(ctx->vo, "Failed to create EGL surface.\n"); return false; @@ -147,7 +148,7 @@ static void update_framebuffer_from_bo( int handle = gbm_bo_get_handle(bo).u32; int ret = drmModeAddFB(p->kms->fd, p->fb.width, p->fb.height, - 24, 32, stride, handle, &p->fb.id); + 24, 32, stride, handle, &p->fb.id); if (ret) { MP_ERR(ctx->vo, "Failed to create framebuffer: %s\n", mp_strerror(errno)); } @@ -155,7 +156,7 @@ static void update_framebuffer_from_bo( } static void page_flipped(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *data) + unsigned int usec, void *data) { struct priv *p = data; p->waiting_for_flip = false; @@ -167,12 +168,8 @@ static bool crtc_setup(struct MPGLContext *ctx) if (p->active) return true; 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, + 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->active = true; return ret == 0; @@ -197,12 +194,9 @@ static void crtc_release(struct MPGLContext *ctx) 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->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; @@ -220,7 +214,8 @@ static void release_vt(void *data) //until things change, this is commented. struct priv *p = ctx->priv; if (drmDropMaster(p->kms->fd)) { - MP_WARN(ctx->vo, "Failed to drop DRM master: %s\n", mp_strerror(errno)); + MP_WARN(ctx->vo, "Failed to drop DRM master: %s\n", + mp_strerror(errno)); } } } @@ -232,7 +227,8 @@ static void acquire_vt(void *data) if (USE_MASTER) { struct priv *p = ctx->priv; if (drmSetMaster(p->kms->fd)) { - MP_WARN(ctx->vo, "Failed to acquire DRM master: %s\n", mp_strerror(errno)); + MP_WARN(ctx->vo, "Failed to acquire DRM master: %s\n", + mp_strerror(errno)); } } @@ -247,7 +243,8 @@ static void drm_egl_uninit(MPGLContext *ctx) if (p->vt_switcher_active) vt_switcher_destroy(&p->vt_switcher); - eglMakeCurrent(p->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglMakeCurrent(p->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); eglDestroyContext(p->egl.display, p->egl.context); eglDestroySurface(p->egl.display, p->egl.surface); gbm_surface_destroy(p->gbm.surface); @@ -287,18 +284,13 @@ static int drm_egl_init(struct MPGLContext *ctx, int flags) } MP_VERBOSE(ctx->vo, "Initializing KMS\n"); - p->kms = kms_create(ctx->vo->log); + p->kms = kms_create(ctx->vo->log, ctx->vo->opts->drm_connector_spec, + ctx->vo->opts->drm_mode_id); if (!p->kms) { MP_ERR(ctx->vo, "Failed to create KMS.\n"); return -1; } - // TODO: arguments should be configurable - if (!kms_setup(p->kms, "/dev/dri/card0", -1, 0)) { - MP_ERR(ctx->vo, "Failed to configure KMS.\n"); - return -1; - } - if (!init_gbm(ctx)) { MP_ERR(ctx->vo, "Failed to setup GBM.\n"); return -1; @@ -309,7 +301,8 @@ static int drm_egl_init(struct MPGLContext *ctx, int flags) return -1; } - if (!eglMakeCurrent(p->egl.display, p->egl.surface, p->egl.surface, p->egl.context)) { + if (!eglMakeCurrent(p->egl.display, p->egl.surface, p->egl.surface, + p->egl.context)) { MP_ERR(ctx->vo, "Failed to make context current.\n"); return -1; } @@ -337,11 +330,8 @@ static int drm_egl_init(struct MPGLContext *ctx, int flags) } if (!crtc_setup(ctx)) { - MP_ERR( - ctx->vo, - "Failed to set CRTC for connector %u: %s\n", - p->kms->connector->connector_id, - mp_strerror(errno)); + MP_ERR(ctx->vo, "Failed to set CRTC for connector %u: %s\n", + p->kms->connector->connector_id, mp_strerror(errno)); return -1; } diff --git a/video/out/vo_drm.c b/video/out/vo_drm.c index 60b3869d5b..7e642e391c 100644 --- a/video/out/vo_drm.c +++ b/video/out/vo_drm.c @@ -54,8 +54,7 @@ struct framebuffer { }; struct priv { - char *device_path; - int connector_id; + char *connector_spec; int mode_id; struct kms *kms; @@ -70,8 +69,8 @@ struct priv { bool active; bool pflip_happening; - int32_t device_w; - int32_t device_h; + int32_t screen_w; + int32_t screen_h; struct mp_image *last_input; struct mp_image *cur_frame; struct mp_rect src; @@ -158,8 +157,7 @@ static bool fb_setup_double_buffering(struct vo *vo) for (unsigned int i = 0; i < BUF_COUNT; i++) { if (!fb_setup_single(vo, p->kms->fd, &p->bufs[i])) { - MP_ERR(vo, "Cannot create framebuffer for connector %d\n", - p->kms->connector->connector_id); + MP_ERR(vo, "Cannot create framebuffer\n"); for (unsigned int j = 0; j < i; j++) { fb_destroy(p->kms->fd, &p->bufs[j]); } @@ -171,7 +169,7 @@ static bool fb_setup_double_buffering(struct vo *vo) } static void page_flipped(int fd, unsigned int frame, unsigned int sec, - unsigned int usec, void *data) + unsigned int usec, void *data) { struct priv *p = data; p->pflip_happening = false; @@ -185,10 +183,7 @@ static bool crtc_setup(struct vo *vo) p->old_crtc = drmModeGetCrtc(p->kms->fd, p->kms->crtc_id); int ret = drmModeSetCrtc(p->kms->fd, p->kms->crtc_id, p->bufs[p->front_buf + BUF_COUNT - 1].fb, - 0, - 0, - &p->kms->connector->connector_id, - 1, + 0, 0, &p->kms->connector->connector_id, 1, &p->kms->mode); p->active = true; return ret == 0; @@ -212,13 +207,10 @@ static void crtc_release(struct vo *vo) } if (p->old_crtc) { - drmModeSetCrtc(p->kms->fd, - p->old_crtc->crtc_id, + 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->x, p->old_crtc->y, + &p->kms->connector->connector_id, 1, &p->old_crtc->mode); drmModeFreeCrtc(p->old_crtc); p->old_crtc = NULL; @@ -274,8 +266,8 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) { struct priv *p = vo->priv; - vo->dwidth = p->device_w; - vo->dheight = p->device_h; + vo->dwidth = p->screen_w; + vo->dheight = p->screen_h; vo_get_src_dst_rects(vo, &p->src, &p->dst, &p->osd); int w = p->dst.x1 - p->dst.x0; @@ -302,7 +294,7 @@ static int reconfig(struct vo *vo, struct mp_image_params *params) }; talloc_free(p->cur_frame); - p->cur_frame = mp_image_alloc(IMGFMT, p->device_w, p->device_h); + p->cur_frame = mp_image_alloc(IMGFMT, p->screen_w, p->screen_h); mp_image_params_guess_csp(&p->sws->dst); mp_image_set_params(p->cur_frame, &p->sws->dst); @@ -338,14 +330,11 @@ static void draw_image(struct vo *vo, mp_image_t *mpi) struct framebuffer *front_buf = &p->bufs[p->front_buf]; int w = p->dst.x1 - p->dst.x0; int h = p->dst.y1 - p->dst.y0; - int x = (p->device_w - w) >> 1; - int y = (p->device_h - h) >> 1; + int x = (p->screen_w - w) >> 1; + int y = (p->screen_h - h) >> 1; int shift = y * front_buf->stride + x * BYTES_PER_PIXEL; - memcpy_pic(front_buf->map + shift, - p->cur_frame->planes[0], - w * BYTES_PER_PIXEL, - h, - front_buf->stride, + memcpy_pic(front_buf->map + shift, p->cur_frame->planes[0], + w * BYTES_PER_PIXEL, h, front_buf->stride, p->cur_frame->stride[0]); } @@ -422,17 +411,13 @@ static int preinit(struct vo *vo) MP_WARN(vo, "Failed to set up VT switcher. Terminal switching will be unavailable.\n"); } - p->kms = kms_create(vo->log); + p->kms = kms_create( + vo->log, vo->opts->drm_connector_spec, vo->opts->drm_mode_id); if (!p->kms) { MP_ERR(vo, "Failed to create KMS.\n"); goto err; } - if (!kms_setup(p->kms, p->device_path, p->connector_id, p->mode_id)) { - MP_ERR(vo, "Failed to configure KMS.\n"); - goto err; - } - if (!fb_setup_double_buffering(vo)) { MP_ERR(vo, "Failed to set up double buffering.\n"); goto err; @@ -440,18 +425,16 @@ static int preinit(struct vo *vo) uint64_t has_dumb; if (drmGetCap(p->kms->fd, DRM_CAP_DUMB_BUFFER, &has_dumb) < 0) { - MP_ERR(vo, "Device \"%s\" does not support dumb buffers.\n", p->device_path); + MP_ERR(vo, "Card \"%d\" does not support dumb buffers.\n", + p->kms->card_no); goto err; } - p->device_w = p->bufs[0].width; - p->device_h = p->bufs[0].height; + p->screen_w = p->bufs[0].width; + p->screen_h = p->bufs[0].height; if (!crtc_setup(vo)) { - MP_ERR(vo, - "Cannot set CRTC for connector %u: %s\n", - p->kms->connector->connector_id, - mp_strerror(errno)); + MP_ERR(vo, "Cannot set CRTC: %s\n", mp_strerror(errno)); goto err; } @@ -507,16 +490,5 @@ const struct vo_driver video_out_drm = { .wait_events = wait_events, .wakeup = wakeup, .priv_size = sizeof(struct priv), - .options = (const struct m_option[]) { - OPT_STRING("devpath", device_path, 0), - OPT_INT("connector", connector_id, 0), - OPT_INT("mode", mode_id, 0), - {0}, - }, - .priv_defaults = &(const struct priv) { - .device_path = "/dev/dri/card0", - .connector_id = -1, - .mode_id = 0, - }, .legacy_prefix = "drm", }; -- cgit v1.2.3