From 4dbabbd1fa98295194f5050edd23aa967ea880c4 Mon Sep 17 00:00:00 2001 From: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com> Date: Thu, 9 Apr 2026 00:24:23 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E8=A7=A3=E6=9E=90=20VDD=20?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E7=AE=A1=E9=81=93=E6=96=B0=E5=93=8D=E5=BA=94?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=EF=BC=8C=E4=BC=98=E5=8C=96=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E7=AD=89=E5=BE=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/display_device/vdd_utils.cpp | 29 ++++++++++++++++++++++++----- src/display_device/vdd_utils.h | 2 +- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/display_device/vdd_utils.cpp b/src/display_device/vdd_utils.cpp index 0b0f79b3de8..b0bcd6ed335 100644 --- a/src/display_device/vdd_utils.cpp +++ b/src/display_device/vdd_utils.cpp @@ -141,7 +141,7 @@ namespace display_device { } bool - execute_pipe_command(const wchar_t *pipe_name, const wchar_t *command, std::string *response, bool *timed_out) { + execute_pipe_command(const wchar_t *pipe_name, const wchar_t *command, std::string *response, bool *timed_out, DWORD read_timeout_ms) { auto hPipe = connect_to_pipe_with_retry(pipe_name); if (hPipe == INVALID_HANDLE_VALUE) { BOOST_LOG(error) << "连接MTT虚拟显示管道失败,已重试多次"; @@ -180,6 +180,7 @@ namespace display_device { } // 读取响应 + const DWORD effective_read_timeout = (read_timeout_ms > 0) ? read_timeout_ms : kPipeTimeoutMs; bool read_timed_out = false; if (response) { char buffer[kPipeBufferSize]; @@ -190,7 +191,7 @@ namespace display_device { return false; } - DWORD waitResult = WaitForSingleObject(overlapped.hEvent, kPipeTimeoutMs); + DWORD waitResult = WaitForSingleObject(overlapped.hEvent, effective_read_timeout); if (waitResult == WAIT_OBJECT_0 && GetOverlappedResult(hPipe, &overlapped, &bytesRead, FALSE)) { buffer[bytesRead] = '\0'; *response = std::string(buffer, bytesRead); @@ -322,14 +323,16 @@ namespace display_device { } // 尝试发送命令(带GUID或不带GUID) + // 使用更长的读取超时,因为新版驱动会在管道中等待CCD系统就绪 + constexpr DWORD kCreateMonitorReadTimeoutMs = 20000; bool read_timed_out = false; - bool success = execute_pipe_command(kVddPipeName, command.c_str(), &response, &read_timed_out); + bool success = execute_pipe_command(kVddPipeName, command.c_str(), &response, &read_timed_out, kCreateMonitorReadTimeoutMs); // 如果带GUID的命令失败,降级为不带GUID的命令(兼容旧版驱动) if (!success && !guid_str.empty()) { BOOST_LOG(warning) << "带GUID的命令失败,尝试降级为不带GUID的命令"; read_timed_out = false; - success = execute_pipe_command(kVddPipeName, L"CREATEMONITOR", &response, &read_timed_out); + success = execute_pipe_command(kVddPipeName, L"CREATEMONITOR", &response, &read_timed_out, kCreateMonitorReadTimeoutMs); } if (!success) { @@ -340,7 +343,23 @@ namespace display_device { #if defined SUNSHINE_TRAY && SUNSHINE_TRAY >= 1 system_tray::update_vdd_menu(); #endif - BOOST_LOG(info) << "创建虚拟显示器完成,响应: " << response << " [return=" << (read_timed_out ? 1 : 0) << "]"; + + // 解析驱动响应:OK = CCD已就绪, OK_PENDING = 创建成功但CCD未就绪, FAIL = 创建失败 + if (response == "FAIL") { + BOOST_LOG(error) << "驱动端报告虚拟显示器创建失败"; + return false; + } + + if (response == "OK") { + BOOST_LOG(info) << "创建虚拟显示器完成,驱动确认CCD已就绪"; + } + else if (response == "OK_PENDING") { + BOOST_LOG(warning) << "创建虚拟显示器完成,但CCD系统尚未就绪(驱动等待超时)"; + } + else { + // 旧版驱动不返回响应(read_timed_out=true),视为成功 + BOOST_LOG(info) << "创建虚拟显示器完成,响应: " << response << " [return=" << (read_timed_out ? 1 : 0) << "]"; + } return true; } diff --git a/src/display_device/vdd_utils.h b/src/display_device/vdd_utils.h index a91939cf3d2..08369c66d78 100644 --- a/src/display_device/vdd_utils.h +++ b/src/display_device/vdd_utils.h @@ -67,7 +67,7 @@ namespace display_device::vdd_utils { connect_to_pipe_with_retry(const wchar_t *pipe_name, int max_retries = 3); bool - execute_pipe_command(const wchar_t *pipe_name, const wchar_t *command, std::string *response = nullptr, bool *timed_out = nullptr); + execute_pipe_command(const wchar_t *pipe_name, const wchar_t *command, std::string *response = nullptr, bool *timed_out = nullptr, DWORD read_timeout_ms = 0); // 驱动重载函数 bool From c9364cc7dd1f6f55b79324ee046851327aa339be Mon Sep 17 00:00:00 2001 From: ShadowLemoon <119576779+ShadowLemoon@users.noreply.github.com> Date: Thu, 9 Apr 2026 16:35:38 +0800 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20=E4=B8=A4=E4=B8=AA=E8=B0=83=E7=94=A8?= =?UTF-8?q?=E7=82=B9=E6=A3=80=E6=9F=A5=E9=A9=B1=E5=8A=A8=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E5=80=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/display_device/session.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/display_device/session.cpp b/src/display_device/session.cpp index af66232a7ff..a1392149724 100644 --- a/src/display_device/session.cpp +++ b/src/display_device/session.cpp @@ -509,8 +509,17 @@ namespace display_device { const std::string vdd_identifier = config::video.vdd_reuse ? "shared_vdd" // 固定标识符,所有客户端共用同一GUID : current_client_id; // 为每个客户端生成不同GUID - vdd_utils::create_vdd_monitor(vdd_identifier, hdr_brightness, physical_size); - std::this_thread::sleep_for(200ms); + if (!vdd_utils::create_vdd_monitor(vdd_identifier, hdr_brightness, physical_size)) { + BOOST_LOG(error) << "创建虚拟显示器失败(驱动报告错误),尝试恢复"; + if (!try_recover_vdd_device(current_client_id, session.client_name, hdr_brightness, device_zako)) { + BOOST_LOG(error) << "VDD设备最终初始化失败"; + vdd_utils::disable_enable_vdd(); + return; + } + } + else { + std::this_thread::sleep_for(200ms); + } } // Wait for device to be ready @@ -622,11 +631,15 @@ namespace display_device { auto devices = display_device::enum_available_devices(); if (devices.empty()) { BOOST_LOG(info) << "无头主机检测:未找到显示设备,自动创建基地显示器"; - create_vdd_monitor(""); - constexpr int max_attempts = 5; - constexpr auto wait_time = std::chrono::milliseconds(233); - for (int i = 0; i < max_attempts && !is_display_on(); ++i) { - std::this_thread::sleep_for(wait_time); + if (!create_vdd_monitor("")) { + BOOST_LOG(error) << "无头主机自动创建显示器失败"; + } + else { + constexpr int max_attempts = 5; + constexpr auto wait_time = std::chrono::milliseconds(233); + for (int i = 0; i < max_attempts && !is_display_on(); ++i) { + std::this_thread::sleep_for(wait_time); + } } } }