From 3b90ba2c1b40debf5a9616bc43dcf8e109f2309a Mon Sep 17 00:00:00 2001 From: daiqingshuang Date: Mon, 8 Dec 2025 17:54:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=E7=9B=AE=E6=A0=87?= =?UTF-8?q?=E5=B8=A7=E7=8E=87=E9=85=8D=E7=BD=AE=E4=B8=BA=E5=8F=AF=E9=80=89?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E4=BD=BF=E7=94=A8=E5=B1=8F=E5=B9=95?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E7=8E=87=EF=BC=8C=E4=BC=98=E5=8C=96=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E7=BA=BF=E7=A8=8B=E8=B6=85=E6=97=B6=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/test_thread/main.cpp | 3 +-- src/app/application.cpp | 29 +++++++++++++++++++++++------ src/app/application.h | 2 +- src/app/threading/render_thread.cpp | 8 ++++---- src/app/threading/render_thread.h | 8 ++++---- 5 files changed, 33 insertions(+), 17 deletions(-) diff --git a/example/test_thread/main.cpp b/example/test_thread/main.cpp index d0d163b..a5c05b3 100644 --- a/example/test_thread/main.cpp +++ b/example/test_thread/main.cpp @@ -17,9 +17,8 @@ int main(int argc, char* argv[]) { config.width = 800; config.height = 600; config.enable_multithreading = true; - config.target_fps = 60; config.enable_validation = true; - config.vsync = false; + config.vsync = true; if (!app.initialize(config)) { return -1; diff --git a/src/app/application.cpp b/src/app/application.cpp index 189e2f1..d176e94 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -38,9 +38,8 @@ namespace mirage::app { return false; } - config_ = config; - target_frame_time_ = 1.0f / static_cast(config.target_fps); - + config_ = config; + // ======================================================================== // 1. 创建窗口管理器和窗口 // ======================================================================== @@ -240,7 +239,7 @@ namespace mirage::app { // ======================================================================== coordinator_ = std::make_unique(*render_pipeline_, *state_store_, *widget_context_); - + // 启动线程协调器 threading::coordinator_config coord_config{}; coord_config.enable_multithreading = config.enable_multithreading; @@ -249,9 +248,23 @@ namespace mirage::app { // 配置渲染参数 coord_config.render_cfg.vsync_enabled = config.vsync; - coord_config.render_cfg.target_fps = config.target_fps; coord_config.render_cfg.triple_buffering = config.triple_buffering; coord_config.render_cfg.adaptive_sync = config.adaptive_sync; + + // 如果没有设置目标帧率,则使用窗口所在屏幕的刷新率 + int effective_fps; + if (!config.target_fps.has_value()) { + auto monitor = window_->get_current_monitor(); + coord_config.render_cfg.target_fps = monitor.refresh_rate; + effective_fps = monitor.refresh_rate; + std::cout << "[application] Using monitor refresh rate: " << monitor.refresh_rate << " Hz" << std::endl; + } else { + coord_config.render_cfg.target_fps = config.target_fps; + effective_fps = config.target_fps.value(); + } + + // 设置主循环的目标帧时间 + target_frame_time_ = 1.0f / static_cast(effective_fps); coordinator_->start(coord_config); @@ -266,7 +279,11 @@ namespace mirage::app { std::cout << " - Window: " << current_width_ << "x" << current_height_ << std::endl; std::cout << " - Present Mode: " << get_present_mode_string() << std::endl; std::cout << " - Multithreading: " << (config.enable_multithreading ? "enabled" : "disabled") << std::endl; - std::cout << " - Target FPS: " << config.target_fps << std::endl; + if (config.target_fps.has_value()) { + std::cout << " - Target FPS: " << config.target_fps.value() << std::endl; + } else { + std::cout << " - Target FPS: Auto (using monitor refresh rate)" << std::endl; + } return true; } diff --git a/src/app/application.h b/src/app/application.h index 37915f6..c475378 100644 --- a/src/app/application.h +++ b/src/app/application.h @@ -53,7 +53,7 @@ struct application_config { bool resizable = true; ///< 是否可调整大小 bool vsync = true; ///< 是否启用垂直同步 bool enable_multithreading = true; ///< 是否启用多线程渲染 - int target_fps = 60; ///< 目标帧率 + std::optional target_fps; ///< 目标帧率(std::nullopt 表示使用屏幕刷新率) bool enable_validation = true; ///< 是否启用 Vulkan 验证层 bool adaptive_sync = false; ///< 是否启用自适应同步(VRR) bool triple_buffering = true; ///< 是否启用三缓冲 diff --git a/src/app/threading/render_thread.cpp b/src/app/threading/render_thread.cpp index bf00f83..525b1a7 100644 --- a/src/app/threading/render_thread.cpp +++ b/src/app/threading/render_thread.cpp @@ -140,8 +140,8 @@ void render_thread::thread_main(std::stop_token stop_token) { // 根据目标帧率计算合理的超时时间 // 使用目标帧时间的一半作为超时,在响应性和CPU使用率之间取得平衡 - if (current_config.target_fps > 0) { - int timeout_ms = std::max(8, 1000 / (current_config.target_fps * 2)); + if (current_config.target_fps.has_value() && current_config.target_fps.value() > 0) { + int timeout_ms = std::max(8, 1000 / (current_config.target_fps.value() * 2)); return std::chrono::milliseconds(timeout_ms); } // 默认 8ms 超时(适合 120fps+) @@ -236,9 +236,9 @@ void render_thread::wait_for_vsync() { // 如果启用了 VSync,Vulkan 的 present 会自动等待 // 这里只处理非 VSync 模式下的帧率限制 - if (!current_config.vsync_enabled && current_config.target_fps > 0) { + if (!current_config.vsync_enabled && current_config.target_fps.has_value() && current_config.target_fps.value() > 0) { // 计算目标帧时间 - double target_frame_time_ms = 1000.0 / current_config.target_fps; + double target_frame_time_ms = 1000.0 / current_config.target_fps.value(); // 计算已经过去的时间 auto now = std::chrono::steady_clock::now(); diff --git a/src/app/threading/render_thread.h b/src/app/threading/render_thread.h index 7f496ac..4e3d14b 100644 --- a/src/app/threading/render_thread.h +++ b/src/app/threading/render_thread.h @@ -35,10 +35,10 @@ namespace mirage::app::threading { /// /// 控制渲染线程的行为参数 struct render_config { - bool vsync_enabled = true; ///< 是否启用垂直同步 - int target_fps = 60; ///< 目标帧率(当 vsync 禁用时使用) - bool triple_buffering = true; ///< 是否启用三缓冲 - bool adaptive_sync = false; ///< 是否启用自适应同步 + bool vsync_enabled = true; ///< 是否启用垂直同步 + std::optional target_fps; ///< 目标帧率(std::nullopt 表示使用屏幕刷新率,当 vsync 禁用时使用) + bool triple_buffering = true; ///< 是否启用三缓冲 + bool adaptive_sync = false; ///< 是否启用自适应同步 }; // ============================================================================