From 3194fe93629100b3f370a8a789f70a2a168253de Mon Sep 17 00:00:00 2001 From: Charmaine Lee Date: Thu, 3 Nov 2022 15:40:49 -0700 Subject: [PATCH] wgl: fix reference to wgl(Create|Delete)Context function pointers Currently in wglCreateContextAttribsARB(), we get and save the pointers to OPENGL32.DLL's wglCreate/DeleteContext() functions. But these function pointers might be invalid after opengl32.dll is unloaded and reloaded again and possibly in a different address space. This patch, provided by Jose Fonseca, uses GetModuleHandle and gets the proc address of wglCreate/DeleteContext functions every time the function is called. Reviewed-by: Jesse Natalie Part-of: --- src/gallium/frontends/wgl/stw_ext_context.c | 51 ++++++++++++--------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/src/gallium/frontends/wgl/stw_ext_context.c b/src/gallium/frontends/wgl/stw_ext_context.c index 27927905424..779074f6a53 100644 --- a/src/gallium/frontends/wgl/stw_ext_context.c +++ b/src/gallium/frontends/wgl/stw_ext_context.c @@ -38,8 +38,8 @@ #include "util/u_debug.h" -static wglCreateContext_t wglCreateContext_func = 0; -static wglDeleteContext_t wglDeleteContext_func = 0; +static wglCreateContext_t g_pfnwglCreateContext = NULL; +static wglDeleteContext_t g_pfnwglDeleteContext = NULL; /* When this library is used as a opengl32.dll drop-in replacement, ensure we * use the wglCreate/Destroy entrypoints above, and not the true opengl32.dll, @@ -51,8 +51,8 @@ static wglDeleteContext_t wglDeleteContext_func = 0; void stw_override_opengl32_entry_points(wglCreateContext_t create, wglDeleteContext_t delete) { - wglCreateContext_func = create; - wglDeleteContext_func = delete; + g_pfnwglCreateContext = create; + g_pfnwglDeleteContext = delete; } @@ -164,34 +164,43 @@ wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList) return NULL; } - /* Get pointer to OPENGL32.DLL's wglCreate/DeleteContext() functions */ - if (!wglCreateContext_func || !wglDeleteContext_func) { - /* Get the OPENGL32.DLL library */ + wglCreateContext_t pfnwglCreateContext; + wglDeleteContext_t pfnwglDeleteContext; + + if (stw_dev->callbacks.pfnGetDhglrc) { + /* Used as an ICD. + * + * Get pointers to OPENGL32.DLL's wglCreate/DeleteContext() functions + */ HMODULE opengl_lib = GetModuleHandleA("opengl32.dll"); if (!opengl_lib) { _debug_printf("wgl: GetModuleHandleA(\"opengl32.dll\") failed\n"); - return 0; + return NULL; } - /* Get pointer to wglCreateContext() function */ - wglCreateContext_func = (wglCreateContext_t) + pfnwglCreateContext = (wglCreateContext_t) GetProcAddress(opengl_lib, "wglCreateContext"); - if (!wglCreateContext_func) { + if (!pfnwglCreateContext) { _debug_printf("wgl: failed to get wglCreateContext()\n"); - return 0; + return NULL; } - /* Get pointer to wglDeleteContext() function */ - wglDeleteContext_func = (wglDeleteContext_t) + pfnwglDeleteContext = (wglDeleteContext_t) GetProcAddress(opengl_lib, "wglDeleteContext"); - if (!wglDeleteContext_func) { + if (!pfnwglDeleteContext) { _debug_printf("wgl: failed to get wglDeleteContext()\n"); - return 0; + return NULL; } + } else { + /* Used as opengl32.dll drop-in alternative. */ + assert(g_pfnwglCreateContext != NULL); + assert(g_pfnwglDeleteContext != NULL); + pfnwglCreateContext = g_pfnwglCreateContext; + pfnwglDeleteContext = g_pfnwglDeleteContext; } /* Call wglCreateContext to get a valid context ID */ - context = wglCreateContext_func(hDC); + context = pfnwglCreateContext(hDC); if (context) { /* Now replace the context we just created with a new one that reflects @@ -224,15 +233,15 @@ wglCreateContextAttribsARB(HDC hDC, HGLRC hShareContext, const int *attribList) resetStrategy); if (!stw_ctx) { - wglDeleteContext_func(context); - return 0; + pfnwglDeleteContext(context); + return NULL; } c = stw_create_context_handle(stw_ctx, dhglrc); if (!c) { stw_destroy_context(stw_ctx); - wglDeleteContext_func(context); - context = 0; + pfnwglDeleteContext(context); + context = NULL; } }