From fe890e5e26a2cf10393763d0298284cc1255157f Mon Sep 17 00:00:00 2001 From: Lukas Hermanns Date: Thu, 5 Apr 2018 13:08:04 +0200 Subject: [PATCH 1/7] Added option 'GLFW_OPENGL_SINGLE_GLRC' to make GLFW use only a single GLRC. --- CMakeLists.txt | 5 +++++ src/internal.h | 5 +++++ src/wgl_context.c | 27 ++++++++++++++++++++++++--- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f5d6ef6c..4ca8de957 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,6 +30,7 @@ option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) option(GLFW_BUILD_DOCS "Build the GLFW documentation" ON) option(GLFW_INSTALL "Generate installation target" ON) option(GLFW_VULKAN_STATIC "Use the Vulkan loader statically linked into application" OFF) +option(GLFW_OPENGL_SINGLE_GLRC "Build the GLFW to use only a single OpenGL render context" OFF) if (UNIX) option(GLFW_USE_OSMESA "Use OSMesa for offscreen context creation" OFF) @@ -73,6 +74,10 @@ if (GLFW_BUILD_DOCS) find_package(Doxygen) endif() +if (GLFW_OPENGL_SINGLE_GLRC) + add_definitions(-D_GLFW_OPENGL_SINGLE_GLRC) +endif() + #-------------------------------------------------------------------- # Set compiler specific flags #-------------------------------------------------------------------- diff --git a/src/internal.h b/src/internal.h index 92bbfccec..f0777102c 100644 --- a/src/internal.h +++ b/src/internal.h @@ -341,6 +341,11 @@ struct _GLFWcontext int profile; int robustness; int release; +#ifdef _GLFW_OPENGL_SINGLE_GLRC + // Specifies whether this _GLFWcontext has its own GLRC object. + // If not, it must not delete the GLRC object on destruction. + GLFWbool customctx; +#endif PFNGLGETSTRINGIPROC GetStringi; PFNGLGETINTEGERVPROC GetIntegerv; diff --git a/src/wgl_context.c b/src/wgl_context.c index beccb13ed..38748b4f1 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -324,7 +324,14 @@ static void destroyContextWGL(_GLFWwindow* window) { if (window->context.wgl.handle) { +#ifdef _GLFW_OPENGL_SINGLE_GLRC + if (window->context.customctx) + { + wglDeleteContext(window->context.wgl.handle); + } +#else wglDeleteContext(window->context.wgl.handle); +#endif window->context.wgl.handle = NULL; } } @@ -623,9 +630,23 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, setAttrib(0, 0); - window->context.wgl.handle = - _glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc, - share, attribs); +#ifdef _GLFW_OPENGL_SINGLE_GLRC + if (share) + { + // Use shared context instead of creating a new one + window->context.wgl.handle = share; + window->context.customctx = GLFW_FALSE; + } + else + { + // Create new GL render context + window->context.wgl.handle = _glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc, NULL, attribs); + window->context.customctx = GLFW_TRUE; + } +#else + window->context.wgl.handle = _glfw.wgl.CreateContextAttribsARB(window->context.wgl.dc, share, attribs); +#endif + if (!window->context.wgl.handle) { const DWORD error = GetLastError(); From d873ed69fb026f32024b4de88d40456137909653 Mon Sep 17 00:00:00 2001 From: Lukas Hermanns Date: Wed, 25 Apr 2018 11:58:15 +0200 Subject: [PATCH 2/7] implemented single GLRC for legacy WGL context. --- src/wgl_context.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/wgl_context.c b/src/wgl_context.c index 38748b4f1..9f76d1ff6 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -697,7 +697,23 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, } else { +#ifdef _GLFW_OPENGL_SINGLE_GLRC + if (share) + { + // Use shared context instead of creating a new one + window->context.wgl.handle = share; + window->context.customctx = GLFW_FALSE; + } + else + { + // Create new GL render context + window->context.wgl.handle = wglCreateContext(window->context.wgl.dc); + window->context.customctx = GLFW_TRUE; + } +#else window->context.wgl.handle = wglCreateContext(window->context.wgl.dc); +#endif + if (!window->context.wgl.handle) { _glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE, @@ -705,6 +721,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, return GLFW_FALSE; } +#ifndef _GLFW_OPENGL_SINGLE_GLRC if (share) { if (!wglShareLists(share, window->context.wgl.handle)) @@ -714,6 +731,7 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, return GLFW_FALSE; } } +#endif } window->context.makeCurrent = makeContextCurrentWGL; From 68d0c63865e13ae1bbacd6bdc81bf4d14b123e20 Mon Sep 17 00:00:00 2001 From: Lukas Hermanns Date: Wed, 25 Apr 2018 14:20:33 +0200 Subject: [PATCH 3/7] Started with single GLRC for GLXContext. --- src/glx_context.c | 231 ++++++++++++++++++++++++++-------------------- 1 file changed, 129 insertions(+), 102 deletions(-) diff --git a/src/glx_context.c b/src/glx_context.c index adace82d9..88c3af244 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -238,7 +238,14 @@ static void destroyContextGLX(_GLFWwindow* window) if (window->context.glx.handle) { +#ifdef _GLFW_OPENGL_SINGLE_GLRC + if (window->context.customctx) + { + glXDestroyContext(_glfw.x11.display, window->context.glx.handle); + } +#else glXDestroyContext(_glfw.x11.display, window->context.glx.handle); +#endif window->context.glx.handle = NULL; } } @@ -495,112 +502,132 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, _glfwGrabErrorHandlerX11(); - if (_glfw.glx.ARB_create_context) +#ifdef _GLFW_OPENGL_SINGLE_GLRC + if(share) { - int index = 0, mask = 0, flags = 0; - - if (ctxconfig->client == GLFW_OPENGL_API) - { - if (ctxconfig->forward) - flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; - - if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) - mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) - mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; - } - else - mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; - - if (ctxconfig->debug) - flags |= GLX_CONTEXT_DEBUG_BIT_ARB; - - if (ctxconfig->robustness) - { - if (_glfw.glx.ARB_create_context_robustness) - { - if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) - { - setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - GLX_NO_RESET_NOTIFICATION_ARB); - } - else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) - { - setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, - GLX_LOSE_CONTEXT_ON_RESET_ARB); - } - - flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; - } - } - - if (ctxconfig->release) - { - if (_glfw.glx.ARB_context_flush_control) - { - if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) - { - setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, - GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); - } - else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) - { - setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, - GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); - } - } - } - - if (ctxconfig->noerror) - { - if (_glfw.glx.ARB_create_context_no_error) - setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); - } - - // NOTE: Only request an explicitly versioned context when necessary, as - // explicitly requesting version 1.0 does not always return the - // highest version supported by the driver - if (ctxconfig->major != 1 || ctxconfig->minor != 0) - { - setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); - setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); - } - - if (mask) - setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); - - if (flags) - setAttrib(GLX_CONTEXT_FLAGS_ARB, flags); - - setAttrib(None, None); - - window->context.glx.handle = - _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, - native, - share, - True, - attribs); - - // HACK: This is a fallback for broken versions of the Mesa - // 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 (_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); - } - } + // Use shared context instead of creating a new one + window->context.wgl.handle = share; + window->context.customctx = GLFW_FALSE; } else { - window->context.glx.handle = - createLegacyContextGLX(window, native, share); + // Create new GL render context + window->context.glx.handle = NULL; + window->context.customctx = GLFW_TRUE; + } +#endif + +#ifdef _GLFW_OPENGL_SINGLE_GLRC + if (!window->context.glx.handle) +#endif + { + if (_glfw.glx.ARB_create_context) + { + int index = 0, mask = 0, flags = 0; + + if (ctxconfig->client == GLFW_OPENGL_API) + { + if (ctxconfig->forward) + flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB; + + if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE) + mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE) + mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; + } + else + mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT; + + if (ctxconfig->debug) + flags |= GLX_CONTEXT_DEBUG_BIT_ARB; + + if (ctxconfig->robustness) + { + if (_glfw.glx.ARB_create_context_robustness) + { + if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION) + { + setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + GLX_NO_RESET_NOTIFICATION_ARB); + } + else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET) + { + setAttrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + GLX_LOSE_CONTEXT_ON_RESET_ARB); + } + + flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB; + } + } + + if (ctxconfig->release) + { + if (_glfw.glx.ARB_context_flush_control) + { + if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE) + { + setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, + GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB); + } + else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH) + { + setAttrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB, + GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB); + } + } + } + + if (ctxconfig->noerror) + { + if (_glfw.glx.ARB_create_context_no_error) + setAttrib(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE); + } + + // NOTE: Only request an explicitly versioned context when necessary, as + // explicitly requesting version 1.0 does not always return the + // highest version supported by the driver + if (ctxconfig->major != 1 || ctxconfig->minor != 0) + { + setAttrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major); + setAttrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor); + } + + if (mask) + setAttrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask); + + if (flags) + setAttrib(GLX_CONTEXT_FLAGS_ARB, flags); + + setAttrib(None, None); + + window->context.glx.handle = + _glfw.glx.CreateContextAttribsARB(_glfw.x11.display, + native, + share, + True, + attribs); + + // HACK: This is a fallback for broken versions of the Mesa + // 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 (_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); + } + } + } + else + { + window->context.glx.handle = + createLegacyContextGLX(window, native, share); + } } _glfwReleaseErrorHandlerX11(); From 4207a0a09b747564f6c2788fc6e6b23ab5a9cca2 Mon Sep 17 00:00:00 2001 From: git <> Date: Thu, 26 Apr 2018 14:45:31 +0200 Subject: [PATCH 4/7] Fixed 'wgl' member by renaming it to 'glx' on Linux port. --- src/glx_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/glx_context.c b/src/glx_context.c index 88c3af244..09627bd12 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -506,7 +506,7 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window, if(share) { // Use shared context instead of creating a new one - window->context.wgl.handle = share; + window->context.glx.handle = share; window->context.customctx = GLFW_FALSE; } else From a179278e2fc162b1b720280b1dd82bd383ea7fac Mon Sep 17 00:00:00 2001 From: Lukas Hermanns Date: Wed, 2 May 2018 15:09:10 +0200 Subject: [PATCH 5/7] Implemented single GLRC option on MacOS port. --- src/nsgl_context.m | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 82af90636..3a920aacc 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -30,7 +30,12 @@ static void makeContextCurrentNSGL(_GLFWwindow* window) { if (window) + { +#ifdef _GLFW_OPENGL_SINGLE_GLRC + [window->context.nsgl.object setView:window->ns.view]; +#endif [window->context.nsgl.object makeCurrentContext]; + } else [NSOpenGLContext clearCurrentContext]; @@ -79,7 +84,12 @@ static void destroyContextNSGL(_GLFWwindow* window) [window->context.nsgl.pixelFormat release]; window->context.nsgl.pixelFormat = nil; +#ifdef _GLFW_OPENGL_SINGLE_GLRC + if (window->context.customctx) + [window->context.nsgl.object release]; +#else [window->context.nsgl.object release]; +#endif window->context.nsgl.object = nil; } @@ -281,6 +291,22 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, return GLFW_FALSE; } +#ifdef _GLFW_OPENGL_SINGLE_GLRC + if (ctxconfig->share) + { + // Use shared context instead of creating a new one + window->context.nsgl.object = ctxconfig->share->context.nsgl.object; + window->context.customctx = GLFW_FALSE; + } + else + { + // Create new GL context + window->context.nsgl.object = + [[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat + shareContext:nil]; + window->context.customctx = GLFW_TRUE; + } +#else NSOpenGLContext* share = NULL; if (ctxconfig->share) @@ -289,13 +315,15 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, window->context.nsgl.object = [[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat shareContext:share]; +#endif + if (window->context.nsgl.object == nil) { _glfwInputError(GLFW_VERSION_UNAVAILABLE, "NSGL: Failed to create OpenGL context"); return GLFW_FALSE; } - + if (fbconfig->transparent) { GLint opaque = 0; From acf14b83a7e7880b38e39d8f038274a810670cca Mon Sep 17 00:00:00 2001 From: Lukas Hermanns Date: Wed, 2 May 2018 16:09:59 +0200 Subject: [PATCH 6/7] Removed trailing whitespace. --- src/nsgl_context.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 3a920aacc..d99235610 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -323,7 +323,7 @@ GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window, "NSGL: Failed to create OpenGL context"); return GLFW_FALSE; } - + if (fbconfig->transparent) { GLint opaque = 0; From 76324979b90465bee07a7e66787f22b704e18444 Mon Sep 17 00:00:00 2001 From: Lukas Hermanns Date: Tue, 8 May 2018 10:11:29 +0200 Subject: [PATCH 7/7] Added missing call to 'update' on NSOpenGLContext object in 'makeContextCurrentNSGL'. --- src/nsgl_context.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nsgl_context.m b/src/nsgl_context.m index d99235610..dcf6aad87 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -33,6 +33,7 @@ static void makeContextCurrentNSGL(_GLFWwindow* window) { #ifdef _GLFW_OPENGL_SINGLE_GLRC [window->context.nsgl.object setView:window->ns.view]; + [window->context.nsgl.object update]; #endif [window->context.nsgl.object makeCurrentContext]; }