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; }
int main(int argc, char** argv) { struct kms_driver *kms; int ret, fd, i; for (i = 0, fd = -1; fd < 0 && drivers[i]; i++) fd = drmOpen(drivers[i], NULL); CHECK_RET_RETURN(fd, "Could not open device"); ret = kms_create(fd, &kms); CHECK_RET_RETURN(ret, "Failed to create kms driver"); ret = test_bo(kms); if (ret) goto err; printf("%s: All ok!\n", __func__); kms_destroy(&kms); return 0; err: kms_destroy(&kms); return ret; }
int bo_device_init(struct omap_device *dev) { struct kms_driver *kms; int ret; ret = kms_create(dev->fd, &kms); if (ret || !kms) return FALSE; dev->bo_dev = kms; dev->ops = &bo_rockchip_ops; return TRUE; }
static struct gbm_device *kms_device_create(int fd) { struct gbm_kms_device *dev; int ret; GBM_DEBUG("%s: %d\n", __func__, __LINE__); if (!(dev = calloc(1, sizeof(struct gbm_kms_device)))) return NULL; dev->base.type = GBM_DRM_DRIVER_TYPE_CUSTOM; dev->base.base = kms_gbm_device; dev->base.base.fd = fd; if (kms_create(fd, &dev->kms)) { free(dev); return NULL; } return &dev->base.base; }
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; }
int fb_map_locked(struct private_module_t *module) { int err; // already initialized... if (module->num_buffers) return 0; int fd = drmOpen("shmob-drm", 0); if (fd < 0) return -errno; module->fd = fd; drmModeModeInfo *mode = 0; drmVersion *version = 0; drmModeRes *resources = 0; drmModeConnector *connector = 0; drmModeEncoder *encoder = 0; version = drmGetVersion(fd); if (!version) { err = -errno; goto done; } resources = drmModeGetResources(fd); if (!resources) { err = -errno; goto done; } /* Get the default mode associated with the first connector. */ if (resources->count_connectors == 0) { err = -EINVAL; goto done; } connector = drmModeGetConnector(fd, resources->connectors[0]); if (!connector) { err = -errno; goto done; } if (connector->count_modes == 0) { err = -EINVAL; goto done; } if (connector->count_encoders == 0) { err = -EINVAL; goto done; } encoder = drmModeGetEncoder(fd, *connector->encoders); if (!encoder) { err = -errno; goto done; } for (int i = 0; i < resources->count_crtcs; ++i) { if (encoder->possible_crtcs & (1U << i)) { module->crtc = resources->crtcs[i]; break; } } if (module->crtc == 0) { err = -EINVAL; goto done; } float xdpi; float ydpi; float fps; mode = &connector->modes[0]; if (connector->mmWidth == 0 || connector->mmHeight == 0) { /* The driver doesn't return that information, default to * 160 dpi. */ xdpi = 160; ydpi = 160; } else { xdpi = (mode->hdisplay * 25.4f) / connector->mmWidth; ydpi = (mode->vdisplay * 25.4f) / connector->mmHeight; } if (mode->htotal && mode->vtotal) fps = mode->clock * 1000.0f / (mode->htotal * mode->vtotal); else fps = 60.0; /* Create two frame buffers. */ module->buffers = new private_buffer_t[FB_NUM_BUFFERS]; if (!module->buffers) { err = -ENOMEM; goto done; } memset(module->buffers, 0, FB_NUM_BUFFERS * sizeof *module->buffers); err = kms_create(fd, &module->kms); if (err < 0) goto done; for (unsigned int i = 0; i < FB_NUM_BUFFERS; ++i) { err = fb_alloc_buffer(module, &module->buffers[i], mode); if (err < 0) goto done; } err = drmModeSetCrtc(fd, module->crtc, module->buffers[0].fb, 0, 0, &connector->connector_id, 1, mode); if (err < 0) goto done; LOGI("using (fd=%d)\n" "desc = %s\n" "hdisplay = %u px\n" "vdisplay = %u px\n" "format = 0x%08x\n", fd, version->desc, mode->hdisplay, mode->vdisplay, FB_FORMAT); LOGI("width = %d mm (%f dpi)\n" "height = %d mm (%f dpi)\n" "refresh rate = %.2f Hz\n", connector->mmWidth, xdpi, connector->mmHeight, ydpi, fps); module->flags = PAGE_FLIP; module->num_buffers = FB_NUM_BUFFERS; module->mode = mode; module->xdpi = xdpi; module->ydpi = ydpi; module->fps = fps; module->stride = mode->hdisplay * 2; done: if (encoder) drmModeFreeEncoder(encoder); if (resources) drmModeFreeResources(resources); if (version) drmFreeVersion(version); if (err < 0) { if (module->buffers) { for (unsigned int i = 0; i < FB_NUM_BUFFERS; ++i) fb_free_buffer(module, &module->buffers[i]); delete[] module->buffers; } if (connector) drmModeFreeConnector(connector); if (fd != -1) drmClose(fd); } return err; }