diff --git a/renderdoc/driver/gl/gl_driver.cpp b/renderdoc/driver/gl/gl_driver.cpp index c04f7d2b7..bb09f3aa4 100644 --- a/renderdoc/driver/gl/gl_driver.cpp +++ b/renderdoc/driver/gl/gl_driver.cpp @@ -498,6 +498,10 @@ void *WrappedOpenGL::GetCtx() // Windowing/setup/etc //////////////////////////////////////////////////////////////// +void WrappedOpenGL::DeleteContext(void *contextHandle) +{ +} + void WrappedOpenGL::CreateContext(void *windowHandle, void *contextHandle, void *shareContext, GLInitParams initParams) { // TODO: support multiple GL contexts more explicitly diff --git a/renderdoc/driver/gl/gl_driver.h b/renderdoc/driver/gl/gl_driver.h index 4262e6d6a..36ab2ec9a 100644 --- a/renderdoc/driver/gl/gl_driver.h +++ b/renderdoc/driver/gl/gl_driver.h @@ -284,6 +284,7 @@ class WrappedOpenGL FetchAPIEvent GetEvent(uint32_t eventID); void CreateContext(void *windowHandle, void *contextHandle, void *shareContext, GLInitParams initParams); + void DeleteContext(void *contextHandle); void ActivateContext(void *windowHandle, void *contextHandle); void WindowSize(void *windowHandle, uint32_t w, uint32_t h); void Present(void *windowHandle); diff --git a/renderdoc/hooks/gl_linux_hooks.cpp b/renderdoc/hooks/gl_linux_hooks.cpp index f36795c91..4fafd0a9d 100644 --- a/renderdoc/hooks/gl_linux_hooks.cpp +++ b/renderdoc/hooks/gl_linux_hooks.cpp @@ -266,6 +266,7 @@ class OpenGLHook : LibraryHook } PFNGLXCREATECONTEXTPROC glXCreateContext_real; + PFNGLXDESTROYCONTEXTPROC glXDestroyContext_real; PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB_real; PFNGLXGETPROCADDRESSPROC glXGetProcAddress_real; PFNGLXMAKECURRENTPROC glXMakeCurrent_real; @@ -315,6 +316,14 @@ GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis, GLXContext shareList return ret; } +__attribute__ ((visibility ("default"))) +void glXDestroyContext(Display *dpy, GLXContext ctx) +{ + OpenGLHook::glhooks.GetDriver()->DeleteContext(ctx); + + OpenGLHook::glhooks.glXDestroyContext_real(dpy, ctx); +} + __attribute__ ((visibility ("default"))) GLXContext glXCreateContextAttribsARB(Display *dpy, GLXFBConfig config, GLXContext shareList, Bool direct, const int *attribList) { @@ -393,6 +402,7 @@ bool OpenGLHook::SetupHooks(GLHookSet &GL) if(glXGetProcAddress_real == NULL) glXGetProcAddress_real = (PFNGLXGETPROCADDRESSPROC)dlsym(libGLdlsymHandle, "glXGetProcAddress"); if(glXCreateContext_real == NULL) glXCreateContext_real = (PFNGLXCREATECONTEXTPROC)dlsym(libGLdlsymHandle, "glXCreateContext"); + if(glXDestroyContext_real == NULL) glXDestroyContext_real = (PFNGLXDESTROYCONTEXTPROC)dlsym(libGLdlsymHandle, "glXDestroyContext"); if(glXCreateContextAttribsARB_real == NULL) glXCreateContextAttribsARB_real = (PFNGLXCREATECONTEXTATTRIBSARBPROC)dlsym(libGLdlsymHandle, "glXCreateContextAttribsARB"); if(glXMakeCurrent_real == NULL) glXMakeCurrent_real = (PFNGLXMAKECURRENTPROC)dlsym(libGLdlsymHandle, "glXMakeCurrent"); if(glXSwapBuffers_real == NULL) glXSwapBuffers_real = (PFNGLXSWAPBUFFERSPROC)dlsym(libGLdlsymHandle, "glXSwapBuffers"); @@ -427,6 +437,7 @@ __GLXextFuncPtr glXGetProcAddress(const GLubyte *f) // handle a few functions that we only export as real functions, just // in case if(!strcmp(func, "glXCreateContext")) return (__GLXextFuncPtr)&glXCreateContext; + if(!strcmp(func, "glXDestroyContext")) return (__GLXextFuncPtr)&glXDestroyContext; if(!strcmp(func, "glXCreateContextAttribsARB")) return (__GLXextFuncPtr)&glXCreateContextAttribsARB; if(!strcmp(func, "glXMakeCurrent")) return (__GLXextFuncPtr)&glXMakeCurrent; if(!strcmp(func, "glXSwapBuffers")) return (__GLXextFuncPtr)&glXSwapBuffers; diff --git a/renderdoc/hooks/gl_win32_hooks.cpp b/renderdoc/hooks/gl_win32_hooks.cpp index 6e17d6347..b9d014498 100644 --- a/renderdoc/hooks/gl_win32_hooks.cpp +++ b/renderdoc/hooks/gl_win32_hooks.cpp @@ -261,6 +261,7 @@ class OpenGLHook : LibraryHook } Hook wglCreateContext_hook; + Hook wglDeleteContext_hook; Hook wglCreateLayerContext_hook; Hook wglMakeCurrent_hook; Hook wglGetProcAddress_hook; @@ -314,6 +315,13 @@ class OpenGLHook : LibraryHook return ret; } + static BOOL WINAPI wglDeleteContext_hooked(HGLRC rc) + { + glhooks.GetDriver()->DeleteContext(rc); + + return glhooks.wglDeleteContext_hook()(rc); + } + static HGLRC WINAPI wglCreateLayerContext_hooked(HDC dc, int iLayerPlane) { HGLRC ret = glhooks.wglCreateLayerContext_hook()(dc, iLayerPlane); @@ -351,9 +359,14 @@ class OpenGLHook : LibraryHook { BOOL ret = glhooks.wglMakeCurrent_hook()(dc, rc); - glhooks.GetDriver()->ActivateContext(WindowFromDC(dc), rc); + if(rc && glhooks.m_Contexts.find(rc) == glhooks.m_Contexts.end()) + { + glhooks.m_Contexts.insert(rc); - glhooks.GetRealFunctions(); + glhooks.PopulateHooks(); + } + + glhooks.GetDriver()->ActivateContext(WindowFromDC(dc), rc); return ret; } @@ -367,7 +380,7 @@ class OpenGLHook : LibraryHook glhooks.GetDriver()->WindowSize(w, r.right-r.left, r.bottom-r.top); - glhooks.GetDriver()->Present(dc); + glhooks.GetDriver()->Present(w); return glhooks.SwapBuffers_hook()(dc); } @@ -449,11 +462,14 @@ class OpenGLHook : LibraryHook bool m_HasHooks; bool m_EnabledHooks; + set m_Contexts; + bool SetupHooks(GLHookSet &GL) { bool success = true; success &= wglCreateContext_hook.Initialize("wglCreateContext", DLL_NAME, wglCreateContext_hooked); + success &= wglDeleteContext_hook.Initialize("wglDeleteContext", DLL_NAME, wglDeleteContext_hooked); success &= wglCreateLayerContext_hook.Initialize("wglCreateLayerContext", DLL_NAME, wglCreateLayerContext_hooked); success &= wglMakeCurrent_hook.Initialize("wglMakeCurrent", DLL_NAME, wglMakeCurrent_hooked); success &= wglGetProcAddress_hook.Initialize("wglGetProcAddress", DLL_NAME, wglGetProcAddress_hooked);