static bool config_window_w32(struct MPGLContext *ctx, int flags) { if (!vo_w32_config(ctx->vo, flags)) return false; bool success = false; if (ctx->requested_gl_version >= MPGL_VER(3, 0)) success = create_context_w32_gl3(ctx); if (!success) success = create_context_w32_old(ctx); return success; }
static bool create_context_x11_old(struct MPGLContext *ctx) { struct glx_context *glx_ctx = ctx->priv; Display *display = ctx->vo->x11->display; struct vo *vo = ctx->vo; GL *gl = ctx->gl; if (glx_ctx->context) return true; GLXContext new_context = glXCreateContext(display, glx_ctx->vinfo, NULL, True); if (!new_context) { MP_FATAL(vo, "Could not create GLX context!\n"); return false; } if (!glXMakeCurrent(display, ctx->vo->x11->window, new_context)) { MP_FATAL(vo, "Could not set GLX context!\n"); glXDestroyContext(display, new_context); return false; } void *(*getProcAddress)(const GLubyte *); getProcAddress = mp_getdladdr("glXGetProcAddress"); if (!getProcAddress) getProcAddress = mp_getdladdr("glXGetProcAddressARB"); const char *glxstr = ""; const char *(*glXExtStr)(Display *, int) = mp_getdladdr("glXQueryExtensionsString"); if (glXExtStr) glxstr = glXExtStr(display, ctx->vo->x11->screen); mpgl_load_functions(gl, getProcAddress, glxstr, vo->log); if (!gl->GenPrograms && gl->GetString && gl->version < MPGL_VER(3, 0) && strstr(gl->GetString(GL_EXTENSIONS), "GL_ARB_vertex_program")) { MP_WARN(vo, "Broken glXGetProcAddress detected, trying workaround\n"); mpgl_load_functions(gl, NULL, glxstr, vo->log); } glx_ctx->context = new_context; if (!glXIsDirect(vo->x11->display, new_context)) ctx->gl->mpgl_caps &= ~MPGL_CAP_NO_SW; return true; }
static bool config_window_cocoa(struct MPGLContext *ctx, int flags) { int rv = vo_cocoa_config_window(ctx->vo, flags, ctx->requested_gl_version >= MPGL_VER(3, 0)); if (rv != 0) return false; mpgl_load_functions(ctx->gl, (void *)vo_cocoa_glgetaddr, NULL, ctx->vo->log); ctx->depth_r = vo_cocoa_cgl_color_size(ctx->vo); ctx->depth_g = vo_cocoa_cgl_color_size(ctx->vo); ctx->depth_b = vo_cocoa_cgl_color_size(ctx->vo); if (!ctx->gl->SwapInterval) ctx->gl->SwapInterval = vo_cocoa_swap_interval; vo_cocoa_register_gl_clear_callback(ctx->vo, ctx->gl, gl_clear); return true; }
static bool config_window_x11(struct MPGLContext *ctx, uint32_t d_width, uint32_t d_height, uint32_t flags) { struct vo *vo = ctx->vo; struct glx_context *glx_ctx = ctx->priv; if (glx_ctx->context) { // GL context and window already exist. // Only update window geometry etc. vo_x11_config_vo_window(vo, glx_ctx->vinfo, d_width, d_height, flags, "gl"); return true; } int glx_major, glx_minor; // FBConfigs were added in GLX version 1.3. if (!glXQueryVersion(vo->x11->display, &glx_major, &glx_minor) || (MPGL_VER(glx_major, glx_minor) < MPGL_VER(1, 3))) { MP_ERR(vo, "GLX version older than 1.3.\n"); return false; } int glx_attribs[] = { GLX_STEREO, False, GLX_X_RENDERABLE, True, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 0, GLX_DOUBLEBUFFER, True, None }; GLXFBConfig fbc = NULL; if (flags & VOFLAG_ALPHA) { set_glx_attrib(glx_attribs, GLX_ALPHA_SIZE, 1); fbc = select_fb_config(vo, glx_attribs, flags); if (!fbc) { set_glx_attrib(glx_attribs, GLX_ALPHA_SIZE, 0); flags &= ~VOFLAG_ALPHA; } } if (flags & VOFLAG_STEREO) { set_glx_attrib(glx_attribs, GLX_STEREO, True); fbc = select_fb_config(vo, glx_attribs, flags); if (!fbc) { MP_ERR(vo, "Could not find a stereo visual," " 3D will probably not work!\n"); set_glx_attrib(glx_attribs, GLX_STEREO, False); flags &= ~VOFLAG_STEREO; } } if (!fbc) fbc = select_fb_config(vo, glx_attribs, flags); if (!fbc) { MP_ERR(vo, "no GLX support present\n"); return false; } glx_ctx->fbc = fbc; glx_ctx->vinfo = glXGetVisualFromFBConfig(vo->x11->display, fbc); if (!glx_ctx->vinfo) { MP_ERR(vo, "Selected GLX FB config has no associated X visual\n"); return false; } MP_VERBOSE(vo, "GLX chose visual with ID 0x%x\n", (int)glx_ctx->vinfo->visualid); glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_RED_SIZE, &ctx->depth_r); glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_GREEN_SIZE, &ctx->depth_g); glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_BLUE_SIZE, &ctx->depth_b); vo_x11_config_vo_window(vo, glx_ctx->vinfo, d_width, d_height, flags, "gl"); bool success = false; if (ctx->requested_gl_version >= MPGL_VER(3, 0)) success = create_context_x11_gl3(ctx, flags & VOFLAG_GL_DEBUG); if (!success) success = create_context_x11_old(ctx); return success; }
static bool config_window_x11(struct MPGLContext *ctx, int flags) { struct vo *vo = ctx->vo; struct glx_context *glx_ctx = ctx->priv; int glx_major, glx_minor; if (!glXQueryVersion(vo->x11->display, &glx_major, &glx_minor)) { MP_ERR(vo, "GLX not found.\n"); return false; } // FBConfigs were added in GLX version 1.3. if (MPGL_VER(glx_major, glx_minor) < MPGL_VER(1, 3)) { MP_ERR(vo, "GLX version older than 1.3.\n"); return false; } int glx_attribs[] = { GLX_X_RENDERABLE, True, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 0, GLX_DOUBLEBUFFER, True, None }; GLXFBConfig fbc = NULL; if (flags & VOFLAG_ALPHA) { set_glx_attrib(glx_attribs, GLX_ALPHA_SIZE, 1); fbc = select_fb_config(vo, glx_attribs, flags); if (!fbc) { set_glx_attrib(glx_attribs, GLX_ALPHA_SIZE, 0); flags &= ~VOFLAG_ALPHA; } } if (!fbc) fbc = select_fb_config(vo, glx_attribs, flags); if (!fbc) { MP_ERR(vo, "no GLX support present\n"); return false; } MP_VERBOSE(vo, "GLX chose FB config with ID 0x%x\n", (int)(intptr_t)fbc); glx_ctx->fbc = fbc; glx_ctx->vinfo = glXGetVisualFromFBConfig(vo->x11->display, fbc); if (glx_ctx->vinfo) { MP_VERBOSE(vo, "GLX chose visual with ID 0x%x\n", (int)glx_ctx->vinfo->visualid); } else { MP_WARN(vo, "Selected GLX FB config has no associated X visual\n"); } glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_RED_SIZE, &ctx->depth_r); glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_GREEN_SIZE, &ctx->depth_g); glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_BLUE_SIZE, &ctx->depth_b); if (!vo_x11_create_vo_window(vo, glx_ctx->vinfo, "gl")) return false; bool success = false; if (!(flags & VOFLAG_GLES)) { success = create_context_x11_gl3(ctx, flags, 300, false); if (!success) success = create_context_x11_old(ctx); } if (!success) // try ES success = create_context_x11_gl3(ctx, flags, 200, true); if (success && !glXIsDirect(vo->x11->display, glx_ctx->context)) ctx->gl->mpgl_caps |= MPGL_CAP_SW; return success; }
static int glx_init(struct MPGLContext *ctx, int flags) { struct vo *vo = ctx->vo; struct glx_context *glx_ctx = ctx->priv; if (!vo_x11_init(ctx->vo)) goto uninit; int glx_major, glx_minor; if (!glXQueryVersion(vo->x11->display, &glx_major, &glx_minor)) { MP_ERR(vo, "GLX not found.\n"); goto uninit; } // FBConfigs were added in GLX version 1.3. if (MPGL_VER(glx_major, glx_minor) < MPGL_VER(1, 3)) { MP_ERR(vo, "GLX version older than 1.3.\n"); goto uninit; } int glx_attribs[] = { GLX_X_RENDERABLE, True, GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_ALPHA_SIZE, 0, GLX_DOUBLEBUFFER, True, None }; GLXFBConfig fbc = NULL; if (flags & VOFLAG_ALPHA) { set_glx_attrib(glx_attribs, GLX_ALPHA_SIZE, 1); fbc = select_fb_config(vo, glx_attribs, flags); if (!fbc) { set_glx_attrib(glx_attribs, GLX_ALPHA_SIZE, 0); flags &= ~VOFLAG_ALPHA; } } if (!fbc) fbc = select_fb_config(vo, glx_attribs, flags); if (!fbc) { MP_ERR(vo, "no GLX support present\n"); goto uninit; } MP_VERBOSE(vo, "GLX chose FB config with ID 0x%x\n", (int)(intptr_t)fbc); glx_ctx->fbc = fbc; glx_ctx->vinfo = glXGetVisualFromFBConfig(vo->x11->display, fbc); if (glx_ctx->vinfo) { MP_VERBOSE(vo, "GLX chose visual with ID 0x%x\n", (int)glx_ctx->vinfo->visualid); } else { MP_WARN(vo, "Selected GLX FB config has no associated X visual\n"); } if (!vo_x11_create_vo_window(vo, glx_ctx->vinfo, "gl")) goto uninit; bool success = false; if (!(flags & VOFLAG_GLES)) { for (int n = 0; mpgl_preferred_gl_versions[n]; n++) { int version = mpgl_preferred_gl_versions[n]; MP_VERBOSE(vo, "Creating OpenGL %d.%d context...\n", MPGL_VER_P(version)); if (version >= 300) { success = create_context_x11_gl3(ctx, flags, version, false); } else { success = create_context_x11_old(ctx); } if (success) break; } } if (!success) // try ES success = create_context_x11_gl3(ctx, flags, 200, true); if (success && !glXIsDirect(vo->x11->display, glx_ctx->context)) ctx->gl->mpgl_caps |= MPGL_CAP_SW; if (!success) goto uninit; glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_RED_SIZE, &ctx->gl->fb_r); glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_GREEN_SIZE, &ctx->gl->fb_g); glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_BLUE_SIZE, &ctx->gl->fb_b); ctx->gl->fb_premultiplied = true; return 0; uninit: glx_uninit(ctx); return -1; }