GLX user context implementation

This commit is contained in:
Doug Binks 2020-07-12 20:28:10 +01:00
parent 0ae4eb4d26
commit 998036654c
2 changed files with 96 additions and 21 deletions

View File

@ -440,26 +440,19 @@ void _glfwTerminateGLX(void)
attribs[index++] = v; \ attribs[index++] = v; \
} }
// Create the OpenGL or OpenGL ES context
// Create the OpenGL or OpenGL ES context for the window fbConfig
// //
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, GLFWbool _glfwCreateContextForFBGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig, const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig) GLXContext* context)
{ {
int attribs[40]; int attribs[40];
GLXFBConfig native = NULL;
GLXContext share = NULL; GLXContext share = NULL;
if (ctxconfig->share) if (ctxconfig->share)
share = ctxconfig->share->context.glx.handle; share = ctxconfig->share->context.glx.handle;
if (!chooseGLXFBConfig(fbconfig, &native))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_ES_API) if (ctxconfig->client == GLFW_OPENGL_ES_API)
{ {
if (!_glfw.glx.ARB_create_context || if (!_glfw.glx.ARB_create_context ||
@ -574,9 +567,9 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
setAttrib(None, None); setAttrib(None, None);
window->context.glx.handle = *context =
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display, _glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
native, window->context.glx.fbconfig,
share, share,
True, True,
attribs); attribs);
@ -585,34 +578,56 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
// implementation of GLX_ARB_create_context_profile that fail // implementation of GLX_ARB_create_context_profile that fail
// default 1.0 context creation with a GLXBadProfileARB error in // default 1.0 context creation with a GLXBadProfileARB error in
// violation of the extension spec // violation of the extension spec
if (!window->context.glx.handle) if (!(*context))
{ {
if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB && if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
ctxconfig->client == GLFW_OPENGL_API && ctxconfig->client == GLFW_OPENGL_API &&
ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE && ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
ctxconfig->forward == GLFW_FALSE) ctxconfig->forward == GLFW_FALSE)
{ {
window->context.glx.handle = *context =
createLegacyContextGLX(window, native, share); createLegacyContextGLX(window, window->context.glx.fbconfig, share);
} }
} }
} }
else else
{ {
window->context.glx.handle = *context =
createLegacyContextGLX(window, native, share); createLegacyContextGLX(window, window->context.glx.fbconfig, share);
} }
_glfwReleaseErrorHandlerX11(); _glfwReleaseErrorHandlerX11();
if (!window->context.glx.handle) if (!(*context))
{ {
_glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context"); _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
return GLFW_FALSE; return GLFW_FALSE;
} }
return GLFW_TRUE;
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
if (!chooseGLXFBConfig(fbconfig, &window->context.glx.fbconfig))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
return GLFW_FALSE;
}
if(!_glfwCreateContextForFBGLX(window,ctxconfig,&window->context.glx.handle))
{
return GLFW_FALSE;
}
window->context.glx.window = window->context.glx.window =
glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL); glXCreateWindow(_glfw.x11.display, window->context.glx.fbconfig, window->x11.handle, NULL);
if (!window->context.glx.window) if (!window->context.glx.window)
{ {
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window"); _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
@ -663,6 +678,57 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
return GLFW_TRUE; return GLFW_TRUE;
} }
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
_GLFWusercontext* _glfwPlatformCreateUserContext(_GLFWwindow* window)
{
_GLFWusercontext* context;
_GLFWctxconfig ctxconfig;
context = calloc(1, sizeof(_GLFWusercontext));
context->window = window;
ctxconfig = _glfw.hints.context;
ctxconfig.share = window;
if(!_glfwCreateContextForFBGLX(window,&ctxconfig,&context->handle))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to create user OpenGL context");
free(context);
return NULL;
}
return context;
}
void _glfwPlatformDestroyUserContext(_GLFWusercontext* context)
{
glXDestroyContext(_glfw.x11.display, context->handle);
free(context);
}
void _glfwPlatformMakeUserContextCurrent(_GLFWusercontext* context)
{
if(context)
{
if(!glXMakeCurrent(_glfw.x11.display, context->window->context.glx.window,context->handle))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to set current user context");
}
}
else
{
if (!glXMakeCurrent(_glfw.x11.display, None, NULL))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to clear current context");
}
}
}
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW native API ////// ////// GLFW native API //////

View File

@ -115,6 +115,7 @@ typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLX
// //
typedef struct _GLFWcontextGLX typedef struct _GLFWcontextGLX
{ {
GLXFBConfig fbconfig;
GLXContext handle; GLXContext handle;
GLXWindow window; GLXWindow window;
@ -168,6 +169,14 @@ typedef struct _GLFWlibraryGLX
} _GLFWlibraryGLX; } _GLFWlibraryGLX;
// GLX-specific user context data
//
typedef struct _GLFWusercontext
{
_GLFWwindow* window;
GLXContext handle;
} _GLFWusercontext;
GLFWbool _glfwInitGLX(void); GLFWbool _glfwInitGLX(void);
void _glfwTerminateGLX(void); void _glfwTerminateGLX(void);
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,