GLXFBConfig GLXContext::getFBConfig(::Display* pDisplay, GLConfig& glConfig) { GLContextAttribs attrs; attrs.append(GLX_X_RENDERABLE, 1); attrs.append(GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT); attrs.append(GLX_RENDER_TYPE, GLX_RGBA_BIT); attrs.append(GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR); attrs.append(GLX_DEPTH_SIZE, 0); attrs.append(GLX_STENCIL_SIZE, 8); attrs.append(GLX_DOUBLEBUFFER, 1); attrs.append(GLX_RED_SIZE, 8); attrs.append(GLX_GREEN_SIZE, 8); attrs.append(GLX_BLUE_SIZE, 8); attrs.append(GLX_ALPHA_SIZE, 0); int fbCount; GLXFBConfig* pFBConfig = glXChooseFBConfig(m_pDisplay, DefaultScreen(m_pDisplay), attrs.get(), &fbCount); if (!pFBConfig) { throw Exception(AVG_ERR_UNSUPPORTED, "Creating OpenGL context failed."); } // Find the config with the appropriate number of multisample samples. int bestConfig = -1; int bestSamples = -1; int bestCaveat = std::numeric_limits<int>::max(); for (int i=0; i<fbCount; ++i) { XVisualInfo* pVisualInfo = glXGetVisualFromFBConfig(m_pDisplay, pFBConfig[i]); if (pVisualInfo && pVisualInfo->depth == 24) { int numBuffers; int numSamples; int caveat; glXGetFBConfigAttrib(m_pDisplay, pFBConfig[i], GLX_SAMPLE_BUFFERS, &numBuffers); glXGetFBConfigAttrib(m_pDisplay, pFBConfig[i], GLX_SAMPLES, &numSamples); glXGetFBConfigAttrib(m_pDisplay, pFBConfig[i], GLX_CONFIG_CAVEAT, &caveat); if (numSamples == 0) { // Configs without multisampling have numBuffers == 0 and numSamples == 0, // but the corresponding libavg config is multisamplesamples == 1. numSamples = 1; } if ((numSamples > bestSamples && numSamples <= glConfig.m_MultiSampleSamples) || (numSamples == bestSamples && caveat < bestCaveat)) { // A config is better than the last one in two cases: // 1) it has more samples per pixel (but not more than requested) or // 2) it has the same number of samples per pixel but a better caveat // value. bestCaveat = caveat; bestConfig = i; bestSamples = numSamples; } XFree(pVisualInfo); } } glConfig.m_MultiSampleSamples = bestSamples; GLXFBConfig fbConfig = pFBConfig[bestConfig]; XFree(pFBConfig); return fbConfig; }
XVisualInfo* GLXContext::createDetachedContext(::Display* pDisplay, GLConfig& glConfig, bool bOwnsDisplay) { m_pDisplay = pDisplay; m_bOwnsDisplay = bOwnsDisplay; GLXFBConfig fbConfig = getFBConfig(m_pDisplay, glConfig); XVisualInfo* pVisualInfo = glXGetVisualFromFBConfig(m_pDisplay, fbConfig); if (haveARBCreateContext()) { GLContextAttribs attrs; GLContextAttribs attrsWODebug; if (glConfig.m_bGLES) { attrs.append(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT); attrs.append(GLX_CONTEXT_MAJOR_VERSION_ARB, 2); attrs.append(GLX_CONTEXT_MINOR_VERSION_ARB, 0); } if (glConfig.m_bUseDebugContext) { attrsWODebug = attrs; attrs.append(GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB); } PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) getglXProcAddress("glXCreateContextAttribsARB"); s_bDumpX11ErrorMsg = false; m_Context = CreateContextAttribsARB(m_pDisplay, fbConfig, 0, 1, attrs.get()); s_bDumpX11ErrorMsg = true; if(!m_Context && glConfig.m_bUseDebugContext) { //On intel HW ContextCreation with DebugBit fails AVG_LOG_WARNING( "Failed to create DEBUG context… falling back to standard context"); s_bX11Error = false; m_Context = CreateContextAttribsARB(m_pDisplay, fbConfig, 0, 1, attrsWODebug.get()); AVG_ASSERT(m_Context); } } else { m_Context = glXCreateContext(m_pDisplay, pVisualInfo, 0, GL_TRUE); } AVG_ASSERT(m_Context); m_Colormap = XCreateColormap(pDisplay, RootWindow(m_pDisplay, pVisualInfo->screen), pVisualInfo->visual, AllocNone); AVG_ASSERT(m_Colormap); return pVisualInfo; }
void GLXContext::createGLXContext(const GLConfig& glConfig, const IntPoint& windowSize, const SDL_SysWMinfo* pSDLWMInfo, bool bUseDebugBit) { Window win = 0; s_bX11Error = false; s_bDumpX11ErrorMsg = true; s_DefaultErrorHandler = XSetErrorHandler(X11ErrorHandler); m_pDisplay = getX11Display(pSDLWMInfo); GLContextAttribs attrs; attrs.append(GLX_X_RENDERABLE, 1); attrs.append(GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT); attrs.append(GLX_RENDER_TYPE, GLX_RGBA_BIT); attrs.append(GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR); attrs.append(GLX_DEPTH_SIZE, 0); attrs.append(GLX_STENCIL_SIZE, 8); attrs.append(GLX_DOUBLEBUFFER, 1); attrs.append(GLX_RED_SIZE, 8); attrs.append(GLX_GREEN_SIZE, 8); attrs.append(GLX_BLUE_SIZE, 8); attrs.append(GLX_ALPHA_SIZE, 0); int fbCount; GLXFBConfig* pFBConfig = glXChooseFBConfig(m_pDisplay, DefaultScreen(m_pDisplay), attrs.get(), &fbCount); if (!pFBConfig) { throw Exception(AVG_ERR_UNSUPPORTED, "Creating OpenGL context failed."); } // Find the config with the appropriate number of multisample samples. int bestConfig = -1; int bestSamples = -1; for (int i=0; i<fbCount; ++i) { XVisualInfo* pVisualInfo = glXGetVisualFromFBConfig(m_pDisplay, pFBConfig[i]); if (pVisualInfo) { int buffer; int samples; glXGetFBConfigAttrib(m_pDisplay, pFBConfig[i], GLX_SAMPLE_BUFFERS, &buffer); glXGetFBConfigAttrib(m_pDisplay, pFBConfig[i], GLX_SAMPLES, &samples); if (bestConfig < 0 || (buffer == 1 && samples > bestSamples && samples <= glConfig.m_MultiSampleSamples)) { bestConfig = i; bestSamples = samples; } XFree(pVisualInfo); } } GLXFBConfig fbConfig = pFBConfig[bestConfig]; XFree(pFBConfig); XVisualInfo* pVisualInfo = glXGetVisualFromFBConfig(m_pDisplay, fbConfig); if (pSDLWMInfo) { win = createChildWindow(pSDLWMInfo, pVisualInfo, windowSize, m_Colormap); } if (haveARBCreateContext()) { GLContextAttribs attrs; if (isGLES()) { attrs.append(GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT); attrs.append(GLX_CONTEXT_MAJOR_VERSION_ARB, 2); attrs.append(GLX_CONTEXT_MINOR_VERSION_ARB, 0); } if (glConfig.m_bUseDebugContext && bUseDebugBit) { attrs.append(GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB); } PFNGLXCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) getglXProcAddress("glXCreateContextAttribsARB"); s_bDumpX11ErrorMsg = false; m_Context = CreateContextAttribsARB(m_pDisplay, fbConfig, 0, 1, attrs.get()); s_bDumpX11ErrorMsg = true; throwOnXError(AVG_ERR_DEBUG_CONTEXT_FAILED); } else { m_Context = glXCreateContext(m_pDisplay, pVisualInfo, 0, GL_TRUE); } AVG_ASSERT(m_Context); if (pSDLWMInfo) { setCurrent(); glXMakeCurrent(m_pDisplay, win, m_Context); } else { Pixmap pmp = XCreatePixmap(m_pDisplay, RootWindow(m_pDisplay, pVisualInfo->screen), 8, 8, pVisualInfo->depth); GLXPixmap pixmap = glXCreateGLXPixmap(m_pDisplay, pVisualInfo, pmp); glXMakeCurrent(m_pDisplay, pixmap, m_Context); } XSetErrorHandler(s_DefaultErrorHandler); throwOnXError(); m_Drawable = glXGetCurrentDrawable(); }
void EGLContext::createEGLContext(const GLConfig&, const IntPoint& windowSize) { m_bOwnsContext = true; #ifdef AVG_ENABLE_RPI m_Display = eglGetDisplay(EGL_DEFAULT_DISPLAY); #else m_xDisplay = (EGLNativeDisplayType)getX11Display(); m_Display = eglGetDisplay(m_xDisplay); #endif checkEGLError(m_Display == EGL_NO_DISPLAY, "No EGL display available"); bool bOk = eglInitialize(m_Display, NULL, NULL); checkEGLError(!bOk, "eglInitialize failed"); GLContextAttribs fbAttrs; fbAttrs.append(EGL_RED_SIZE, 1); fbAttrs.append(EGL_GREEN_SIZE, 1); fbAttrs.append(EGL_BLUE_SIZE, 1); fbAttrs.append(EGL_DEPTH_SIZE, 0); fbAttrs.append(EGL_STENCIL_SIZE, 1); #ifdef AVG_ENABLE_RPI int alphaSize = 1; #else int alphaSize = 0; #endif fbAttrs.append(EGL_ALPHA_SIZE, alphaSize); fbAttrs.append(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT); EGLint numFBConfig; EGLConfig config; bOk = eglChooseConfig(m_Display, fbAttrs.get(), &config, 1, &numFBConfig); checkEGLError(!bOk, "Failed to choose EGL config"); EGLint vid; bOk = eglGetConfigAttrib(m_Display, config, EGL_NATIVE_VISUAL_ID, &vid); AVG_ASSERT(bOk); #ifndef AVG_ENABLE_RPI XVisualInfo visTemplate; visTemplate.visualid = vid; int num_visuals; XVisualInfo* pVisualInfo = XGetVisualInfo((_XDisplay*)m_xDisplay, VisualIDMask, &visTemplate, &num_visuals); AVG_ASSERT(pVisualInfo); #endif if (!eglBindAPI(EGL_OPENGL_ES_API)) { cerr << "Failed to bind GLES API to EGL\n"; return; } if (numFBConfig != 1) { cerr << "Didn't get exactly one config, but " << numFBConfig << endl; return; } #ifdef AVG_ENABLE_RPI m_Surface = createBCMPixmapSurface(m_Display, config); #else XVisualInfo visTemplate, *results; visTemplate.screen = 0; int numVisuals; results = XGetVisualInfo((_XDisplay*)m_xDisplay, VisualScreenMask, &visTemplate, & numVisuals); Pixmap pmp = XCreatePixmap((_XDisplay*)m_xDisplay, RootWindow((_XDisplay*)m_xDisplay, results[0].screen), 8, 8, results[0].depth); m_Surface = eglCreatePixmapSurface(m_Display, config, (EGLNativePixmapType)pmp, NULL); #endif //dumpEGLConfig(config); AVG_ASSERT(m_Surface); GLContextAttribs attrs; attrs.append(EGL_CONTEXT_CLIENT_VERSION, 2); m_Context = eglCreateContext(m_Display, config, NULL, attrs.get()); checkEGLError(!m_Context, "Unable to create EGL context"); }