Avoid libraries loading and unloading for GL hooks on windows

* This can cause the hooks to get out of sync if the libraries move between
  loads, so should be avoided. Most applications won't do this anyway.
This commit is contained in:
baldurk
2025-04-16 12:08:49 +01:00
parent 99c4d5a588
commit f9d03761b3
8 changed files with 22 additions and 9 deletions
+6 -1
View File
@@ -969,7 +969,7 @@ EGL_PASSTHRU_4(EGLSurface, eglCreatePlatformPixmapSurface, EGLDisplay, dpy, EGLC
void *, native_pixmap, const EGLAttrib *, attrib_list)
EGL_PASSTHRU_3(EGLBoolean, eglWaitSync, EGLDisplay, dpy, EGLSync, sync, EGLint, flags)
static void EGLHooked(void *handle)
static void EGLHooked(void *handle, const char *libName)
{
RDCDEBUG("EGL library hooked");
@@ -1013,6 +1013,11 @@ static void EGLHooked(void *handle)
ScopedSuppressHooking suppress;
return (void *)EGL.GetProcAddress(funcName);
});
#if ENABLED(RDOC_WIN32)
// force library to stay loaded so that function pointers don't move
LoadLibraryA(libName);
#endif
}
#if ENABLED(RDOC_WIN32)
+6 -1
View File
@@ -259,11 +259,16 @@ void GLDispatchTable::PopulateWithCallback(PlatformGetProcAddr lookupFunc)
ForEachSupported(HookFunc);
}
static void GLHooked(void *handle)
static void GLHooked(void *handle, const char *libName)
{
// store the handle for any unimplemented functions that need to look up their onward
// pointers
glhook.handle = handle;
#if ENABLED(RDOC_WIN32)
// force library to stay loaded so that function pointers don't move
LoadLibraryA(libName);
#endif
}
void GLHook::RegisterHooks()
+4 -1
View File
@@ -634,7 +634,7 @@ static PROC WINAPI wglGetProcAddress_hooked(const char *func)
return (PROC)HookedGetProcAddress(func, (void *)realFunc);
}
static void WGLHooked(void *handle)
static void WGLHooked(void *handle, const char *libName)
{
RDCDEBUG("WGL library hooked");
@@ -647,6 +647,9 @@ static void WGLHooked(void *handle)
WGL_NONHOOKED_SYMBOLS(WGL_FETCH)
#undef WGL_FETCH
// force library to stay loaded so that function pointers don't move
LoadLibraryA(libName);
// maybe in future we could create a dummy context here and populate the GL hooks already?
}
+1 -1
View File
@@ -27,7 +27,7 @@
#include "os/os_specific.h"
typedef std::function<void(void *)> FunctionLoadCallback;
typedef std::function<void(void *, const char *)> FunctionLoadCallback;
struct FunctionHook
{
+1 -1
View File
@@ -810,7 +810,7 @@ void LibraryHooks::EndHookRegistration()
HOOK_DEBUG_PRINT("Calling callbacks for %s", it->first.c_str());
for(FunctionLoadCallback callback : it->second)
if(callback)
callback(handle);
callback(handle, it->first.c_str());
}
}
+1 -1
View File
@@ -118,7 +118,7 @@ void LibraryHooks::EndHookRegistration()
{
for(FunctionLoadCallback cb : it->second)
if(cb)
cb(handle);
cb(handle, libName.c_str());
// don't call callbacks again if the library is dlopen'd again
it->second.clear();
+2 -2
View File
@@ -500,7 +500,7 @@ static void CheckLoadedLibraries()
for(FunctionLoadCallback cb : callbacks)
if(cb)
cb(handle);
cb(handle, libName.c_str());
}
}
@@ -542,7 +542,7 @@ void *intercept_dlopen(const char *filename, int flag, void *ret)
for(FunctionLoadCallback cb : callbacks)
if(cb)
cb(ret);
cb(ret, libName.c_str());
ret = realdlopen("lib" STRINGIZE(RDOC_BASE_NAME) ".so", flag);
break;
+1 -1
View File
@@ -598,7 +598,7 @@ static void HookAllModules()
for(FunctionLoadCallback cb : callbacks)
if(cb)
cb(it->second.module);
cb(it->second.module, it->first.c_str());
}
Atomic::CmpExch32(&s_HookData->posthooking, 1, 0);