bool GLXLibrary::EnsureInitialized(LibType libType) { if (mInitialized) { return true; } // Don't repeatedly try to initialize. if (mTriedInitializing) { return false; } mTriedInitializing = true; // Force enabling s3 texture compression. (Bug 774134) PR_SetEnv("force_s3tc_enable=true"); if (!mOGLLibrary) { const char* libGLfilename = nullptr; bool forceFeatureReport = false; switch (libType) { case MESA_LLVMPIPE_LIB: libGLfilename = "mesallvmpipe.so"; forceFeatureReport = true; break; case OPENGL_LIB: // see e.g. bug 608526: it is intrinsically interesting to know whether we have dynamically linked to libGL.so.1 // because at least the NVIDIA implementation requires an executable stack, which causes mprotect calls, // which trigger glibc bug http://sourceware.org/bugzilla/show_bug.cgi?id=12225 #ifdef __OpenBSD__ libGLfilename = "libGL.so"; #else libGLfilename = "libGL.so.1"; #endif break; default: MOZ_CRASH("Invalid GLX library type."); } ScopedGfxFeatureReporter reporter(libGLfilename, forceFeatureReport); mOGLLibrary = PR_LoadLibrary(libGLfilename); if (!mOGLLibrary) { NS_WARNING("Couldn't load OpenGL shared library."); return false; } reporter.SetSuccessful(); } if (PR_GetEnv("MOZ_GLX_DEBUG")) { mDebug = true; } GLLibraryLoader::SymLoadStruct symbols[] = { /* functions that were in GLX 1.0 */ { (PRFuncPtr*) &xDestroyContextInternal, { "glXDestroyContext", nullptr } }, { (PRFuncPtr*) &xMakeCurrentInternal, { "glXMakeCurrent", nullptr } }, { (PRFuncPtr*) &xSwapBuffersInternal, { "glXSwapBuffers", nullptr } }, { (PRFuncPtr*) &xQueryVersionInternal, { "glXQueryVersion", nullptr } }, { (PRFuncPtr*) &xGetCurrentContextInternal, { "glXGetCurrentContext", nullptr } }, { (PRFuncPtr*) &xWaitGLInternal, { "glXWaitGL", nullptr } }, { (PRFuncPtr*) &xWaitXInternal, { "glXWaitX", nullptr } }, /* functions introduced in GLX 1.1 */ { (PRFuncPtr*) &xQueryExtensionsStringInternal, { "glXQueryExtensionsString", nullptr } }, { (PRFuncPtr*) &xGetClientStringInternal, { "glXGetClientString", nullptr } }, { (PRFuncPtr*) &xQueryServerStringInternal, { "glXQueryServerString", nullptr } }, { nullptr, { nullptr } } }; GLLibraryLoader::SymLoadStruct symbols13[] = { /* functions introduced in GLX 1.3 */ { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfig", nullptr } }, { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttrib", nullptr } }, // WARNING: xGetFBConfigs not set in symbols13_ext { (PRFuncPtr*) &xGetFBConfigsInternal, { "glXGetFBConfigs", nullptr } }, // WARNING: symbols13_ext sets xCreateGLXPixmapWithConfig instead { (PRFuncPtr*) &xCreatePixmapInternal, { "glXCreatePixmap", nullptr } }, { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyPixmap", nullptr } }, { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateNewContext", nullptr } }, { nullptr, { nullptr } } }; GLLibraryLoader::SymLoadStruct symbols13_ext[] = { /* extension equivalents for functions introduced in GLX 1.3 */ // GLX_SGIX_fbconfig extension { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfigSGIX", nullptr } }, { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttribSGIX", nullptr } }, // WARNING: no xGetFBConfigs equivalent in extensions // WARNING: different from symbols13: { (PRFuncPtr*) &xCreateGLXPixmapWithConfigInternal, { "glXCreateGLXPixmapWithConfigSGIX", nullptr } }, { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyGLXPixmap", nullptr } }, // not from ext { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateContextWithConfigSGIX", nullptr } }, { nullptr, { nullptr } } }; GLLibraryLoader::SymLoadStruct symbols14[] = { /* functions introduced in GLX 1.4 */ { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddress", nullptr } }, { nullptr, { nullptr } } }; GLLibraryLoader::SymLoadStruct symbols14_ext[] = { /* extension equivalents for functions introduced in GLX 1.4 */ // GLX_ARB_get_proc_address extension { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddressARB", nullptr } }, { nullptr, { nullptr } } }; GLLibraryLoader::SymLoadStruct symbols_texturefrompixmap[] = { { (PRFuncPtr*) &xBindTexImageInternal, { "glXBindTexImageEXT", nullptr } }, { (PRFuncPtr*) &xReleaseTexImageInternal, { "glXReleaseTexImageEXT", nullptr } }, { nullptr, { nullptr } } }; GLLibraryLoader::SymLoadStruct symbols_robustness[] = { { (PRFuncPtr*) &xCreateContextAttribsInternal, { "glXCreateContextAttribsARB", nullptr } }, { nullptr, { nullptr } } }; if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &symbols[0])) { NS_WARNING("Couldn't find required entry point in OpenGL shared library"); return false; } Display *display = DefaultXDisplay(); int screen = DefaultScreen(display); if (!xQueryVersion(display, &mGLXMajorVersion, &mGLXMinorVersion)) { mGLXMajorVersion = 0; mGLXMinorVersion = 0; return false; } if (!GLXVersionCheck(1, 1)) // Not possible to query for extensions. return false; const char *clientVendor = xGetClientString(display, LOCAL_GLX_VENDOR); const char *serverVendor = xQueryServerString(display, screen, LOCAL_GLX_VENDOR); const char *extensionsStr = xQueryExtensionsString(display, screen); GLLibraryLoader::SymLoadStruct *sym13; if (!GLXVersionCheck(1, 3)) { // Even if we don't have 1.3, we might have equivalent extensions // (as on the Intel X server). if (!HasExtension(extensionsStr, "GLX_SGIX_fbconfig")) { return false; } sym13 = symbols13_ext; } else { sym13 = symbols13; } if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym13)) { NS_WARNING("Couldn't find required entry point in OpenGL shared library"); return false; } GLLibraryLoader::SymLoadStruct *sym14; if (!GLXVersionCheck(1, 4)) { // Even if we don't have 1.4, we might have equivalent extensions // (as on the Intel X server). if (!HasExtension(extensionsStr, "GLX_ARB_get_proc_address")) { return false; } sym14 = symbols14_ext; } else { sym14 = symbols14; } if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym14)) { NS_WARNING("Couldn't find required entry point in OpenGL shared library"); return false; } if (HasExtension(extensionsStr, "GLX_EXT_texture_from_pixmap") && GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap, (GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress)) { #ifdef MOZ_WIDGET_GTK mUseTextureFromPixmap = gfxPlatformGtk::GetPlatform()->UseXRender(); #else mUseTextureFromPixmap = true; #endif } else { mUseTextureFromPixmap = false; NS_WARNING("Texture from pixmap disabled"); } if (HasExtension(extensionsStr, "GLX_ARB_create_context_robustness") && GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) { mHasRobustness = true; } mIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI"); mIsNVIDIA = serverVendor && DoesStringMatch(serverVendor, "NVIDIA Corporation"); mClientIsMesa = clientVendor && DoesStringMatch(clientVendor, "Mesa"); mInitialized = true; mLibType = libType; return true; }
PRBool GLXLibrary::EnsureInitialized() { if (mInitialized) { return PR_TRUE; } if (!mOGLLibrary) { mOGLLibrary = PR_LoadLibrary("libGL.so.1"); if (!mOGLLibrary) { NS_WARNING("Couldn't load OpenGL shared library."); return PR_FALSE; } } LibrarySymbolLoader::SymLoadStruct symbols[] = { { (PRFuncPtr*) &xDeleteContext, { "glXDestroyContext", NULL } }, { (PRFuncPtr*) &xMakeCurrent, { "glXMakeCurrent", NULL } }, { (PRFuncPtr*) &xGetProcAddress, { "glXGetProcAddress", NULL } }, { (PRFuncPtr*) &xChooseVisual, { "glXChooseVisual", NULL } }, { (PRFuncPtr*) &xChooseFBConfig, { "glXChooseFBConfig", NULL } }, { (PRFuncPtr*) &xGetFBConfigs, { "glXGetFBConfigs", NULL } }, { (PRFuncPtr*) &xCreatePbuffer, { "glXCreatePbuffer", NULL } }, { (PRFuncPtr*) &xCreateNewContext, { "glXCreateNewContext", NULL } }, { (PRFuncPtr*) &xDestroyPbuffer, { "glXDestroyPbuffer", NULL } }, { (PRFuncPtr*) &xGetVisualFromFBConfig, { "glXGetVisualFromFBConfig", NULL } }, { (PRFuncPtr*) &xGetFBConfigAttrib, { "glXGetFBConfigAttrib", NULL } }, { (PRFuncPtr*) &xSwapBuffers, { "glXSwapBuffers", NULL } }, { (PRFuncPtr*) &xQueryServerString, { "glXQueryServerString", NULL } }, { (PRFuncPtr*) &xCreatePixmap, { "glXCreatePixmap", NULL } }, { (PRFuncPtr*) &xDestroyPixmap, { "glXDestroyPixmap", NULL } }, { (PRFuncPtr*) &xGetClientString, { "glXGetClientString", NULL } }, { (PRFuncPtr*) &xCreateContext, { "glXCreateContext", NULL } }, { NULL, { NULL } } }; if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) { NS_WARNING("Couldn't find required entry point in OpenGL shared library"); return PR_FALSE; } const char *vendor = xQueryServerString(DefaultXDisplay(), DefaultScreen(DefaultXDisplay()), GLX_VENDOR); const char *serverVersionStr = xQueryServerString(DefaultXDisplay(), DefaultScreen(DefaultXDisplay()), GLX_VERSION); const char *clientVersionStr = xGetClientString(DefaultXDisplay(), GLX_VERSION); int serverVersion = 0, clientVersion = 0; if (serverVersionStr && strlen(serverVersionStr) >= 3 && serverVersionStr[1] == '.') { serverVersion = (serverVersionStr[0] - '0') << 8 | (serverVersionStr[2] - '0'); } if (clientVersionStr && strlen(clientVersionStr) >= 3 && clientVersionStr[1] == '.') { clientVersion = (clientVersionStr[0] - '0') << 8 | (clientVersionStr[2] - '0'); } gGLXVersion = PR_MIN(clientVersion, serverVersion); if (gGLXVersion < 0x0103) return PR_FALSE; gIsATI = vendor && strstr(vendor, "ATI"); gIsChromium = (vendor && strstr(vendor, "Chromium")) || (serverVersion && strstr(serverVersionStr, "Chromium")); mInitialized = PR_TRUE; return PR_TRUE; }