Browse Source

Move context management out of glfwCreateWindow

Related to #25.
Camilla Löwy 7 years ago
parent
commit
1034b6e0db
5 changed files with 62 additions and 69 deletions
  1. 12 4
      src/context.c
  2. 2 1
      src/internal.h
  3. 44 47
      src/wgl_context.c
  4. 3 2
      src/wgl_context.h
  5. 1 15
      src/window.c

+ 12 - 4
src/context.c

@@ -321,10 +321,11 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
     return closest;
 }
 
-GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
+GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
+                                    const _GLFWctxconfig* ctxconfig)
 {
     int i;
-    _GLFWwindow* window;
+    _GLFWwindow* previous;
     const char* version;
     const char* prefixes[] =
     {
@@ -334,11 +335,12 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
         NULL
     };
 
-    window = _glfwPlatformGetTls(&_glfw.contextSlot);
-
     window->context.source = ctxconfig->source;
     window->context.client = GLFW_OPENGL_API;
 
+    previous = _glfwPlatformGetTls(&_glfw.contextSlot);;
+    glfwMakeContextCurrent((GLFWwindow*) window);
+
     window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
         window->context.getProcAddress("glGetIntegerv");
     window->context.GetString = (PFNGLGETSTRINGPROC)
@@ -346,6 +348,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
     if (!window->context.GetIntegerv || !window->context.GetString)
     {
         _glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
+        glfwMakeContextCurrent((GLFWwindow*) previous);
         return GLFW_FALSE;
     }
 
@@ -363,6 +366,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
                             "OpenGL ES version string retrieval is broken");
         }
 
+        glfwMakeContextCurrent((GLFWwindow*) previous);
         return GLFW_FALSE;
     }
 
@@ -394,6 +398,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
                             "No version found in OpenGL ES version string");
         }
 
+        glfwMakeContextCurrent((GLFWwindow*) previous);
         return GLFW_FALSE;
     }
 
@@ -423,6 +428,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
                             window->context.major, window->context.minor);
         }
 
+        glfwMakeContextCurrent((GLFWwindow*) previous);
         return GLFW_FALSE;
     }
 
@@ -438,6 +444,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
         {
             _glfwInputError(GLFW_PLATFORM_ERROR,
                             "Entry point retrieval is broken");
+            glfwMakeContextCurrent((GLFWwindow*) previous);
             return GLFW_FALSE;
         }
     }
@@ -544,6 +551,7 @@ GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig)
         window->context.swapBuffers(window);
     }
 
+    glfwMakeContextCurrent((GLFWwindow*) previous);
     return GLFW_TRUE;
 }
 

+ 2 - 1
src/internal.h

@@ -954,7 +954,8 @@ const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
  *  unusable.
  *  @ingroup utility
  */
-GLFWbool _glfwRefreshContextAttribs(const _GLFWctxconfig* ctxconfig);
+GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
+                                    const _GLFWctxconfig* ctxconfig);
 
 /*! @brief Checks whether the desired context attributes are valid.
  *  @param[in] ctxconfig The context attributes to check.

+ 44 - 47
src/wgl_context.c

@@ -329,21 +329,52 @@ static void destroyContextWGL(_GLFWwindow* window)
     }
 }
 
-// Initialize WGL-specific extensions
+
+//////////////////////////////////////////////////////////////////////////
+//////                       GLFW internal API                      //////
+//////////////////////////////////////////////////////////////////////////
+
+// Initialize WGL
 //
-static void loadWGLExtensions(void)
+GLFWbool _glfwInitWGL(void)
 {
     PIXELFORMATDESCRIPTOR pfd;
-    HGLRC rc;
-    HDC dc = GetDC(_glfw.win32.helperWindowHandle);;
+    HGLRC prc, rc;
+    HDC pdc, dc;
+
+    if (_glfw.wgl.instance)
+        return GLFW_TRUE;
+
+    _glfw.wgl.instance = LoadLibraryA("opengl32.dll");
+    if (!_glfw.wgl.instance)
+    {
+        _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
+                             "WGL: Failed to load opengl32.dll");
+        return GLFW_FALSE;
+    }
 
-    _glfw.wgl.extensionsLoaded = GLFW_TRUE;
+    _glfw.wgl.CreateContext = (PFN_wglCreateContext)
+        GetProcAddress(_glfw.wgl.instance, "wglCreateContext");
+    _glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
+        GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
+    _glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
+        GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
+    _glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
+        GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
+    _glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
+        GetProcAddress(_glfw.wgl.instance, "wglGetCurrentContext");
+    _glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
+        GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
+    _glfw.wgl.ShareLists = (PFN_wglShareLists)
+        GetProcAddress(_glfw.wgl.instance, "wglShareLists");
 
     // NOTE: A dummy context has to be created for opengl32.dll to load the
     //       OpenGL ICD, from which we can then query WGL extensions
     // NOTE: This code will accept the Microsoft GDI ICD; accelerated context
     //       creation failure occurs during manual pixel format enumeration
 
+    dc = GetDC(_glfw.win32.helperWindowHandle);;
+
     ZeroMemory(&pfd, sizeof(pfd));
     pfd.nSize = sizeof(pfd);
     pfd.nVersion = 1;
@@ -355,7 +386,7 @@ static void loadWGLExtensions(void)
     {
         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
                              "WGL: Failed to set pixel format for dummy context");
-        return;
+        return GLFW_FALSE;
     }
 
     rc = wglCreateContext(dc);
@@ -363,15 +394,19 @@ static void loadWGLExtensions(void)
     {
         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
                              "WGL: Failed to create dummy context");
-        return;
+        return GLFW_FALSE;
     }
 
+    pdc = wglGetCurrentDC();
+    prc = wglGetCurrentContext();
+
     if (!wglMakeCurrent(dc, rc))
     {
         _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
                              "WGL: Failed to make dummy context current");
+        wglMakeCurrent(pdc, prc);
         wglDeleteContext(rc);
-        return;
+        return GLFW_FALSE;
     }
 
     // NOTE: Functions must be loaded first as they're needed to retrieve the
@@ -414,43 +449,8 @@ static void loadWGLExtensions(void)
     _glfw.wgl.ARB_context_flush_control =
         extensionSupportedWGL("WGL_ARB_context_flush_control");
 
-    wglMakeCurrent(dc, NULL);
+    wglMakeCurrent(pdc, prc);
     wglDeleteContext(rc);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-//////                       GLFW internal API                      //////
-//////////////////////////////////////////////////////////////////////////
-
-// Initialize WGL
-//
-GLFWbool _glfwInitWGL(void)
-{
-    if (_glfw.wgl.instance)
-        return GLFW_TRUE;
-
-    _glfw.wgl.instance = LoadLibraryA("opengl32.dll");
-    if (!_glfw.wgl.instance)
-    {
-        _glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
-                             "WGL: Failed to load opengl32.dll");
-        return GLFW_FALSE;
-    }
-
-    _glfw.wgl.CreateContext = (PFN_wglCreateContext)
-        GetProcAddress(_glfw.wgl.instance, "wglCreateContext");
-    _glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
-        GetProcAddress(_glfw.wgl.instance, "wglDeleteContext");
-    _glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
-        GetProcAddress(_glfw.wgl.instance, "wglGetProcAddress");
-    _glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
-        GetProcAddress(_glfw.wgl.instance, "wglGetCurrentDC");
-    _glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
-        GetProcAddress(_glfw.wgl.instance, "wglMakeCurrent");
-    _glfw.wgl.ShareLists = (PFN_wglShareLists)
-        GetProcAddress(_glfw.wgl.instance, "wglShareLists");
-
     return GLFW_TRUE;
 }
 
@@ -480,9 +480,6 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
     PIXELFORMATDESCRIPTOR pfd;
     HGLRC share = NULL;
 
-    if (!_glfw.wgl.extensionsLoaded)
-        loadWGLExtensions();
-
     if (ctxconfig->share)
         share = ctxconfig->share->context.wgl.handle;
 

+ 3 - 2
src/wgl_context.h

@@ -86,6 +86,7 @@ typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
 typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
 typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
 typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
+typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
 typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
 typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
 
@@ -94,6 +95,7 @@ typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
 #define wglDeleteContext _glfw.wgl.DeleteContext
 #define wglGetProcAddress _glfw.wgl.GetProcAddress
 #define wglGetCurrentDC _glfw.wgl.GetCurrentDC
+#define wglGetCurrentContext _glfw.wgl.GetCurrentContext
 #define wglMakeCurrent _glfw.wgl.MakeCurrent
 #define wglShareLists _glfw.wgl.ShareLists
 
@@ -124,11 +126,10 @@ typedef struct _GLFWlibraryWGL
     PFN_wglDeleteContext                DeleteContext;
     PFN_wglGetProcAddress               GetProcAddress;
     PFN_wglGetCurrentDC                 GetCurrentDC;
+    PFN_wglGetCurrentContext            GetCurrentContext;
     PFN_wglMakeCurrent                  MakeCurrent;
     PFN_wglShareLists                   ShareLists;
 
-    GLFWbool                            extensionsLoaded;
-
     PFNWGLSWAPINTERVALEXTPROC           SwapIntervalEXT;
     PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
     PFNWGLGETEXTENSIONSSTRINGEXTPROC    GetExtensionsStringEXT;

+ 1 - 15
src/window.c

@@ -127,7 +127,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
     _GLFWctxconfig ctxconfig;
     _GLFWwndconfig wndconfig;
     _GLFWwindow* window;
-    _GLFWwindow* previous;
 
     assert(title != NULL);
     assert(width >= 0);
@@ -191,33 +190,20 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
     window->numer       = GLFW_DONT_CARE;
     window->denom       = GLFW_DONT_CARE;
 
-    // Save the currently current context so it can be restored later
-    previous = _glfwPlatformGetTls(&_glfw.contextSlot);
-    if (ctxconfig.client != GLFW_NO_API)
-        glfwMakeContextCurrent(NULL);
-
     // Open the actual window and create its context
     if (!_glfwPlatformCreateWindow(window, &wndconfig, &ctxconfig, &fbconfig))
     {
-        glfwMakeContextCurrent((GLFWwindow*) previous);
         glfwDestroyWindow((GLFWwindow*) window);
         return NULL;
     }
 
     if (ctxconfig.client != GLFW_NO_API)
     {
-        window->context.makeCurrent(window);
-
-        // Retrieve the actual (as opposed to requested) context attributes
-        if (!_glfwRefreshContextAttribs(&ctxconfig))
+        if (!_glfwRefreshContextAttribs(window, &ctxconfig))
         {
-            glfwMakeContextCurrent((GLFWwindow*) previous);
             glfwDestroyWindow((GLFWwindow*) window);
             return NULL;
         }
-
-        // Restore the previously current context (or NULL)
-        glfwMakeContextCurrent((GLFWwindow*) previous);
     }
 
     if (!window->monitor)