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 <jenatali@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/19478>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user