diff --git a/control/src/control/__init__.py b/control/src/control/__init__.py index db1bae389b..512c17452f 100644 --- a/control/src/control/__init__.py +++ b/control/src/control/__init__.py @@ -202,6 +202,9 @@ def control(args): conn.send(bytearray(':hud;', 'utf-8')) elif args.cmd == 'toggle-fcat': conn.send(bytearray(':fcat;', 'utf-8')) + elif args.cmd == 'set-fps-limit': + msg = ':set_fps_limit={};'.format(args.fps) + conn.send(bytearray(msg, 'utf-8')) def main(): parser = argparse.ArgumentParser(description='MangoHud control client') @@ -214,6 +217,8 @@ def main(): commands.add_parser('start-logging') commands.add_parser('stop-logging') commands.add_parser('toggle-fcat') + set_fps_limit_parser = commands.add_parser('set-fps-limit') + set_fps_limit_parser.add_argument('fps', type=float, help='FPS limit value (0 for unlimited)') args = parser.parse_args() diff --git a/src/app/main.cpp b/src/app/main.cpp index 2dbed1a12d..48b052400b 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -386,7 +386,7 @@ int main(int, char**) // Main loop while (!glfwWindowShouldClose(window)){ real_params = get_params(); - check_keybinds(*real_params); + check_keybinds(*real_params, &control_client); if (!real_params->no_display && new_frame){ if (mangoapp_paused){ glfwShowWindow(window); diff --git a/src/control.cpp b/src/control.cpp index 9d99708981..457ab1a5f3 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -7,6 +7,7 @@ #include "overlay.h" #include "version.h" #include "app/mangoapp.h" +#include "fps_limiter.h" int global_control_client; @@ -35,6 +36,13 @@ static void parse_command(overlay_params ¶ms, } } else if (!strncmp(cmd, "fcat", cmdlen)) { params.enabled[OVERLAY_PARAM_ENABLED_fcat] = !params.enabled[OVERLAY_PARAM_ENABLED_fcat]; + } else if (!strncmp(cmd, "set_fps_limit", cmdlen)) { + if (param && param[0] && fps_limiter) { + char *endptr; + float fps = strtof(param, &endptr); + if (endptr != param && fps >= 0) + fps_limiter->set_target(fps); + } } } diff --git a/src/fps_limiter.h b/src/fps_limiter.h index 509d20acef..d300d33694 100644 --- a/src/fps_limiter.h +++ b/src/fps_limiter.h @@ -73,14 +73,16 @@ class fpsLimiter { return; fps_limits_idx = (fps_limits_idx + 1) % v.size(); - auto next_target = v[fps_limits_idx]; - target = next_target <= 0.0f ? 0 : int64_t(1'000'000'000.0f / next_target); - SPDLOG_DEBUG("Changed fps limit to {}", next_target); + set_target(v[fps_limits_idx]); + SPDLOG_DEBUG("Changed fps limit to {}", v[fps_limits_idx]); + } + + void set_target(float fps) { + target = fps <= 0.0f ? 0 : int64_t(1'000'000'000.0f / fps); } int current_limit() { - auto& v = get_params()->fps_limit; - return v[fps_limits_idx]; + return target > 0 ? int(1'000'000'000.0f / target) : 0; } }; diff --git a/src/gl/gl_hud.cpp b/src/gl/gl_hud.cpp index 2ef688dbb7..0798f11a46 100644 --- a/src/gl/gl_hud.cpp +++ b/src/gl/gl_hud.cpp @@ -213,7 +213,7 @@ void imgui_render(gl_context *ctx, unsigned int width, unsigned int height) process_control_socket(control_client, params); } - check_keybinds(params); + check_keybinds(params, &control_client); update_hud_info(sw_stats, params, vendorID); auto saved_imgui_contexts = get_current_imgui_contexts(); diff --git a/src/keybinds.cpp b/src/keybinds.cpp index 28b4f55577..61a7158418 100644 --- a/src/keybinds.cpp +++ b/src/keybinds.cpp @@ -10,10 +10,11 @@ #include "keybinds.h" #include "fps_metrics.h" #include "fps_limiter.h" +#include "mesa/util/os_socket.h" Clock::time_point last_f2_press, toggle_fps_limit_press, toggle_preset_press, last_f12_press, reload_cfg_press, last_upload_press; -void check_keybinds(struct overlay_params& params){ +void check_keybinds(struct overlay_params& params, int* control_client){ auto real_params = get_params(); using namespace std::chrono_literals; auto now = Clock::now(); /* us */ @@ -55,7 +56,7 @@ void check_keybinds(struct overlay_params& params){ for (size_t i = 0; i < size; i++){ if(real_params->preset[i] == current_preset) { current_preset = real_params->preset[++i%size]; - parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG"), true); + parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG"), true, control_client); break; } } @@ -69,7 +70,7 @@ void check_keybinds(struct overlay_params& params){ if (elapsedReloadCfg >= keyPressDelay && keys_are_pressed(real_params->reload_cfg)) { - parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG"), false); + parse_overlay_config(¶ms, getenv("MANGOHUD_CONFIG"), false, control_client); reload_cfg_press = now; } diff --git a/src/overlay.h b/src/overlay.h index cad97c27bd..c201be6056 100644 --- a/src/overlay.h +++ b/src/overlay.h @@ -160,7 +160,7 @@ void update_hud_info(struct swapchain_stats& sw_stats, const struct overlay_para void update_hud_info_with_frametime(struct swapchain_stats& sw_stats, const struct overlay_params& params, uint32_t vendorID, uint64_t frametime_ns); void update_hw_info(const struct overlay_params& params, uint32_t vendorID); void init_cpu_stats(overlay_params& params); -void check_keybinds(overlay_params& params); +void check_keybinds(overlay_params& params, int* control_client = nullptr); void init_system_info(void); void check_for_vkbasalt_and_gamemode(); void create_fonts(ImFontAtlas* font_atlas, const overlay_params& params, ImFont*& small_font, ImFont*& text_font, ImFont*& secondary_font); diff --git a/src/overlay_params.cpp b/src/overlay_params.cpp index 6a5dbb8784..103c588a78 100644 --- a/src/overlay_params.cpp +++ b/src/overlay_params.cpp @@ -925,12 +925,15 @@ static std::string verify_pci_dev(std::string pci_dev) { void parse_overlay_config(struct overlay_params *params, - const char *env, bool use_existing_preset) + const char *env, bool use_existing_preset, int* control_client) { SPDLOG_DEBUG("Version: {}", MANGOHUD_VERSION); std::vector default_preset = {-1, 0, 1, 2, 3, 4}; auto preset = std::move(params->preset); int transfer_function = params->transfer_function; + // Save old control socket info for comparison (don't close yet - we may reuse it!) + int old_control_fd = params->control; + std::string old_control_path = params->control_path; *params = {}; params->transfer_function = transfer_function; params->preset = use_existing_preset ? std::move(preset) : default_preset; @@ -1010,6 +1013,34 @@ parse_overlay_config(struct overlay_params *params, parse_overlay_env(params, env, true); } + // Resolve the new control path (empty if control option absent) + std::string new_control_path; + auto control_it = params->options.find("control"); + if (control_it != params->options.end()) { + new_control_path = control_it->second; + size_t npos = new_control_path.find("%p"); + if (npos != std::string::npos) + new_control_path.replace(npos, 2, std::to_string(getpid())); + } + + bool reuse = old_control_fd >= 0 + && new_control_path == old_control_path; + + if (reuse) { + if (params->control >= 0 && params->control != old_control_fd) + os_socket_close(params->control); + params->control = old_control_fd; + } else { + if (old_control_fd >= 0) + os_socket_close(old_control_fd); + if (control_client && *control_client >= 0) { + os_socket_close(*control_client); + *control_client = -1; + } + } + + params->control_path = new_control_path; + // If fps_only param is enabled disable legacy_layout if (params->enabled[OVERLAY_PARAM_ENABLED_fps_only]) params->enabled[OVERLAY_PARAM_ENABLED_legacy_layout] = false; diff --git a/src/overlay_params.h b/src/overlay_params.h index e1c2b40436..a25f8d501b 100644 --- a/src/overlay_params.h +++ b/src/overlay_params.h @@ -287,6 +287,7 @@ struct overlay_params { bool enabled[OVERLAY_PARAM_ENABLED_MAX]; enum overlay_param_position position; int control; + std::string control_path; uint32_t fps_sampling_period; /* ns */ std::vector fps_limit; enum fps_limit_method fps_limit_method; @@ -393,7 +394,7 @@ struct overlay_params { const extern char *overlay_param_names[]; void parse_overlay_config(struct overlay_params *params, - const char *env, bool ignore_preset); + const char *env, bool ignore_preset, int* control_client = nullptr); void presets(int preset, struct overlay_params *params, bool inherit=false); bool parse_preset_config(int preset, struct overlay_params *params); void add_to_options(struct overlay_params *params, std::string option, std::string value); diff --git a/src/vulkan.cpp b/src/vulkan.cpp index ffadf255ac..29f797f9a7 100644 --- a/src/vulkan.cpp +++ b/src/vulkan.cpp @@ -471,7 +471,7 @@ static void snapshot_swapchain_frame(struct swapchain_data *data) struct device_data *device_data = data->device; struct instance_data *instance_data = device_data->instance; update_hud_info(data->sw_stats, instance_data->params, device_data->properties.vendorID); - check_keybinds(instance_data->params); + check_keybinds(instance_data->params, &instance_data->control_client); #ifdef __linux__ if (instance_data->params.control >= 0) { control_client_check(instance_data->params.control, instance_data->control_client, gpu.c_str());