static int drm_egl_init(struct MPGLContext *ctx, int flags) { struct priv *p = ctx->priv; p->kms = NULL; p->old_crtc = NULL; p->gbm.surface = NULL; p->gbm.device = NULL; p->active = false; p->waiting_for_flip = false; p->ev.version = DRM_EVENT_CONTEXT_VERSION; p->ev.page_flip_handler = page_flipped; p->vt_switcher_active = vt_switcher_init(&p->vt_switcher, ctx->vo->log); if (p->vt_switcher_active) { vt_switcher_acquire(&p->vt_switcher, acquire_vt, ctx); vt_switcher_release(&p->vt_switcher, release_vt, ctx); } else { MP_WARN(ctx->vo, "Failed to set up VT switcher. Terminal switching will be unavailable.\n"); } MP_VERBOSE(ctx->vo, "Initializing KMS\n"); p->kms = kms_create(ctx->vo->log); 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; } if (!init_egl(ctx, flags & VOFLAG_GLES)) { MP_ERR(ctx->vo, "Failed to setup EGL.\n"); return -1; } 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; } const char *egl_exts = eglQueryString(p->egl.display, EGL_EXTENSIONS); void *(*gpa)(const GLubyte*) = (void *(*)(const GLubyte*))eglGetProcAddress; mpgl_load_functions(ctx->gl, gpa, egl_exts, ctx->vo->log); // required by gbm_surface_lock_front_buffer eglSwapBuffers(p->egl.display, p->egl.surface); MP_VERBOSE(ctx->vo, "Preparing framebuffer\n"); p->gbm.bo = gbm_surface_lock_front_buffer(p->gbm.surface); if (!p->gbm.bo) { MP_ERR(ctx->vo, "Failed to lock GBM surface.\n"); return -1; } update_framebuffer_from_bo(ctx, p->gbm.bo); if (!p->fb.id) { MP_ERR(ctx->vo, "Failed to create framebuffer.\n"); return -1; } 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)); return -1; } return 0; }
static void acquire_vt(void *data) { struct MPGLContext *ctx = data; MP_VERBOSE(ctx->vo, "Acquiring VT"); 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)); } } crtc_setup(ctx); }
static int drm_egl_init(struct MPGLContext *ctx, int flags) { if (ctx->vo->probing) { MP_VERBOSE(ctx->vo, "DRM EGL backend can be activated only manually.\n"); return -1; } struct priv *p = ctx->priv; p->kms = NULL; p->old_crtc = NULL; p->gbm.surface = NULL; p->gbm.device = NULL; p->active = false; p->waiting_for_flip = false; p->ev.version = DRM_EVENT_CONTEXT_VERSION; p->ev.page_flip_handler = page_flipped; p->vt_switcher_active = vt_switcher_init(&p->vt_switcher, ctx->vo->log); if (p->vt_switcher_active) { vt_switcher_acquire(&p->vt_switcher, acquire_vt, ctx); vt_switcher_release(&p->vt_switcher, release_vt, ctx); } else { MP_WARN(ctx->vo, "Failed to set up VT switcher. Terminal switching will be unavailable.\n"); } MP_VERBOSE(ctx->vo, "Initializing KMS\n"); 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; } if (!init_gbm(ctx)) { MP_ERR(ctx->vo, "Failed to setup GBM.\n"); return -1; } if (!init_egl(ctx, flags)) { MP_ERR(ctx->vo, "Failed to setup EGL.\n"); return -1; } 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; } const char *egl_exts = eglQueryString(p->egl.display, EGL_EXTENSIONS); void *(*gpa)(const GLubyte*) = (void *(*)(const GLubyte*))eglGetProcAddress; mpgl_load_functions(ctx->gl, gpa, egl_exts, ctx->vo->log); ctx->native_display_type = "drm"; ctx->native_display = (void *)(intptr_t)p->kms->fd; // required by gbm_surface_lock_front_buffer eglSwapBuffers(p->egl.display, p->egl.surface); MP_VERBOSE(ctx->vo, "Preparing framebuffer\n"); p->gbm.bo = gbm_surface_lock_front_buffer(p->gbm.surface); if (!p->gbm.bo) { MP_ERR(ctx->vo, "Failed to lock GBM surface.\n"); return -1; } update_framebuffer_from_bo(ctx, p->gbm.bo); if (!p->fb.id) { MP_ERR(ctx->vo, "Failed to create framebuffer.\n"); return -1; } 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)); return -1; } return 0; }