diff --git a/meson_options.txt b/meson_options.txt index b9de6b83..e357e8d1 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -8,3 +8,4 @@ option('with_xnvctrl', type : 'feature', value : 'enabled', description: 'Enable option('with_x11', type : 'feature', value : 'enabled') option('with_wayland', type : 'feature', value : 'disabled') option('with_dbus', type : 'feature', value : 'enabled') +option('with_dlsym', type : 'feature', value : 'disabled') diff --git a/src/blacklist.cpp b/src/blacklist.cpp new file mode 100644 index 00000000..eff7f302 --- /dev/null +++ b/src/blacklist.cpp @@ -0,0 +1,59 @@ +#include +#include +#include + +#include "blacklist.h" +#include "string_utils.h" +#include "file_utils.h" + +static std::string get_proc_name() { +#ifdef _GNU_SOURCE_OFF + std::string p(program_invocation_name); + std::string proc_name = p.substr(p.find_last_of("/\\") + 1); +#else + std::string p = get_exe_path(); + std::string proc_name; + if (ends_with(p, "wine-preloader") || ends_with(p, "wine64-preloader")) { + get_wine_exe_name(proc_name, true); + } else { + proc_name = p.substr(p.find_last_of("/\\") + 1); + } +#endif + return proc_name; +} + +static bool check_blacklisted() { + std::vector blacklist { + "Battle.net.exe", + "BethesdaNetLauncher.exe", + "EpicGamesLauncher.exe", + "IGOProxy.exe", + "IGOProxy64.exe", + "Origin.exe", + "OriginThinSetupInternal.exe", + "steam", + "steamwebhelper", + "gldriverquery", + "vulkandriverquery", + "Steam.exe", + }; + + std::string proc_name = get_proc_name(); + bool blacklisted = std::find(blacklist.begin(), blacklist.end(), proc_name) != blacklist.end(); +#ifndef NDEBUG + std::cerr << "MANGOHUD: process " << proc_name << " is blacklisted: " << blacklisted << std::endl; +#endif + return blacklisted; +} + +bool& is_blacklisted() { + static bool checked = false; + static bool blacklisted = false; + + if (!checked) { + checked = true; + blacklisted = check_blacklisted(); + } + + return blacklisted; +} diff --git a/src/blacklist.h b/src/blacklist.h new file mode 100644 index 00000000..6051bcca --- /dev/null +++ b/src/blacklist.h @@ -0,0 +1,3 @@ +#pragma once + +bool& is_blacklisted(); diff --git a/src/gl/inject_egl.cpp b/src/gl/inject_egl.cpp index 05c8ec74..a65c4f1b 100644 --- a/src/gl/inject_egl.cpp +++ b/src/gl/inject_egl.cpp @@ -4,6 +4,7 @@ #include "real_dlsym.h" #include "mesa/util/macros.h" #include "mesa/util/os_time.h" +#include "blacklist.h" #include #include @@ -51,21 +52,23 @@ EXPORT_C_(unsigned int) eglSwapBuffers( void* dpy, void* surf) if (!pfn_eglSwapBuffers) pfn_eglSwapBuffers = reinterpret_cast(get_proc_address("eglSwapBuffers")); - static int (*pfn_eglQuerySurface)(void* dpy, void* surface, int attribute, int *value) = nullptr; - if (!pfn_eglQuerySurface) - pfn_eglQuerySurface = reinterpret_cast(get_proc_address("eglQuerySurface")); + if (!is_blacklisted()) { + static int (*pfn_eglQuerySurface)(void* dpy, void* surface, int attribute, int *value) = nullptr; + if (!pfn_eglQuerySurface) + pfn_eglQuerySurface = reinterpret_cast(get_proc_address("eglQuerySurface")); - //std::cerr << __func__ << "\n"; + //std::cerr << __func__ << "\n"; - imgui_create(surf); + imgui_create(surf); - int width=0, height=0; - if (pfn_eglQuerySurface(dpy, surf, 0x3056, &height) && - pfn_eglQuerySurface(dpy, surf, 0x3057, &width)) - imgui_render(width, height); + int width=0, height=0; + if (pfn_eglQuerySurface(dpy, surf, 0x3056, &height) && + pfn_eglQuerySurface(dpy, surf, 0x3057, &width)) + imgui_render(width, height); - //std::cerr << "\t" << width << " x " << height << "\n"; + //std::cerr << "\t" << width << " x " << height << "\n"; + } return pfn_eglSwapBuffers(dpy, surf); } @@ -83,6 +86,9 @@ static std::array name_to_funcptr_map = {{ void *find_egl_ptr(const char *name) { + if (is_blacklisted()) + return nullptr; + for (auto& func : name_to_funcptr_map) { if (strcmp(name, func.name) == 0) return func.ptr; diff --git a/src/gl/inject_glx.cpp b/src/gl/inject_glx.cpp index a13ff8ea..82d8c1b2 100644 --- a/src/gl/inject_glx.cpp +++ b/src/gl/inject_glx.cpp @@ -7,6 +7,7 @@ #include "loaders/loader_x11.h" #include "mesa/util/macros.h" #include "mesa/util/os_time.h" +#include "blacklist.h" #include #include @@ -64,16 +65,19 @@ EXPORT_C_(int) glXMakeCurrent(void* dpy, void* drawable, void* ctx) { #endif int ret = glx.MakeCurrent(dpy, drawable, ctx); - if (ret) - imgui_set_context(ctx); - - if (params.gl_vsync >= -1) { - if (glx.SwapIntervalEXT) - glx.SwapIntervalEXT(dpy, drawable, params.gl_vsync); - if (glx.SwapIntervalSGI) - glx.SwapIntervalSGI(params.gl_vsync); - if (glx.SwapIntervalMESA) - glx.SwapIntervalMESA(params.gl_vsync); + + if (!is_blacklisted()) { + if (ret) + imgui_set_context(ctx); + + if (params.gl_vsync >= -1) { + if (glx.SwapIntervalEXT) + glx.SwapIntervalEXT(dpy, drawable, params.gl_vsync); + if (glx.SwapIntervalSGI) + glx.SwapIntervalSGI(params.gl_vsync); + if (glx.SwapIntervalMESA) + glx.SwapIntervalMESA(params.gl_vsync); + } } return ret; @@ -81,32 +85,37 @@ EXPORT_C_(int) glXMakeCurrent(void* dpy, void* drawable, void* ctx) { EXPORT_C_(void) glXSwapBuffers(void* dpy, void* drawable) { glx.Load(); - imgui_create(glx.GetCurrentContext()); - - unsigned int width = -1, height = -1; - - // glXQueryDrawable is buggy, use XGetGeometry instead - Window unused_window; - int unused; - static bool xgetgeom_failed = false; - if (xgetgeom_failed || !g_x11->XGetGeometry((Display*)dpy, - (Window)drawable, &unused_window, - &unused, &unused, - &width, &height, - (unsigned int*) &unused, (unsigned int*) &unused)) { - - xgetgeom_failed = true; - glx.QueryDrawable(dpy, drawable, GLX_WIDTH, &width); - glx.QueryDrawable(dpy, drawable, GLX_HEIGTH, &height); - } - /*GLint vp[4]; glGetIntegerv (GL_VIEWPORT, vp); - width = vp[2]; - height = vp[3];*/ + if (!is_blacklisted()) { + imgui_create(glx.GetCurrentContext()); + + unsigned int width = -1, height = -1; + + // glXQueryDrawable is buggy, use XGetGeometry instead + Window unused_window; + int unused; + static bool xgetgeom_failed = false; + if (xgetgeom_failed || !g_x11->XGetGeometry((Display*)dpy, + (Window)drawable, &unused_window, + &unused, &unused, + &width, &height, + (unsigned int*) &unused, (unsigned int*) &unused)) { + + xgetgeom_failed = true; + glx.QueryDrawable(dpy, drawable, GLX_WIDTH, &width); + glx.QueryDrawable(dpy, drawable, GLX_HEIGTH, &height); + } + + /*GLint vp[4]; glGetIntegerv (GL_VIEWPORT, vp); + width = vp[2]; + height = vp[3];*/ + + imgui_render(width, height); + } - imgui_render(width, height); glx.SwapBuffers(dpy, drawable); - if (fps_limit_stats.targetFrameTime > 0){ + + if (!is_blacklisted() && fps_limit_stats.targetFrameTime > 0){ fps_limit_stats.frameStart = os_time_get_nano(); FpsLimiter(fps_limit_stats); fps_limit_stats.frameEnd = os_time_get_nano(); @@ -117,10 +126,11 @@ EXPORT_C_(void) glXSwapIntervalEXT(void *dpy, void *draw, int interval) { #ifndef NDEBUG std::cerr << __func__ << ": " << interval << std::endl; #endif - glx.Load(); - if (params.gl_vsync >= 0) + + if (!is_blacklisted() && params.gl_vsync >= 0) interval = params.gl_vsync; + glx.SwapIntervalEXT(dpy, draw, interval); } @@ -129,8 +139,10 @@ EXPORT_C_(int) glXSwapIntervalSGI(int interval) { std::cerr << __func__ << ": " << interval << std::endl; #endif glx.Load(); - if (params.gl_vsync >= 0) + + if (!is_blacklisted() && params.gl_vsync >= 0) interval = params.gl_vsync; + return glx.SwapIntervalSGI(interval); } @@ -139,21 +151,26 @@ EXPORT_C_(int) glXSwapIntervalMESA(unsigned int interval) { std::cerr << __func__ << ": " << interval << std::endl; #endif glx.Load(); - if (params.gl_vsync >= 0) + + if (!is_blacklisted() && params.gl_vsync >= 0) interval = (unsigned int)params.gl_vsync; + return glx.SwapIntervalMESA(interval); } EXPORT_C_(int) glXGetSwapIntervalMESA() { glx.Load(); - static bool first_call = true; int interval = glx.GetSwapIntervalMESA(); - if (first_call) { - first_call = false; - if (params.gl_vsync >= 0) { - interval = params.gl_vsync; - glx.SwapIntervalMESA(interval); + if (!is_blacklisted()) { + static bool first_call = true; + + if (first_call) { + first_call = false; + if (params.gl_vsync >= 0) { + interval = params.gl_vsync; + glx.SwapIntervalMESA(interval); + } } } @@ -185,6 +202,9 @@ static std::array name_to_funcptr_map = {{ void *find_glx_ptr(const char *name) { + if (is_blacklisted()) + return nullptr; + for (auto& func : name_to_funcptr_map) { if (strcmp(name, func.name) == 0) return func.ptr; diff --git a/src/meson.build b/src/meson.build index a769d143..f00cf59d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -42,6 +42,7 @@ vklayer_files = files( 'overlay.cpp', 'overlay_params.cpp', 'font_unispace.c', + 'blacklist.cpp', 'cpu.cpp', 'loaders/loader_nvml.cpp', 'nvml.cpp', @@ -62,7 +63,9 @@ opengl_files = files( 'gl/inject_egl.cpp', ) -pre_args += '-DHOOK_DLSYM' +if get_option('with_dlsym').enabled() + pre_args += '-DHOOK_DLSYM' +endif if get_option('with_xnvctrl').enabled() diff --git a/src/overlay.cpp b/src/overlay.cpp index f1a91f96..fbc8d641 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -57,6 +57,7 @@ #include "loaders/loader_nvml.h" #include "memory.h" #include "notify.h" +#include "blacklist.h" #ifdef HAVE_DBUS #include "dbus_info.h" @@ -816,7 +817,10 @@ void init_gpu_stats(uint32_t& vendorID, overlay_params& params) } void init_system_info(){ - unsetenv("LD_PRELOAD"); + const char* ld_preload = getenv("LD_PRELOAD"); + if (ld_preload) + unsetenv("LD_PRELOAD"); + ram = exec("cat /proc/meminfo | grep 'MemTotal' | awk '{print $2}'"); trim(ram); cpu = exec("cat /proc/cpuinfo | grep 'model name' | tail -n1 | sed 's/^.*: //' | sed 's/([^)]*)/()/g' | tr -d '(/)'"); @@ -832,6 +836,8 @@ void init_system_info(){ trim(driver); //driver = itox(device_data->properties.driverVersion); + if (ld_preload) + setenv("LD_PRELOAD", ld_preload, 1); #ifndef NDEBUG std::cout << "Ram:" << ram << "\n" << "Cpu:" << cpu << "\n" @@ -2503,10 +2509,12 @@ static VkResult overlay_CreateDevice( get_device_chain_info(pCreateInfo, VK_LOADER_DATA_CALLBACK); device_data->set_device_loader_data = load_data_info->u.pfnSetDeviceLoaderData; - device_map_queues(device_data, pCreateInfo); + if (!is_blacklisted()) { + device_map_queues(device_data, pCreateInfo); - init_gpu_stats(device_data->properties.vendorID, instance_data->params); - init_system_info(); + init_gpu_stats(device_data->properties.vendorID, instance_data->params); + init_system_info(); + } return result; } @@ -2516,7 +2524,8 @@ static void overlay_DestroyDevice( const VkAllocationCallbacks* pAllocator) { struct device_data *device_data = FIND(struct device_data, device); - device_unmap_queues(device_data); + if (!is_blacklisted()) + device_unmap_queues(device_data); device_data->vtable.DestroyDevice(device, pAllocator); destroy_device_data(device_data); } @@ -2531,21 +2540,23 @@ static VkResult overlay_CreateInstance( std::string engineName, engineVersion; - const char* pEngineName = nullptr; - if (pCreateInfo->pApplicationInfo) - pEngineName = pCreateInfo->pApplicationInfo->pEngineName; - if (pEngineName) - engineName = pEngineName; - if (engineName == "DXVK" || engineName == "vkd3d") { - int engineVer = pCreateInfo->pApplicationInfo->engineVersion; - engineVersion = to_string(VK_VERSION_MAJOR(engineVer)) + "." + to_string(VK_VERSION_MINOR(engineVer)) + "." + to_string(VK_VERSION_PATCH(engineVer)); - } + if (!is_blacklisted()) { + const char* pEngineName = nullptr; + if (pCreateInfo->pApplicationInfo) + pEngineName = pCreateInfo->pApplicationInfo->pEngineName; + if (pEngineName) + engineName = pEngineName; + if (engineName == "DXVK" || engineName == "vkd3d") { + int engineVer = pCreateInfo->pApplicationInfo->engineVersion; + engineVersion = to_string(VK_VERSION_MAJOR(engineVer)) + "." + to_string(VK_VERSION_MINOR(engineVer)) + "." + to_string(VK_VERSION_PATCH(engineVer)); + } - if (engineName != "DXVK" && engineName != "vkd3d" && engineName != "Feral3D") - engineName = "VULKAN"; + if (engineName != "DXVK" && engineName != "vkd3d" && engineName != "Feral3D") + engineName = "VULKAN"; - if (engineName == "vkd3d") - engineName = "VKD3D"; + if (engineName == "vkd3d") + engineName = "VKD3D"; + } assert(chain_info->u.pLayerInfo); PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = @@ -2568,23 +2579,25 @@ static VkResult overlay_CreateInstance( &instance_data->vtable); instance_data_map_physical_devices(instance_data, true); - parse_overlay_config(&instance_data->params, getenv("MANGOHUD_CONFIG")); - instance_data->notifier.params = &instance_data->params; - start_notifier(instance_data->notifier); + if (!is_blacklisted()) { + parse_overlay_config(&instance_data->params, getenv("MANGOHUD_CONFIG")); + instance_data->notifier.params = &instance_data->params; + start_notifier(instance_data->notifier); - init_cpu_stats(instance_data->params); + init_cpu_stats(instance_data->params); - // Adjust height for DXVK/VKD3D version number - if (engineName == "DXVK" || engineName == "VKD3D"){ - if (instance_data->params.font_size){ - instance_data->params.height += instance_data->params.font_size / 2; - } else { - instance_data->params.height += 24 / 2; + // Adjust height for DXVK/VKD3D version number + if (engineName == "DXVK" || engineName == "VKD3D"){ + if (instance_data->params.font_size){ + instance_data->params.height += instance_data->params.font_size / 2; + } else { + instance_data->params.height += 24 / 2; + } } - } - instance_data->engineName = engineName; - instance_data->engineVersion = engineVersion; + instance_data->engineName = engineName; + instance_data->engineVersion = engineVersion; + } return result; } @@ -2596,7 +2609,8 @@ static void overlay_DestroyInstance( struct instance_data *instance_data = FIND(struct instance_data, instance); instance_data_map_physical_devices(instance_data, false); instance_data->vtable.DestroyInstance(instance, pAllocator); - stop_notifier(instance_data->notifier); + if (!is_blacklisted()) + stop_notifier(instance_data->notifier); destroy_instance_data(instance_data); } @@ -2630,42 +2644,11 @@ static const struct { #undef ADD_HOOK }; -static bool checkBlacklisted() -{ - std::vector blacklist { - "Battle.net.exe", - "EpicGamesLauncher.exe", - "IGOProxy.exe", - "IGOProxy64.exe", - "Origin.exe", - "OriginThinSetupInternal.exe", - "Steam.exe", - "BethesdaNetLauncher.exe", - }; - -#ifdef _GNU_SOURCE_OFF - std::string p(program_invocation_name); - std::string procName = p.substr(p.find_last_of("/\\") + 1); -#else - std::string p = get_exe_path(); - std::string procName; - if (ends_with(p, "wine-preloader") || ends_with(p, "wine64-preloader")) { - get_wine_exe_name(procName, true); - } else { - procName = p.substr(p.find_last_of("/\\") + 1); - } -#endif - - return std::find(blacklist.begin(), blacklist.end(), procName) != blacklist.end(); -} - -static bool isBlacklisted = checkBlacklisted(); - static void *find_ptr(const char *name) { std::string f(name); - if (isBlacklisted && (f != "vkCreateInstance" && f != "vkDestroyInstance" && f != "vkCreateDevice" && f != "vkDestroyDevice")) + if (is_blacklisted() && (f != "vkCreateInstance" && f != "vkDestroyInstance" && f != "vkCreateDevice" && f != "vkDestroyDevice")) { return NULL; }