static int mpegl_init(struct MPGLContext *ctx, int flags) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; bool es = flags & VOFLAG_GLES; int msgl = vo->probing ? MSGL_V : MSGL_FATAL; if (!vo_x11_init(vo)) goto uninit; if (!eglBindAPI(es ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) { mp_msg(vo->log, msgl, "Could not bind API (%s).\n", es ? "GLES" : "GL"); goto uninit; } p->egl_display = eglGetDisplay(vo->x11->display); if (!eglInitialize(p->egl_display, NULL, NULL)) { mp_msg(vo->log, msgl, "Could not initialize EGL.\n"); goto uninit; } EGLConfig config = select_fb_config_egl(ctx, es); if (!config) goto uninit; int vID, n; eglGetConfigAttrib(p->egl_display, config, EGL_NATIVE_VISUAL_ID, &vID); XVisualInfo template = {.visualid = vID};
static bool init_egl(struct MPGLContext *ctx, bool es) { struct priv *p = ctx->priv; MP_VERBOSE(ctx->vo, "Initializing EGL\n"); p->egl.display = eglGetDisplay(p->gbm.device); if (p->egl.display == EGL_NO_DISPLAY) { MP_ERR(ctx->vo, "Failed to get EGL display.\n"); return false; } if (!eglInitialize(p->egl.display, NULL, NULL)) { MP_ERR(ctx->vo, "Failed to initialize EGL.\n"); return false; } if (!eglBindAPI(es ? EGL_OPENGL_ES_API : EGL_OPENGL_API)) { MP_ERR(ctx->vo, "Failed to set EGL API version.\n"); return false; } EGLConfig config = select_fb_config_egl(ctx, es); if (!config) { MP_ERR(ctx->vo, "Failed to configure EGL.\n"); return false; } p->egl.context = eglCreateContext(p->egl.display, config, EGL_NO_CONTEXT, NULL); if (!p->egl.context) { MP_ERR(ctx->vo, "Failed to create EGL context.\n"); return false; } MP_VERBOSE(ctx->vo, "Initializing EGL surface\n"); 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; } return true; }
int mp_egl_rpi_init(struct mp_egl_rpi *p, DISPMANX_ELEMENT_HANDLE_T window, int w, int h) { p->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (!eglInitialize(p->egl_display, NULL, NULL)) { MP_FATAL(p, "EGL failed to initialize.\n"); goto fail; } eglBindAPI(EGL_OPENGL_ES_API); EGLConfig config = select_fb_config_egl(p); if (!config) goto fail; p->egl_window = (EGL_DISPMANX_WINDOW_T){ .element = window, .width = w, .height = h, }; p->egl_surface = eglCreateWindowSurface(p->egl_display, config, &p->egl_window, NULL); if (p->egl_surface == EGL_NO_SURFACE) { MP_FATAL(p, "Could not create EGL surface!\n"); goto fail; } EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; p->egl_context = eglCreateContext(p->egl_display, config, EGL_NO_CONTEXT, context_attributes); if (p->egl_context == EGL_NO_CONTEXT) { MP_FATAL(p, "Could not create EGL context!\n"); goto fail; } eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface, p->egl_context); p->gl = talloc_zero(NULL, struct GL); const char *exts = eglQueryString(p->egl_display, EGL_EXTENSIONS); mpgl_load_functions(p->gl, get_proc_address, exts, p->log); if (!p->gl->version && !p->gl->es) goto fail; return 0; fail: mp_egl_rpi_destroy(p); return -1; }
static int angle_init(struct MPGLContext *ctx, int flags) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; if (!angle_load()) { MP_VERBOSE(vo, "Failed to load LIBEGL.DLL\n"); goto fail; } if (!vo_w32_init(vo)) goto fail; HDC dc = GetDC(vo_w32_hwnd(vo)); if (!dc) { MP_FATAL(vo, "Couldn't get DC\n"); goto fail; } PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); if (!eglGetPlatformDisplayEXT) { MP_FATAL(vo, "Missing EGL_EXT_platform_base\n"); goto fail; } EGLint d3d_types[] = {EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE}; EGLint d3d_dev_types[] = {EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE}; for (int i = 0; i < MP_ARRAY_SIZE(d3d_types); i++) { EGLint display_attributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, d3d_types[i], EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, d3d_dev_types[i], EGL_NONE, }; p->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, display_attributes); if (p->egl_display == EGL_NO_DISPLAY) continue; if (!eglInitialize(p->egl_display, NULL, NULL)) { p->egl_display = EGL_NO_DISPLAY; continue; } if (d3d_dev_types[i] == EGL_PLATFORM_ANGLE_DEVICE_TYPE_WARP_ANGLE) show_sw_adapter_msg(ctx); break; } if (p->egl_display == EGL_NO_DISPLAY) { MP_FATAL(vo, "Couldn't get display\n"); goto fail; } const char *exts = eglQueryString(p->egl_display, EGL_EXTENSIONS); if (exts) MP_DBG(ctx->vo, "EGL extensions: %s\n", exts); eglBindAPI(EGL_OPENGL_ES_API); if (eglGetError() != EGL_SUCCESS) { MP_FATAL(vo, "Couldn't bind GLES API\n"); goto fail; } EGLConfig config = select_fb_config_egl(ctx); if (!config) goto fail; int window_attribs_len = 0; EGLint *window_attribs = NULL; EGLint flip_val; if (eglGetConfigAttrib(p->egl_display, config, EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE, &flip_val)) { if (flip_val == EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE) { MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_SURFACE_ORIENTATION_ANGLE); MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_SURFACE_ORIENTATION_INVERT_Y_ANGLE); ctx->flip_v = true; MP_VERBOSE(vo, "Rendering flipped.\n"); } } // EGL_DIRECT_COMPOSITION_ANGLE enables the use of flip-mode present, which // avoids a copy of the video image and lowers vsync jitter, though the // extension is only present on Windows 8 and up. if (strstr(exts, "EGL_ANGLE_direct_composition")) { MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_DIRECT_COMPOSITION_ANGLE); MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_TRUE); MP_VERBOSE(vo, "Using DirectComposition.\n"); } MP_TARRAY_APPEND(NULL, window_attribs, window_attribs_len, EGL_NONE); p->egl_surface = eglCreateWindowSurface(p->egl_display, config, vo_w32_hwnd(vo), window_attribs); talloc_free(window_attribs); if (p->egl_surface == EGL_NO_SURFACE) { MP_FATAL(ctx->vo, "Could not create EGL surface!\n"); goto fail; } if (!(!p->use_es2 && create_context_egl(ctx, config, 3)) && !create_context_egl(ctx, config, 2)) { MP_FATAL(ctx->vo, "Could not create EGL context!\n"); goto fail; } // Configure the underlying Direct3D device d3d_init(ctx); if (strstr(exts, "EGL_NV_post_sub_buffer")) { p->eglPostSubBufferNV = (PFNEGLPOSTSUBBUFFERNVPROC)eglGetProcAddress("eglPostSubBufferNV"); } mpgl_load_functions(ctx->gl, get_proc_address, NULL, vo->log); return 0; fail: angle_uninit(ctx); return -1; }
static int angle_init(struct MPGLContext *ctx, int flags) { struct priv *p = ctx->priv; struct vo *vo = ctx->vo; if (!vo_w32_init(vo)) goto fail; HDC dc = GetDC(vo_w32_hwnd(vo)); if (!dc) { MP_FATAL(vo, "Couldn't get DC\n"); goto fail; } PFNEGLGETPLATFORMDISPLAYEXTPROC eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)eglGetProcAddress("eglGetPlatformDisplayEXT"); if (!eglGetPlatformDisplayEXT) { MP_FATAL(vo, "Missing EGL_EXT_platform_base\n"); goto fail; } EGLint d3d_types[] = {EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE}; for (int i = 0; i < MP_ARRAY_SIZE(d3d_types); i++) { EGLint display_attributes[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE, d3d_types[i], EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, EGL_NONE, }; p->egl_display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, display_attributes); if (p->egl_display != EGL_NO_DISPLAY) break; } if (p->egl_display == EGL_NO_DISPLAY) { MP_FATAL(vo, "Couldn't get display\n"); goto fail; } if (!eglInitialize(p->egl_display, NULL, NULL)) { MP_FATAL(vo, "Couldn't initialize EGL\n"); goto fail; } eglBindAPI(EGL_OPENGL_ES_API); if (eglGetError() != EGL_SUCCESS) { MP_FATAL(vo, "Couldn't bind GLES API\n"); goto fail; } EGLConfig config = select_fb_config_egl(ctx); if (!config) goto fail; p->egl_surface = eglCreateWindowSurface(p->egl_display, config, vo_w32_hwnd(vo), NULL); if (p->egl_surface == EGL_NO_SURFACE) { MP_FATAL(ctx->vo, "Could not create EGL surface!\n"); goto fail; } if (!create_context_egl(ctx, config, 3) && !create_context_egl(ctx, config, 2)) { MP_FATAL(ctx->vo, "Could not create EGL context!\n"); goto fail; } mpgl_load_functions(ctx->gl, get_proc_address, NULL, vo->log); return 0; fail: angle_uninit(ctx); return -1; }