|
|
|
@ -38,16 +38,16 @@ |
|
|
|
|
|
|
|
|
|
// Returns the specified attribute of the specified GLXFBConfig
|
|
|
|
|
//
|
|
|
|
|
static int getFBConfigAttrib(GLXFBConfig fbconfig, int attrib) |
|
|
|
|
static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib) |
|
|
|
|
{ |
|
|
|
|
int value; |
|
|
|
|
glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value); |
|
|
|
|
return value; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Return a list of available and usable framebuffer configs
|
|
|
|
|
// Return the GLXFBConfig most closely matching the specified hints
|
|
|
|
|
//
|
|
|
|
|
static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result) |
|
|
|
|
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result) |
|
|
|
|
{ |
|
|
|
|
GLXFBConfig* nativeConfigs; |
|
|
|
|
_GLFWfbconfig* usableConfigs; |
|
|
|
@ -79,41 +79,41 @@ static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result |
|
|
|
|
_GLFWfbconfig* u = usableConfigs + usableCount; |
|
|
|
|
|
|
|
|
|
// Only consider RGBA GLXFBConfigs
|
|
|
|
|
if (!(getFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT)) |
|
|
|
|
if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
// Only consider window GLXFBConfigs
|
|
|
|
|
if (!(getFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) |
|
|
|
|
if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT)) |
|
|
|
|
{ |
|
|
|
|
if (trustWindowBit) |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
u->redBits = getFBConfigAttrib(n, GLX_RED_SIZE); |
|
|
|
|
u->greenBits = getFBConfigAttrib(n, GLX_GREEN_SIZE); |
|
|
|
|
u->blueBits = getFBConfigAttrib(n, GLX_BLUE_SIZE); |
|
|
|
|
u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE); |
|
|
|
|
u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE); |
|
|
|
|
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE); |
|
|
|
|
|
|
|
|
|
u->alphaBits = getFBConfigAttrib(n, GLX_ALPHA_SIZE); |
|
|
|
|
u->depthBits = getFBConfigAttrib(n, GLX_DEPTH_SIZE); |
|
|
|
|
u->stencilBits = getFBConfigAttrib(n, GLX_STENCIL_SIZE); |
|
|
|
|
u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE); |
|
|
|
|
u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE); |
|
|
|
|
u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE); |
|
|
|
|
|
|
|
|
|
u->accumRedBits = getFBConfigAttrib(n, GLX_ACCUM_RED_SIZE); |
|
|
|
|
u->accumGreenBits = getFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE); |
|
|
|
|
u->accumBlueBits = getFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE); |
|
|
|
|
u->accumAlphaBits = getFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE); |
|
|
|
|
u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE); |
|
|
|
|
u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE); |
|
|
|
|
u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE); |
|
|
|
|
u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE); |
|
|
|
|
|
|
|
|
|
u->auxBuffers = getFBConfigAttrib(n, GLX_AUX_BUFFERS); |
|
|
|
|
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS); |
|
|
|
|
|
|
|
|
|
if (getFBConfigAttrib(n, GLX_STEREO)) |
|
|
|
|
if (getGLXFBConfigAttrib(n, GLX_STEREO)) |
|
|
|
|
u->stereo = GLFW_TRUE; |
|
|
|
|
if (getFBConfigAttrib(n, GLX_DOUBLEBUFFER)) |
|
|
|
|
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER)) |
|
|
|
|
u->doublebuffer = GLFW_TRUE; |
|
|
|
|
|
|
|
|
|
if (_glfw.glx.ARB_multisample) |
|
|
|
|
u->samples = getFBConfigAttrib(n, GLX_SAMPLES); |
|
|
|
|
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES); |
|
|
|
|
|
|
|
|
|
if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB) |
|
|
|
|
u->sRGB = getFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); |
|
|
|
|
u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB); |
|
|
|
|
|
|
|
|
|
u->handle = (uintptr_t) n; |
|
|
|
|
usableCount++; |
|
|
|
@ -131,9 +131,9 @@ static GLFWbool chooseFBConfig(const _GLFWfbconfig* desired, GLXFBConfig* result |
|
|
|
|
|
|
|
|
|
// Create the OpenGL context using legacy API
|
|
|
|
|
//
|
|
|
|
|
static GLXContext createLegacyContext(_GLFWwindow* window, |
|
|
|
|
GLXFBConfig fbconfig, |
|
|
|
|
GLXContext share) |
|
|
|
|
static GLXContext createLegacyContextGLX(_GLFWwindow* window, |
|
|
|
|
GLXFBConfig fbconfig, |
|
|
|
|
GLXContext share) |
|
|
|
|
{ |
|
|
|
|
return glXCreateNewContext(_glfw.x11.display, |
|
|
|
|
fbconfig, |
|
|
|
@ -142,7 +142,7 @@ static GLXContext createLegacyContext(_GLFWwindow* window, |
|
|
|
|
True); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void makeContextCurrent(_GLFWwindow* window) |
|
|
|
|
static void makeContextCurrentGLX(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
if (window) |
|
|
|
|
{ |
|
|
|
@ -168,12 +168,12 @@ static void makeContextCurrent(_GLFWwindow* window) |
|
|
|
|
_glfwPlatformSetCurrentContext(window); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void swapBuffers(_GLFWwindow* window) |
|
|
|
|
static void swapBuffersGLX(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
glXSwapBuffers(_glfw.x11.display, window->context.glx.window); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void swapInterval(int interval) |
|
|
|
|
static void swapIntervalGLX(int interval) |
|
|
|
|
{ |
|
|
|
|
_GLFWwindow* window = _glfwPlatformGetCurrentContext(); |
|
|
|
|
|
|
|
|
@ -192,7 +192,7 @@ static void swapInterval(int interval) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int extensionSupported(const char* extension) |
|
|
|
|
static int extensionSupportedGLX(const char* extension) |
|
|
|
|
{ |
|
|
|
|
const char* extensions = |
|
|
|
|
glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen); |
|
|
|
@ -205,7 +205,7 @@ static int extensionSupported(const char* extension) |
|
|
|
|
return GLFW_FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static GLFWglproc getProcAddress(const char* procname) |
|
|
|
|
static GLFWglproc getProcAddressGLX(const char* procname) |
|
|
|
|
{ |
|
|
|
|
if (_glfw.glx.GetProcAddress) |
|
|
|
|
return _glfw.glx.GetProcAddress((const GLubyte*) procname); |
|
|
|
@ -217,7 +217,7 @@ static GLFWglproc getProcAddress(const char* procname) |
|
|
|
|
|
|
|
|
|
// Destroy the OpenGL context
|
|
|
|
|
//
|
|
|
|
|
static void destroyContext(_GLFWwindow* window) |
|
|
|
|
static void destroyContextGLX(_GLFWwindow* window) |
|
|
|
|
{ |
|
|
|
|
if (window->context.glx.window) |
|
|
|
|
{ |
|
|
|
@ -319,61 +319,61 @@ GLFWbool _glfwInitGLX(void) |
|
|
|
|
return GLFW_FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_EXT_swap_control")) |
|
|
|
|
if (extensionSupportedGLX("GLX_EXT_swap_control")) |
|
|
|
|
{ |
|
|
|
|
_glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) |
|
|
|
|
getProcAddress("glXSwapIntervalEXT"); |
|
|
|
|
getProcAddressGLX("glXSwapIntervalEXT"); |
|
|
|
|
|
|
|
|
|
if (_glfw.glx.SwapIntervalEXT) |
|
|
|
|
_glfw.glx.EXT_swap_control = GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_SGI_swap_control")) |
|
|
|
|
if (extensionSupportedGLX("GLX_SGI_swap_control")) |
|
|
|
|
{ |
|
|
|
|
_glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) |
|
|
|
|
getProcAddress("glXSwapIntervalSGI"); |
|
|
|
|
getProcAddressGLX("glXSwapIntervalSGI"); |
|
|
|
|
|
|
|
|
|
if (_glfw.glx.SwapIntervalSGI) |
|
|
|
|
_glfw.glx.SGI_swap_control = GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_MESA_swap_control")) |
|
|
|
|
if (extensionSupportedGLX("GLX_MESA_swap_control")) |
|
|
|
|
{ |
|
|
|
|
_glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) |
|
|
|
|
getProcAddress("glXSwapIntervalMESA"); |
|
|
|
|
getProcAddressGLX("glXSwapIntervalMESA"); |
|
|
|
|
|
|
|
|
|
if (_glfw.glx.SwapIntervalMESA) |
|
|
|
|
_glfw.glx.MESA_swap_control = GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_ARB_multisample")) |
|
|
|
|
if (extensionSupportedGLX("GLX_ARB_multisample")) |
|
|
|
|
_glfw.glx.ARB_multisample = GLFW_TRUE; |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_ARB_framebuffer_sRGB")) |
|
|
|
|
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB")) |
|
|
|
|
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE; |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_EXT_framebuffer_sRGB")) |
|
|
|
|
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB")) |
|
|
|
|
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE; |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_ARB_create_context")) |
|
|
|
|
if (extensionSupportedGLX("GLX_ARB_create_context")) |
|
|
|
|
{ |
|
|
|
|
_glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) |
|
|
|
|
getProcAddress("glXCreateContextAttribsARB"); |
|
|
|
|
getProcAddressGLX("glXCreateContextAttribsARB"); |
|
|
|
|
|
|
|
|
|
if (_glfw.glx.CreateContextAttribsARB) |
|
|
|
|
_glfw.glx.ARB_create_context = GLFW_TRUE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_ARB_create_context_robustness")) |
|
|
|
|
if (extensionSupportedGLX("GLX_ARB_create_context_robustness")) |
|
|
|
|
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE; |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_ARB_create_context_profile")) |
|
|
|
|
if (extensionSupportedGLX("GLX_ARB_create_context_profile")) |
|
|
|
|
_glfw.glx.ARB_create_context_profile = GLFW_TRUE; |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_EXT_create_context_es2_profile")) |
|
|
|
|
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile")) |
|
|
|
|
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE; |
|
|
|
|
|
|
|
|
|
if (extensionSupported("GLX_ARB_context_flush_control")) |
|
|
|
|
if (extensionSupportedGLX("GLX_ARB_context_flush_control")) |
|
|
|
|
_glfw.glx.ARB_context_flush_control = GLFW_TRUE; |
|
|
|
|
|
|
|
|
|
return GLFW_TRUE; |
|
|
|
@ -413,7 +413,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, |
|
|
|
|
if (ctxconfig->share) |
|
|
|
|
share = ctxconfig->share->context.glx.handle; |
|
|
|
|
|
|
|
|
|
if (!chooseFBConfig(fbconfig, &native)) |
|
|
|
|
if (!chooseGLXFBConfig(fbconfig, &native)) |
|
|
|
|
{ |
|
|
|
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, |
|
|
|
|
"GLX: Failed to find a suitable GLXFBConfig"); |
|
|
|
@ -549,12 +549,15 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, |
|
|
|
|
ctxconfig->forward == GLFW_FALSE) |
|
|
|
|
{ |
|
|
|
|
window->context.glx.handle = |
|
|
|
|
createLegacyContext(window, native, share); |
|
|
|
|
createLegacyContextGLX(window, native, share); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
window->context.glx.handle = createLegacyContext(window, native, share); |
|
|
|
|
{ |
|
|
|
|
window->context.glx.handle = |
|
|
|
|
createLegacyContextGLX(window, native, share); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_glfwReleaseErrorHandlerX11(); |
|
|
|
|
|
|
|
|
@ -572,12 +575,12 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, |
|
|
|
|
return GLFW_FALSE; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
window->context.makeCurrent = makeContextCurrent; |
|
|
|
|
window->context.swapBuffers = swapBuffers; |
|
|
|
|
window->context.swapInterval = swapInterval; |
|
|
|
|
window->context.extensionSupported = extensionSupported; |
|
|
|
|
window->context.getProcAddress = getProcAddress; |
|
|
|
|
window->context.destroy = destroyContext; |
|
|
|
|
window->context.makeCurrent = makeContextCurrentGLX; |
|
|
|
|
window->context.swapBuffers = swapBuffersGLX; |
|
|
|
|
window->context.swapInterval = swapIntervalGLX; |
|
|
|
|
window->context.extensionSupported = extensionSupportedGLX; |
|
|
|
|
window->context.getProcAddress = getProcAddressGLX; |
|
|
|
|
window->context.destroy = destroyContextGLX; |
|
|
|
|
|
|
|
|
|
return GLFW_TRUE; |
|
|
|
|
} |
|
|
|
@ -593,7 +596,7 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig, |
|
|
|
|
GLXFBConfig native; |
|
|
|
|
XVisualInfo* result; |
|
|
|
|
|
|
|
|
|
if (!chooseFBConfig(fbconfig, &native)) |
|
|
|
|
if (!chooseGLXFBConfig(fbconfig, &native)) |
|
|
|
|
{ |
|
|
|
|
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, |
|
|
|
|
"GLX: Failed to find a suitable GLXFBConfig"); |
|
|
|
|