From 749bd14db4cc0b5fdf9c9cb5b6b7ada0fa3ab729 Mon Sep 17 00:00:00 2001 From: TheComet Date: Thu, 22 Nov 2018 23:32:44 +0100 Subject: [PATCH] fixes #1559 - Support opening default display when the user specifies a custom window handle but no display device --- src/glcontext_glx.cpp | 74 +++++++++++++++++++++++++++---------------- src/glcontext_glx.h | 2 ++ 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/glcontext_glx.cpp b/src/glcontext_glx.cpp index 5a614e40e..b968267e9 100644 --- a/src/glcontext_glx.cpp +++ b/src/glcontext_glx.cpp @@ -29,28 +29,30 @@ namespace bgfx { namespace gl struct SwapChainGL { - SwapChainGL(::Window _window, XVisualInfo* _visualInfo, GLXContext _context) - : m_window(_window) + SwapChainGL(::Display* display, ::Window _window, XVisualInfo* _visualInfo, GLXContext _context) + : m_display(display) + , m_window(_window) { - m_context = glXCreateContext( (::Display*)g_platformData.ndt, _visualInfo, _context, GL_TRUE); + m_context = glXCreateContext(m_display, _visualInfo, _context, GL_TRUE); } ~SwapChainGL() { - glXMakeCurrent( (::Display*)g_platformData.ndt, 0, 0); - glXDestroyContext( (::Display*)g_platformData.ndt, m_context); + glXMakeCurrent(m_display, 0, 0); + glXDestroyContext(m_display, m_context); } void makeCurrent() { - glXMakeCurrent( (::Display*)g_platformData.ndt, m_window, m_context); + glXMakeCurrent(m_display, m_window, m_context); } void swapBuffers() { - glXSwapBuffers( (::Display*)g_platformData.ndt, m_window); + glXSwapBuffers(m_display, m_window); } + ::Display* m_display; Window m_window; GLXContext m_context; }; @@ -60,13 +62,23 @@ namespace bgfx { namespace gl BX_UNUSED(_width, _height); m_context = (GLXContext)g_platformData.context; + m_display = (::Display*)g_platformData.ndt; + + // It's possible the user has provided the window handle, but not + // the display handle. If this is the case, try opening the default + // display + if (NULL == m_display) + { + m_display = XOpenDisplay(NULL); + BGFX_FATAL(m_display, Fatal::UnableToInitialize, "XOpenDisplay(NULL) : Failed to open default display"); + } if (NULL == g_platformData.context) { - XLockDisplay( (::Display*)g_platformData.ndt); + XLockDisplay(m_display); int major, minor; - bool version = glXQueryVersion( (::Display*)g_platformData.ndt, &major, &minor); + bool version = glXQueryVersion(m_display, &major, &minor); BGFX_FATAL(version, Fatal::UnableToInitialize, "Failed to query GLX version"); BGFX_FATAL( (major == 1 && minor >= 2) || major > 1 , Fatal::UnableToInitialize @@ -75,9 +87,9 @@ namespace bgfx { namespace gl , minor ); - int32_t screen = DefaultScreen( (::Display*)g_platformData.ndt); + int32_t screen = DefaultScreen(m_display); - const char* extensions = glXQueryExtensionsString( (::Display*)g_platformData.ndt, screen); + const char* extensions = glXQueryExtensionsString(m_display, screen); BX_TRACE("GLX extensions:"); dumpExtensions(extensions); @@ -99,13 +111,13 @@ namespace bgfx { namespace gl GLXFBConfig bestConfig = NULL; int numConfigs; - GLXFBConfig* configs = glXChooseFBConfig( (::Display*)g_platformData.ndt, screen, attrsGlx, &numConfigs); + GLXFBConfig* configs = glXChooseFBConfig(m_display, screen, attrsGlx, &numConfigs); BX_TRACE("glX num configs %d", numConfigs); for (int ii = 0; ii < numConfigs; ++ii) { - m_visualInfo = glXGetVisualFromFBConfig( (::Display*)g_platformData.ndt, configs[ii]); + m_visualInfo = glXGetVisualFromFBConfig(m_display, configs[ii]); if (NULL != m_visualInfo) { BX_TRACE("---"); @@ -113,7 +125,7 @@ namespace bgfx { namespace gl for (uint32_t attr = 6; attr < BX_COUNTOF(attrsGlx)-1 && attrsGlx[attr] != 0; attr += 2) { int value; - glXGetFBConfigAttrib( (::Display*)g_platformData.ndt, configs[ii], attrsGlx[attr], &value); + glXGetFBConfigAttrib(m_display, configs[ii], attrsGlx[attr], &value); BX_TRACE("glX %d/%d %2d: %4x, %8x (%8x%s)" , ii , numConfigs @@ -149,7 +161,7 @@ namespace bgfx { namespace gl BGFX_FATAL(m_visualInfo, Fatal::UnableToInitialize, "Failed to find a suitable X11 display configuration."); BX_TRACE("Create GL 2.1 context."); - m_context = glXCreateContext( (::Display*)g_platformData.ndt, m_visualInfo, 0, GL_TRUE); + m_context = glXCreateContext(m_display, m_visualInfo, 0, GL_TRUE); BGFX_FATAL(NULL != m_context, Fatal::UnableToInitialize, "Failed to create GL 2.1 context."); #if BGFX_CONFIG_RENDERER_OPENGL >= 31 @@ -168,11 +180,11 @@ namespace bgfx { namespace gl 0, }; - GLXContext context = glXCreateContextAttribsARB( (::Display*)g_platformData.ndt, bestConfig, 0, true, contextAttrs); + GLXContext context = glXCreateContextAttribsARB(m_display, bestConfig, 0, true, contextAttrs); if (NULL != context) { - glXDestroyContext( (::Display*)g_platformData.ndt, m_context); + glXDestroyContext(m_display, m_context); m_context = context; } } @@ -180,19 +192,19 @@ namespace bgfx { namespace gl BX_UNUSED(bestConfig); #endif // BGFX_CONFIG_RENDERER_OPENGL >= 31 - XUnlockDisplay( (::Display*)g_platformData.ndt); + XUnlockDisplay(m_display); } import(); - glXMakeCurrent( (::Display*)g_platformData.ndt, (::Window)g_platformData.nwh, m_context); + glXMakeCurrent(m_display, (::Window)g_platformData.nwh, m_context); m_current = NULL; glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress( (const GLubyte*)"glXSwapIntervalEXT"); if (NULL != glXSwapIntervalEXT) { BX_TRACE("Using glXSwapIntervalEXT."); - glXSwapIntervalEXT( (::Display*)g_platformData.ndt, (::Window)g_platformData.nwh, 0); + glXSwapIntervalEXT(m_display, (::Window)g_platformData.nwh, 0); } else { @@ -215,21 +227,27 @@ namespace bgfx { namespace gl glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); - glXSwapBuffers( (::Display*)g_platformData.ndt, (::Window)g_platformData.nwh); + glXSwapBuffers(m_display, (::Window)g_platformData.nwh); g_internalData.context = m_context; } void GlContext::destroy() { - glXMakeCurrent( (::Display*)g_platformData.ndt, 0, 0); + glXMakeCurrent(m_display, 0, 0); if (NULL == g_platformData.context) { - glXDestroyContext( (::Display*)g_platformData.ndt, m_context); + glXDestroyContext(m_display, m_context); XFree(m_visualInfo); } + // If we opened the display, have to close it + if (NULL == g_platformData.ndt) + { + XCloseDisplay(m_display); + } m_context = NULL; m_visualInfo = NULL; + m_display = NULL; } void GlContext::resize(uint32_t /*_width*/, uint32_t /*_height*/, uint32_t _flags) @@ -239,7 +257,7 @@ namespace bgfx { namespace gl if (NULL != glXSwapIntervalEXT) { - glXSwapIntervalEXT( (::Display*)g_platformData.ndt, (::Window)g_platformData.nwh, interval); + glXSwapIntervalEXT(m_display, (::Window)g_platformData.nwh, interval); } else if (NULL != glXSwapIntervalMESA) { @@ -258,13 +276,13 @@ namespace bgfx { namespace gl SwapChainGL* GlContext::createSwapChain(void* _nwh) { - return BX_NEW(g_allocator, SwapChainGL)( (::Window)_nwh, m_visualInfo, m_context); + return BX_NEW(g_allocator, SwapChainGL)(m_display, (::Window)_nwh, m_visualInfo, m_context); } void GlContext::destroySwapChain(SwapChainGL* _swapChain) { BX_DELETE(g_allocator, _swapChain); - glXMakeCurrent( (::Display*)g_platformData.ndt, (::Window)g_platformData.nwh, m_context); + glXMakeCurrent(m_display, (::Window)g_platformData.nwh, m_context); } void GlContext::swap(SwapChainGL* _swapChain) @@ -273,7 +291,7 @@ namespace bgfx { namespace gl if (NULL == _swapChain) { - glXSwapBuffers( (::Display*)g_platformData.ndt, (::Window)g_platformData.nwh); + glXSwapBuffers(m_display, (::Window)g_platformData.nwh); } else { @@ -289,7 +307,7 @@ namespace bgfx { namespace gl if (NULL == _swapChain) { - glXMakeCurrent( (::Display*)g_platformData.ndt, (::Window)g_platformData.nwh, m_context); + glXMakeCurrent(m_display, (::Window)g_platformData.nwh, m_context); } else { diff --git a/src/glcontext_glx.h b/src/glcontext_glx.h index 766e15688..622f6ab98 100644 --- a/src/glcontext_glx.h +++ b/src/glcontext_glx.h @@ -21,6 +21,7 @@ namespace bgfx { namespace gl : m_current(NULL) , m_context(0) , m_visualInfo(NULL) + , m_display(NULL) { } @@ -44,6 +45,7 @@ namespace bgfx { namespace gl SwapChainGL* m_current; GLXContext m_context; XVisualInfo* m_visualInfo; + ::Display* m_display; }; } /* namespace gl */ } // namespace bgfx