2013-01-13 18:39:25 -08:00
/*
2014-02-10 22:07:04 -08:00
* Copyright 2011 - 2014 Branimir Karadzic . All rights reserved .
2013-01-13 18:39:25 -08:00
* License : http : //www.opensource.org/licenses/BSD-2-Clause
*/
# include "bgfx_p.h"
2014-08-24 17:41:41 -07:00
# if (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX) && (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL)
2013-01-13 18:39:25 -08:00
# include "renderer_gl.h"
2013-04-26 23:43:31 -07:00
# define GLX_GLXEXT_PROTOTYPES
# include <glx / glxext.h>
2013-01-13 18:39:25 -08:00
namespace bgfx
{
2013-04-27 22:39:15 -07:00
typedef int ( * PFNGLXSWAPINTERVALMESAPROC ) ( uint32_t _interval ) ;
2013-04-27 15:16:05 -07:00
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB ;
PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT ;
2013-04-27 22:39:15 -07:00
PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA ;
2013-04-27 15:16:05 -07:00
PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI ;
2013-12-07 22:01:32 -08:00
# define GL_IMPORT(_optional, _proto, _func, _import) _proto _func
2014-02-18 23:36:13 -08:00
# include "glimports.h"
2013-01-13 18:39:25 -08:00
static : : Display * s_display ;
static : : Window s_window ;
void x11SetDisplayWindow ( : : Display * _display , : : Window _window )
{
s_display = _display ;
s_window = _window ;
}
void GlContext : : create ( uint32_t _width , uint32_t _height )
{
2013-12-07 10:26:17 -08:00
BX_UNUSED ( _width , _height ) ;
2013-01-13 18:39:25 -08:00
XLockDisplay ( s_display ) ;
int major , minor ;
bool version = glXQueryVersion ( s_display , & major , & minor ) ;
BGFX_FATAL ( version , Fatal : : UnableToInitialize , " Failed to query GLX version " ) ;
2013-07-24 22:22:38 -07:00
BGFX_FATAL ( ( major = = 1 & & minor > = 2 ) | | major > 1
2013-01-13 18:39:25 -08:00
, Fatal : : UnableToInitialize
2013-07-24 22:22:38 -07:00
, " GLX version is not >=1.2 (%d.%d). "
2013-01-13 18:39:25 -08:00
, major
, minor
) ;
2013-04-26 23:43:31 -07:00
int32_t screen = DefaultScreen ( s_display ) ;
const char * extensions = glXQueryExtensionsString ( s_display , screen ) ;
BX_TRACE ( " GLX extensions: " ) ;
dumpExtensions ( extensions ) ;
2013-01-13 18:39:25 -08:00
const int attrsGlx [ ] =
{
GLX_RENDER_TYPE , GLX_RGBA_BIT ,
GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT ,
GLX_DOUBLEBUFFER , true ,
GLX_RED_SIZE , 8 ,
GLX_BLUE_SIZE , 8 ,
GLX_GREEN_SIZE , 8 ,
2013-03-10 23:18:38 -07:00
// GLX_ALPHA_SIZE, 8,
2013-01-13 18:39:25 -08:00
GLX_DEPTH_SIZE , 24 ,
GLX_STENCIL_SIZE , 8 ,
2013-03-10 23:18:38 -07:00
0 ,
2013-01-13 18:39:25 -08:00
} ;
// Find suitable config
GLXFBConfig bestConfig = NULL ;
int numConfigs ;
2013-04-26 23:43:31 -07:00
GLXFBConfig * configs = glXChooseFBConfig ( s_display , screen , attrsGlx , & numConfigs ) ;
2013-01-13 18:39:25 -08:00
BX_TRACE ( " glX num configs %d " , numConfigs ) ;
2013-10-19 15:36:26 -07:00
XVisualInfo * visualInfo = NULL ;
2013-01-13 18:39:25 -08:00
for ( int ii = 0 ; ii < numConfigs ; + + ii )
{
visualInfo = glXGetVisualFromFBConfig ( s_display , configs [ ii ] ) ;
if ( NULL ! = visualInfo )
{
BX_TRACE ( " --- " ) ;
bool valid = true ;
2013-08-06 21:04:28 -07:00
for ( uint32_t attr = 6 ; attr < BX_COUNTOF ( attrsGlx ) - 1 & & attrsGlx [ attr ] ! = None ; attr + = 2 )
2013-01-13 18:39:25 -08:00
{
int value ;
glXGetFBConfigAttrib ( s_display , configs [ ii ] , attrsGlx [ attr ] , & value ) ;
BX_TRACE ( " glX %d/%d %2d: %4x, %8x (%8x%s) "
, ii
, numConfigs
, attr / 2
, attrsGlx [ attr ]
, value
, attrsGlx [ attr + 1 ]
, value < attrsGlx [ attr + 1 ] ? " * " : " "
) ;
if ( value < attrsGlx [ attr + 1 ] )
{
valid = false ;
# if !BGFX_CONFIG_DEBUG
break ;
# endif // BGFX_CONFIG_DEBUG
}
}
if ( valid )
{
bestConfig = configs [ ii ] ;
2013-10-19 15:36:26 -07:00
BX_TRACE ( " Best config %d. " , ii ) ;
2013-01-13 18:39:25 -08:00
break ;
}
}
XFree ( visualInfo ) ;
2013-10-19 15:36:26 -07:00
visualInfo = NULL ;
2013-01-13 18:39:25 -08:00
}
XFree ( configs ) ;
BGFX_FATAL ( visualInfo , Fatal : : UnableToInitialize , " Failed to find a suitable X11 display configuration. " ) ;
BX_TRACE ( " Create GL 2.1 context. " ) ;
m_context = glXCreateContext ( s_display , visualInfo , 0 , GL_TRUE ) ;
BGFX_FATAL ( NULL ! = m_context , Fatal : : UnableToInitialize , " Failed to create GL 2.1 context. " ) ;
XFree ( visualInfo ) ;
2013-03-09 15:56:26 -08:00
# if BGFX_CONFIG_RENDERER_OPENGL >= 31
2013-04-27 15:16:05 -07:00
glXCreateContextAttribsARB = ( PFNGLXCREATECONTEXTATTRIBSARBPROC ) glXGetProcAddress ( ( const GLubyte * ) " glXCreateContextAttribsARB " ) ;
2013-05-16 21:31:59 -07:00
2013-01-13 18:39:25 -08:00
if ( NULL ! = glXCreateContextAttribsARB )
{
2013-03-04 20:24:02 -08:00
BX_TRACE ( " Create GL 3.1 context. " ) ;
2013-01-13 18:39:25 -08:00
const int contextAttrs [ ] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB , 3 ,
2013-03-04 20:24:02 -08:00
GLX_CONTEXT_MINOR_VERSION_ARB , 1 ,
GLX_CONTEXT_PROFILE_MASK_ARB , GLX_CONTEXT_CORE_PROFILE_BIT_ARB ,
0 ,
2013-01-13 18:39:25 -08:00
} ;
GLXContext context = glXCreateContextAttribsARB ( s_display , bestConfig , 0 , true , contextAttrs ) ;
if ( NULL ! = context )
{
glXDestroyContext ( s_display , m_context ) ;
m_context = context ;
}
}
2013-03-09 15:56:26 -08:00
# else
BX_UNUSED ( bestConfig ) ;
# endif // BGFX_CONFIG_RENDERER_OPENGL >= 31
2013-01-13 18:39:25 -08:00
XUnlockDisplay ( s_display ) ;
import ( ) ;
2013-05-16 21:31:59 -07:00
glXMakeCurrent ( s_display , s_window , m_context ) ;
2013-04-27 15:16:05 -07:00
glXSwapIntervalEXT = ( PFNGLXSWAPINTERVALEXTPROC ) glXGetProcAddress ( ( const GLubyte * ) " glXSwapIntervalEXT " ) ;
2013-04-26 23:43:31 -07:00
if ( NULL ! = glXSwapIntervalEXT )
{
BX_TRACE ( " Using glXSwapIntervalEXT. " ) ;
2013-04-27 15:26:23 -07:00
glXSwapIntervalEXT ( s_display , s_window , 0 ) ;
2013-04-26 23:43:31 -07:00
}
else
{
2013-04-27 22:39:15 -07:00
glXSwapIntervalMESA = ( PFNGLXSWAPINTERVALMESAPROC ) glXGetProcAddress ( ( const GLubyte * ) " glXSwapIntervalMESA " ) ;
if ( NULL ! = glXSwapIntervalMESA )
2013-04-26 23:43:31 -07:00
{
2013-04-27 22:39:15 -07:00
BX_TRACE ( " Using glXSwapIntervalMESA. " ) ;
glXSwapIntervalMESA ( 0 ) ;
}
else
{
glXSwapIntervalSGI = ( PFNGLXSWAPINTERVALSGIPROC ) glXGetProcAddress ( ( const GLubyte * ) " glXSwapIntervalSGI " ) ;
if ( NULL ! = glXSwapIntervalSGI )
{
BX_TRACE ( " Using glXSwapIntervalSGI. " ) ;
glXSwapIntervalSGI ( 0 ) ;
}
2013-04-26 23:43:31 -07:00
}
}
2013-01-13 18:39:25 -08:00
glClearColor ( 0.0f , 0.0f , 0.0f , 1.0f ) ;
glClear ( GL_COLOR_BUFFER_BIT ) ;
glXSwapBuffers ( s_display , s_window ) ;
}
void GlContext : : destroy ( )
{
2013-01-17 22:38:13 -08:00
glXMakeCurrent ( s_display , 0 , 0 ) ;
glXDestroyContext ( s_display , m_context ) ;
2013-01-13 18:39:25 -08:00
}
2013-04-27 15:16:05 -07:00
void GlContext : : resize ( uint32_t /*_width*/ , uint32_t /*_height*/ , bool _vsync )
2013-01-13 18:39:25 -08:00
{
2013-04-27 15:16:05 -07:00
int32_t interval = _vsync ? 1 : 0 ;
if ( NULL ! = glXSwapIntervalEXT )
{
2013-04-27 15:26:23 -07:00
glXSwapIntervalEXT ( s_display , s_window , interval ) ;
2013-04-27 15:16:05 -07:00
}
2013-04-27 22:39:15 -07:00
else if ( NULL ! = glXSwapIntervalMESA )
{
glXSwapIntervalMESA ( interval ) ;
}
2013-04-27 15:16:05 -07:00
else if ( NULL ! = glXSwapIntervalSGI )
{
glXSwapIntervalSGI ( interval ) ;
}
2013-01-13 18:39:25 -08:00
}
2014-09-23 20:35:39 -07:00
bool GlContext : : isSwapChainSupported ( )
{
return false ;
}
2014-09-07 17:17:38 -07:00
SwapChainGL * GlContext : : createSwapChain ( void * /*_nwh*/ )
2013-01-13 18:39:25 -08:00
{
2014-09-07 17:17:38 -07:00
BX_CHECK ( false , " Shouldn't be called! " ) ;
return NULL ;
}
void GlContext : : destorySwapChain ( SwapChainGL * /*_swapChain*/ )
{
BX_CHECK ( false , " Shouldn't be called! " ) ;
}
void GlContext : : swap ( SwapChainGL * _swapChain )
{
BX_CHECK ( NULL = = _swapChain , " Shouldn't be called! " ) ; BX_UNUSED ( _swapChain ) ;
2013-01-13 18:39:25 -08:00
glXSwapBuffers ( s_display , s_window ) ;
}
2014-09-07 17:17:38 -07:00
void GlContext : : makeCurrent ( SwapChainGL * /*_swapChain*/ )
{
}
2013-01-13 18:39:25 -08:00
void GlContext : : import ( )
{
2014-02-18 23:36:13 -08:00
# define GL_EXTENSION(_optional, _proto, _func, _import) \
{ \
if ( NULL = = _func ) \
{ \
2014-02-19 20:53:06 -08:00
_func = ( _proto ) glXGetProcAddress ( ( const GLubyte * ) # _import ) ; \
BX_TRACE ( " %p " # _func " ( " # _import " ) " , _func ) ; \
2014-02-18 23:36:13 -08:00
BGFX_FATAL ( _optional | | NULL ! = _func , Fatal : : UnableToInitialize , " Failed to create OpenGL context. glXGetProcAddress %s " , # _import ) ; \
} \
}
2013-01-13 18:39:25 -08:00
# include "glimports.h"
}
} // namespace bgfx
2014-08-24 17:41:41 -07:00
# endif // (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX) && (BGFX_CONFIG_RENDERER_OPENGLES || BGFX_CONFIG_RENDERER_OPENGL)