From 998036654c23a5b1388be66463d271a5ec5b25b8 Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Sun, 12 Jul 2020 20:28:10 +0100 Subject: [PATCH] GLX user context implementation --- src/glx_context.c | 108 +++++++++++++++++++++++++++++++++++++--------- src/glx_context.h | 9 ++++ 2 files changed, 96 insertions(+), 21 deletions(-) diff --git a/src/glx_context.c b/src/glx_context.c index 7ccd1374..043c42ba 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -440,26 +440,19 @@ void _glfwTerminateGLX(void) 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, - const _GLFWctxconfig* ctxconfig, - const _GLFWfbconfig* fbconfig) +GLFWbool _glfwCreateContextForFBGLX(_GLFWwindow* window, + const _GLFWctxconfig* ctxconfig, + GLXContext* context) { int attribs[40]; - GLXFBConfig native = NULL; GLXContext share = NULL; if (ctxconfig->share) 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 (!_glfw.glx.ARB_create_context || @@ -574,9 +567,9 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, setAttrib(None, None); - window->context.glx.handle = + *context = _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, - native, + window->context.glx.fbconfig, share, True, attribs); @@ -585,34 +578,56 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, // implementation of GLX_ARB_create_context_profile that fail // default 1.0 context creation with a GLXBadProfileARB error in // violation of the extension spec - if (!window->context.glx.handle) + if (!(*context)) { if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB && ctxconfig->client == GLFW_OPENGL_API && ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE && ctxconfig->forward == GLFW_FALSE) { - window->context.glx.handle = - createLegacyContextGLX(window, native, share); + *context = + createLegacyContextGLX(window, window->context.glx.fbconfig, share); } } } else { - window->context.glx.handle = - createLegacyContextGLX(window, native, share); + *context = + createLegacyContextGLX(window, window->context.glx.fbconfig, share); } _glfwReleaseErrorHandlerX11(); - if (!window->context.glx.handle) + if (!(*context)) { _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context"); 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 = - 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) { _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window"); @@ -663,6 +678,57 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, 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 ////// diff --git a/src/glx_context.h b/src/glx_context.h index 94f07e2e..6826922a 100644 --- a/src/glx_context.h +++ b/src/glx_context.h @@ -115,6 +115,7 @@ typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLX // typedef struct _GLFWcontextGLX { + GLXFBConfig fbconfig; GLXContext handle; GLXWindow window; @@ -168,6 +169,14 @@ typedef struct _GLFWlibraryGLX } _GLFWlibraryGLX; +// GLX-specific user context data +// +typedef struct _GLFWusercontext +{ + _GLFWwindow* window; + GLXContext handle; +} _GLFWusercontext; + GLFWbool _glfwInitGLX(void); void _glfwTerminateGLX(void); GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,