From 60940e5a02c5251fe1aa1d9ad7f2bf74d7076a73 Mon Sep 17 00:00:00 2001 From: jackun Date: Tue, 18 Aug 2020 19:13:27 +0300 Subject: [PATCH] [OpenGL] Just "refcount" by glXCreate/DestroyContext calls; recreate "lost" objects --- src/gl/gl.h | 1 + src/gl/imgui_hud.cpp | 4 +-- src/gl/imgui_impl_opengl3.cpp | 7 ++++ src/gl/inject_glx.cpp | 61 ++++++++++++++++++++++++++--------- src/loaders/loader_glx.cpp | 16 +++++++++ src/loaders/loader_glx.h | 2 ++ 6 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/gl/gl.h b/src/gl/gl.h index 34b8e137..79b5a3db 100644 --- a/src/gl/gl.h +++ b/src/gl/gl.h @@ -15,6 +15,7 @@ int glXSwapIntervalMESA(unsigned int); int glXGetSwapIntervalMESA(void); int glXMakeCurrent(void*, void*, void*); void* glXGetCurrentContext(); +void *glXCreateContextAttribsARB(void *dpy, void *config,void *share_context, int direct, const int *attrib_list); void* glXGetProcAddress(const unsigned char*); void* glXGetProcAddressARB(const unsigned char*); diff --git a/src/gl/imgui_hud.cpp b/src/gl/imgui_hud.cpp index 257ad62f..4ada82de 100644 --- a/src/gl/imgui_hud.cpp +++ b/src/gl/imgui_hud.cpp @@ -85,11 +85,11 @@ void imgui_create(void *ctx) if (!ctx) return; - + imgui_shutdown(); imgui_init(); inited = true; - + gladLoadGL(); GetOpenGLVersion(sw_stats.version_gl.major, diff --git a/src/gl/imgui_impl_opengl3.cpp b/src/gl/imgui_impl_opengl3.cpp index c5f822bc..c87e7da2 100644 --- a/src/gl/imgui_impl_opengl3.cpp +++ b/src/gl/imgui_impl_opengl3.cpp @@ -480,6 +480,13 @@ void ImGui_ImplOpenGL3_NewFrame() { if (!g_ShaderHandle) ImGui_ImplOpenGL3_CreateDeviceObjects(); + else if (!glIsProgram(g_ShaderHandle)) { // TODO Got created in a now dead context? +#ifndef NDEBUG + fprintf(stderr, "MANGOHUD: recreating lost objects\n"); +#endif + ImGui_ImplOpenGL3_CreateDeviceObjects(); + } + if (!glIsTexture(g_FontTexture)) { #ifndef NDEBUG fprintf(stderr, "MANGOHUD: GL Texture lost? Regenerating.\n"); diff --git a/src/gl/inject_glx.cpp b/src/gl/inject_glx.cpp index 624bc379..763a4b33 100644 --- a/src/gl/inject_glx.cpp +++ b/src/gl/inject_glx.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "real_dlsym.h" #include "loaders/loader_glx.h" @@ -31,7 +32,7 @@ EXPORT_C_(void *) glXGetProcAddressARB(const unsigned char* procName); static glx_loader glx; -static std::vector gl_threads; +static std::atomic refcnt (0); void* get_glx_proc_address(const char* name) { glx.Load(); @@ -57,12 +58,50 @@ EXPORT_C_(void *) glXCreateContext(void *dpy, void *vis, void *shareList, int di { glx.Load(); void *ctx = glx.CreateContext(dpy, vis, shareList, direct); + if (ctx) + refcnt++; #ifndef NDEBUG std::cerr << __func__ << ":" << ctx << std::endl; #endif return ctx; } +EXPORT_C_(void *) glXCreateContextAttribs(void *dpy, void *config,void *share_context, int direct, const int *attrib_list) +{ + glx.Load(); + void *ctx = glx.CreateContextAttribs(dpy, config, share_context, direct, attrib_list); + if (ctx) + refcnt++; +#ifndef NDEBUG + std::cerr << __func__ << ":" << ctx << std::endl; +#endif + return ctx; +} + +EXPORT_C_(void *) glXCreateContextAttribsARB(void *dpy, void *config,void *share_context, int direct, const int *attrib_list) +{ + glx.Load(); + void *ctx = glx.CreateContextAttribsARB(dpy, config, share_context, direct, attrib_list); + if (ctx) + refcnt++; +#ifndef NDEBUG + std::cerr << __func__ << ":" << ctx << std::endl; +#endif + return ctx; +} + +EXPORT_C_(void) glXDestroyContext(void *dpy, void *ctx) +{ + glx.Load(); + glx.DestroyContext(dpy, ctx); + refcnt--; + if (refcnt <= 0) + imgui_shutdown(); +#ifndef NDEBUG + std::cerr << __func__ << ":" << ctx << std::endl; +#endif +} + EXPORT_C_(int) glXMakeCurrent(void* dpy, void* drawable, void* ctx) { glx.Load(); #ifndef NDEBUG @@ -73,21 +112,10 @@ EXPORT_C_(int) glXMakeCurrent(void* dpy, void* drawable, void* ctx) { if (!is_blacklisted()) { if (ret) { - //TODO might as well just ignore everything here as long as VBOs get recreated anyway - auto it = std::find(gl_threads.begin(), gl_threads.end(), std::this_thread::get_id()); - if (!ctx) { - if (it != gl_threads.end()) - gl_threads.erase(it); - if (!gl_threads.size()) - imgui_set_context(nullptr); - } else { - if (it == gl_threads.end()) - gl_threads.push_back(std::this_thread::get_id()); - imgui_set_context(ctx); + imgui_set_context(ctx); #ifndef NDEBUG - std::cerr << "MANGOHUD: GL thread count: " << gl_threads.size() << "\n"; + std::cerr << "MANGOHUD: GL ref count: " << refcnt << "\n"; #endif - } } if (params.gl_vsync >= -1) { @@ -214,11 +242,14 @@ struct func_ptr { void *ptr; }; -static std::array name_to_funcptr_map = {{ +static std::array name_to_funcptr_map = {{ #define ADD_HOOK(fn) { #fn, (void *) fn } ADD_HOOK(glXGetProcAddress), ADD_HOOK(glXGetProcAddressARB), + ADD_HOOK(glXCreateContextAttribs), + ADD_HOOK(glXCreateContextAttribsARB), ADD_HOOK(glXCreateContext), + ADD_HOOK(glXDestroyContext), ADD_HOOK(glXMakeCurrent), ADD_HOOK(glXSwapBuffers), ADD_HOOK(glXSwapBuffersMscOML), diff --git a/src/loaders/loader_glx.cpp b/src/loaders/loader_glx.cpp index ca22ccd4..d245a76a 100644 --- a/src/loaders/loader_glx.cpp +++ b/src/loaders/loader_glx.cpp @@ -42,6 +42,22 @@ bool glx_loader::Load() { return false; } + CreateContextAttribs = + reinterpret_castCreateContextAttribs)>( + GetProcAddress((const unsigned char *)"glXCreateContextAttribs")); +// if (!CreateContextAttribs) { +// CleanUp(true); +// return false; +// } + + CreateContextAttribsARB = + reinterpret_castCreateContextAttribsARB)>( + GetProcAddress((const unsigned char *)"glXCreateContextAttribsARB")); +// if (!CreateContextAttribsARB) { +// CleanUp(true); +// return false; +// } + DestroyContext = reinterpret_castDestroyContext)>( GetProcAddress((const unsigned char *)"glXDestroyContext")); diff --git a/src/loaders/loader_glx.h b/src/loaders/loader_glx.h index 760894c4..e3ecc9fb 100644 --- a/src/loaders/loader_glx.h +++ b/src/loaders/loader_glx.h @@ -13,6 +13,8 @@ class glx_loader { decltype(&::glXGetProcAddress) GetProcAddress; decltype(&::glXGetProcAddressARB) GetProcAddressARB; decltype(&::glXCreateContext) CreateContext; + decltype(&::glXCreateContextAttribsARB) CreateContextAttribs; + decltype(&::glXCreateContextAttribsARB) CreateContextAttribsARB; decltype(&::glXDestroyContext) DestroyContext; decltype(&::glXSwapBuffers) SwapBuffers; decltype(&::glXSwapIntervalEXT) SwapIntervalEXT;