From 5e94092263caec509951698f4ffb8effa4bada4c Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Mon, 13 Jul 2020 18:06:48 +0100 Subject: [PATCH] Refactor user context implementation to use the standard GLFW platform / context approach --- src/context.c | 8 +++--- src/egl_context.c | 7 +++++ src/egl_context.h | 10 +++++++ src/glx_context.c | 68 ++++++++++++++++++++++---------------------- src/glx_context.h | 16 ++++++----- src/internal.h | 22 ++++++++++++-- src/osmesa_context.c | 5 ++++ src/osmesa_context.h | 9 +++++- src/wgl_context.c | 68 +++++++++++++++++++++----------------------- src/wgl_context.h | 9 ++++-- src/win32_window.c | 17 +++++++++++ src/x11_window.c | 18 ++++++++++++ 12 files changed, 171 insertions(+), 86 deletions(-) diff --git a/src/context.c b/src/context.c index c6a808cb..2ec29c25 100644 --- a/src/context.c +++ b/src/context.c @@ -771,13 +771,13 @@ GLFWAPI GLFWusercontext* glfwCreateUserContext(GLFWwindow* handle) GLFWAPI void glfwDestroyUserContext(GLFWusercontext* handle) { _GLFWusercontext* context = (_GLFWusercontext*)handle; - - _glfwPlatformDestroyUserContext(context); + if (context) + context->destroy(context); } GLFWAPI void glfwMakeUserContextCurrent(GLFWusercontext* handle) { _GLFWusercontext* context = (_GLFWusercontext*)handle; - - _glfwPlatformMakeUserContextCurrent(context); + if (context) + context->makeCurrent(context); } diff --git a/src/egl_context.c b/src/egl_context.c index 533ed8e7..b059c4d9 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -802,6 +802,13 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, } #endif // _GLFW_X11 +_GLFWusercontext* _glfwCreateUserContextEGL(_GLFWwindow* window) +{ + // TODO + return NULL; +} + + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/egl_context.h b/src/egl_context.h index 9de424c9..1dcab099 100644 --- a/src/egl_context.h +++ b/src/egl_context.h @@ -164,6 +164,14 @@ typedef struct _GLFWcontextEGL } _GLFWcontextEGL; +// EGL-specific per user context data +// +typedef struct _GLFWusercontextEGL +{ + EGLContext handle; +} _GLFWusercontextEGL; + + // EGL-specific global data // typedef struct _GLFWlibraryEGL @@ -218,6 +226,8 @@ void _glfwTerminateEGL(void); GLFWbool _glfwCreateContextEGL(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); +_GLFWusercontext* _glfwCreateUserContextEGL(_GLFWwindow* window); + #if defined(_GLFW_X11) GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, diff --git a/src/glx_context.c b/src/glx_context.c index 043c42ba..e58584ee 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -678,43 +678,11 @@ 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) +static void _glfwMakeUserContextCurrentGLX(_GLFWusercontext* context) { if(context) { - if(!glXMakeCurrent(_glfw.x11.display, context->window->context.glx.window,context->handle)) + if(!glXMakeCurrent(_glfw.x11.display, context->window->context.glx.window,context->glx.handle)) { _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to set current user context"); @@ -730,6 +698,38 @@ void _glfwPlatformMakeUserContextCurrent(_GLFWusercontext* context) } } +static void _glfwDestroyUserContextGLX(_GLFWusercontext* context) +{ + glXDestroyContext(_glfw.x11.display, context->glx.handle); + free(context); +} + +_GLFWusercontext* _glfwCreateUserContextGLX(_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->glx.handle)) + { + _glfwInputError(GLFW_PLATFORM_ERROR, + "GLX: Failed to create user OpenGL context"); + free(context); + return NULL; + } + + context->makeCurrent = _glfwMakeUserContextCurrentGLX; + context->destroy = _glfwDestroyUserContextGLX; + + + return context; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// ////////////////////////////////////////////////////////////////////////// diff --git a/src/glx_context.h b/src/glx_context.h index 6826922a..4046d887 100644 --- a/src/glx_context.h +++ b/src/glx_context.h @@ -109,6 +109,7 @@ typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display*,GLXFBConfig,GLX #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX glx #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryGLX glx +#define _GLFW_PLATFORM_USER_CONTEXT_STATE _GLFWusercontextGLX glx // GLX-specific per-context data @@ -121,6 +122,13 @@ typedef struct _GLFWcontextGLX } _GLFWcontextGLX; +// GLX-specific per user context data +// +typedef struct _GLFWusercontextGLX +{ + GLXContext handle; +} _GLFWusercontextGLX; + // GLX-specific global data // typedef struct _GLFWlibraryGLX @@ -169,13 +177,6 @@ typedef struct _GLFWlibraryGLX } _GLFWlibraryGLX; -// GLX-specific user context data -// -typedef struct _GLFWusercontext -{ - _GLFWwindow* window; - GLXContext handle; -} _GLFWusercontext; GLFWbool _glfwInitGLX(void); void _glfwTerminateGLX(void); @@ -187,4 +188,5 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig, Visual** visual, int* depth); +_GLFWusercontext* _glfwCreateUserContextGLX(_GLFWwindow* window); diff --git a/src/internal.h b/src/internal.h index 04cc4935..bf99478e 100644 --- a/src/internal.h +++ b/src/internal.h @@ -83,6 +83,8 @@ typedef void (* _GLFWswapintervalfun)(int); typedef int (* _GLFWextensionsupportedfun)(const char*); typedef GLFWglproc (* _GLFWgetprocaddressfun)(const char*); typedef void (* _GLFWdestroycontextfun)(_GLFWwindow*); +typedef void (* _GLFWmakeusercontextcurrentfun)(_GLFWusercontext* context); +typedef void (* _GLFWdestroyusercontextfun)(_GLFWusercontext* context); #define GL_VERSION 0x1f02 #define GL_NONE 0 @@ -369,6 +371,24 @@ struct _GLFWcontext _GLFWcontextOSMesa osmesa; }; + +// User Context structure +// +struct _GLFWusercontext +{ + _GLFWwindow* window; + + // This is defined in the context API's context.h + _GLFW_PLATFORM_USER_CONTEXT_STATE; + // This is defined in egl_context.h + _GLFWusercontextEGL egl; + // This is defined in osmesa_context.h + _GLFWusercontextOSMesa osmesa; + + _GLFWmakeusercontextcurrentfun makeCurrent; + _GLFWdestroyusercontextfun destroy; +}; + // Window and context structure // struct _GLFWwindow @@ -687,8 +707,6 @@ void _glfwPlatformWaitEventsTimeout(double timeout); void _glfwPlatformPostEmptyEvent(void); _GLFWusercontext* _glfwPlatformCreateUserContext(_GLFWwindow* window); -void _glfwPlatformDestroyUserContext(_GLFWusercontext* context); -void _glfwPlatformMakeUserContextCurrent(_GLFWusercontext* context); EGLenum _glfwPlatformGetEGLPlatform(EGLint** attribs); EGLNativeDisplayType _glfwPlatformGetEGLNativeDisplay(void); diff --git a/src/osmesa_context.c b/src/osmesa_context.c index 70e8675b..07baabed 100644 --- a/src/osmesa_context.c +++ b/src/osmesa_context.c @@ -287,6 +287,11 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, #undef setAttrib +_GLFWusercontext* _glfwCreateUserContextOSMesa(_GLFWwindow* window) +{ + // TODO + return NULL; +} ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/osmesa_context.h b/src/osmesa_context.h index ce1f1a29..7a20c1f8 100644 --- a/src/osmesa_context.h +++ b/src/osmesa_context.h @@ -65,6 +65,13 @@ typedef struct _GLFWcontextOSMesa } _GLFWcontextOSMesa; +// OSMesa-specific per user context data +// +typedef struct _GLFWusercontextOSMesa +{ + OSMesaContext handle; +} _GLFWusercontextOSMesa; + // OSMesa-specific global data // typedef struct _GLFWlibraryOSMesa @@ -87,4 +94,4 @@ void _glfwTerminateOSMesa(void); GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); - +_GLFWusercontext* _glfwCreateUserContextOSMesa(_GLFWwindow* window); diff --git a/src/wgl_context.c b/src/wgl_context.c index 5a57aed7..d6d668ad 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -790,44 +790,11 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, #undef setAttrib - -////////////////////////////////////////////////////////////////////////// -////// 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 (!_glfwCreateContextForDCWGL(window->context.wgl.dc, &ctxconfig, &context->handle)) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "WGL: Failed to create user OpenGL context"); - free(context); - return NULL; - } - - return context; -} - -void _glfwPlatformDestroyUserContext(_GLFWusercontext* context) -{ - wglDeleteContext(context->handle); - free(context); -} - -void _glfwPlatformMakeUserContextCurrent(_GLFWusercontext* context) +static void _glfwMakeUserContextCurrentWGL(_GLFWusercontext* context) { if(context) { - if(!wglMakeCurrent(context->window->context.wgl.dc,context->handle)) + if(!wglMakeCurrent(context->window->context.wgl.dc,context->wgl.handle)) { _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, "WGL: Failed to set current user context"); @@ -843,6 +810,37 @@ void _glfwPlatformMakeUserContextCurrent(_GLFWusercontext* context) } } +static void _glfwDestroyUserContextWGL(_GLFWusercontext* context) +{ + wglDeleteContext(context->wgl.handle); + free(context); +} + +_GLFWusercontext* _glfwCreateUserContextWGL(_GLFWwindow* window) +{ + _GLFWusercontext* context; + _GLFWctxconfig ctxconfig; + + context = calloc(1, sizeof(_GLFWusercontext)); + context->window = window; + + ctxconfig = _glfw.hints.context; + ctxconfig.share = window; + + if (!_glfwCreateContextForDCWGL(window->context.wgl.dc, &ctxconfig, &context->wgl.handle)) + { + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "WGL: Failed to create user OpenGL context"); + free(context); + return NULL; + } + + context->makeCurrent = _glfwMakeUserContextCurrentWGL; + context->destroy = _glfwDestroyUserContextWGL; + + return context; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/wgl_context.h b/src/wgl_context.h index abf97559..d04cd661 100644 --- a/src/wgl_context.h +++ b/src/wgl_context.h @@ -106,6 +106,7 @@ typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC); #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl #define _GLFW_PLATFORM_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl +#define _GLFW_PLATFORM_USER_CONTEXT_STATE _GLFWusercontextWGL wgl // WGL-specific per-context data @@ -153,15 +154,17 @@ typedef struct _GLFWlibraryWGL // WGL-specific user context data // -typedef struct _GLFWusercontext +typedef struct _GLFWusercontextWGL { - _GLFWwindow* window; HGLRC handle; -} _GLFWusercontext; +} _GLFWusercontextWGL; GLFWbool _glfwInitWGL(void); void _glfwTerminateWGL(void); GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig); +_GLFWusercontext* _glfwCreateUserContextWGL(_GLFWwindow* window); + + diff --git a/src/win32_window.c b/src/win32_window.c index 9dc52bab..fe75b765 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -2321,6 +2321,23 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, return err; } +_GLFWusercontext* _glfwPlatformCreateUserContext(_GLFWwindow* window) +{ + if (window->context.wgl.handle) + { + return _glfwCreateUserContextWGL(window); + } + else if (window->context.egl.handle) + { + return _glfwCreateUserContextEGL(window); + } + else if (window->context.osmesa.handle) + { + return _glfwCreateUserContextOSMesa(window); + } + + return GLFW_FALSE; +} ////////////////////////////////////////////////////////////////////////// ////// GLFW native API ////// diff --git a/src/x11_window.c b/src/x11_window.c index f88a45c4..8704126e 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -3219,6 +3219,24 @@ VkResult _glfwPlatformCreateWindowSurface(VkInstance instance, } } +_GLFWusercontext* _glfwPlatformCreateUserContext(_GLFWwindow* window) +{ + if (window->context.glx.handle) + { + return _glfwCreateUserContextGLX(window); + } + else if (window->context.egl.handle) + { + return _glfwCreateUserContextEGL(window); + } + else if (window->context.osmesa.handle) + { + return _glfwCreateUserContextOSMesa(window); + } + + return GLFW_FALSE; +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW native API //////