fix(vdd): VDD拓扑范围限定 + 延迟销毁机制,修复首次连接失败和切换应用GUID失效#527
Open
fix(vdd): VDD拓扑范围限定 + 延迟销毁机制,修复首次连接失败和切换应用GUID失效#527
Conversation
There was a problem hiding this comment.
Pull request overview
该 PR 修复 Windows 下 VDD 模式首次连接串流失败的问题:在仅需要操作 VDD 的场景中,避免对整个系统拓扑(物理+VDD)进行显示模式/HDR 设置,从而规避物理显示器在 VDD 创建后短暂不稳定导致的失败。
Changes:
- VDD 模式下
get_current_topology_metadata()仅向 metadata 暴露包含 VDD 的拓扑组,限制后续模式/HDR 操作范围。 wait_for_display_stability()改为对设备集合做 subset 检查,并仅查询 metadata 相关设备的当前显示模式。
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/platform/windows/display_device/settings_topology.cpp | VDD 模式下构造 vdd-only 的 metadata.current_topology,避免对物理显示器做模式/HDR 查询与设置 |
| src/platform/windows/display_device/settings.cpp | 稳定性等待逻辑改为 subset 判断,并限制显示模式查询范围到 metadata 设备集合 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+459
to
478
| // VDD模式:构建仅包含VDD设备所在组的拓扑用于 metadata | ||
| // 这样 handle_display_mode_configuration 和 handle_hdr_state_configuration | ||
| // 只会查询/设置VDD相关设备的模式,不会因为物理显示器状态不稳定而失败 | ||
| active_topology_t vdd_only_topology; | ||
| for (const auto &group : current_topology) { | ||
| for (const auto &id : group) { | ||
| if (id == requested_device_id) { | ||
| vdd_only_topology.push_back(group); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return handled_topology_result_t { | ||
| topology_pair_t { | ||
| current_topology, | ||
| current_topology }, | ||
| topology_metadata_t { | ||
| current_topology, | ||
| vdd_only_topology, | ||
| {}, // 没有新启用的设备 |
Comment on lines
+327
to
+329
| const auto current_device_ids = get_device_ids_from_topology(current_topology); | ||
| bool topology_stable = std::all_of(metadata_device_ids.begin(), metadata_device_ids.end(), | ||
| [¤t_device_ids](const std::string &id) { return current_device_ids.count(id) > 0; }); |
There was a problem hiding this comment.
Pull request overview
该 PR 聚焦于 Windows 下 VDD 模式的显示设置稳定性:将显示模式/HDR 等操作限定在 VDD 相关设备范围内,并在使用持久化数据前过滤已销毁设备的陈旧 GUID,避免首次连接/快速重连时因对不存在设备下发配置而失败。
Changes:
- VDD 模式下
metadata.current_topology改为仅包含 VDD 所在拓扑组,避免对物理显示器做不必要的模式/HDR 操作 - 引入对持久化显示模式/HDR/主屏 GUID 的“陈旧设备”过滤逻辑,防止对已销毁 VDD 设备下发设置
- 调整稳定性等待逻辑:VDD 模式下拓扑对比改为 subset 检查,并按 metadata 范围查询当前模式
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/platform/windows/display_device/settings_topology.cpp | VDD 模式下构建仅含 VDD 组的 topology metadata,限制后续模式/HDR 操作范围 |
| src/platform/windows/display_device/settings.cpp | 新增过滤陈旧设备条目逻辑,并在模式/HDR/主屏处理入口使用;更新稳定性等待的拓扑比较与模式查询范围 |
| src/display_device/session.cpp | 在 no_operation 恢复路径中增加对持久化数据的清理调用,避免旧 VDD GUID 影响后续会话 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/display_device/session.cpp
Outdated
| // 避免下一次 Launch 创建新 VDD 时,apply_config 使用旧 VDD 的 GUID | ||
| if (settings.has_persistent_data()) { | ||
| BOOST_LOG(info) << "清理残留的显示设备持久化数据(VDD 已销毁/重建后 GUID 会变化)"; | ||
| settings.reset_persistence(); |
Comment on lines
+462
to
+469
| active_topology_t vdd_only_topology; | ||
| for (const auto &group : current_topology) { | ||
| for (const auto &id : group) { | ||
| if (id == requested_device_id) { | ||
| vdd_only_topology.push_back(group); | ||
| break; | ||
| } | ||
| } |
Comment on lines
+67
to
+88
| template <typename T> | ||
| size_t | ||
| remove_stale_device_entries(std::unordered_map<std::string, T> &device_map) { | ||
| if (device_map.empty()) { | ||
| return 0; | ||
| } | ||
|
|
||
| const auto available_devices { enum_available_devices() }; | ||
| size_t removed { 0 }; | ||
| for (auto it = device_map.begin(); it != device_map.end();) { | ||
| if (available_devices.find(it->first) == available_devices.end()) { | ||
| BOOST_LOG(debug) << "Removing stale device entry (device no longer exists): " << it->first; | ||
| it = device_map.erase(it); | ||
| ++removed; | ||
| } | ||
| else { | ||
| ++it; | ||
| } | ||
| } | ||
|
|
||
| return removed; | ||
| } |
4ca6a24 to
8de6e0f
Compare
在 dff5a72 的重构中,VDD 模式下 apply_config 不再跳过显示设置, 但 get_current_topology_metadata 返回了整个系统拓扑(物理+VDD), 导致 handle_display_mode_configuration 尝试对所有设备(包括可能不稳定 的物理显示器)设置分辨率/刷新率,引发 'Failed to find device' 错误。 修复: - get_current_topology_metadata: metadata.current_topology 改为仅包含 VDD 设备所在的拓扑组,不包含无关的物理显示器 - wait_for_display_stability: 拓扑比较改为 subset 检查, 避免 VDD 模式下因部分拓扑不匹配导致无意义的 5 秒超时等待
When Cancel is followed by a quick Launch (app switching), instead of immediately destroying the VDD and restoring topology, defer the entire restore operation with a grace period (5 seconds timer). If a new configure_display arrives within the grace period, the timer is cancelled and the existing VDD is reused — same GUID, same persistent_data, no topology flicker, no stale device entries. If the grace period expires without a new session, the full restore (VDD destruction + topology revert) executes normally. This benefits ALL display modes (not just no_operation) by eliminating unnecessary VDD destroy/recreate cycles during app switching. Also fixes remove_stale_device_entries template to accept std::map (not just std::unordered_map) matching device_display_mode_map_t.
8de6e0f to
5c45d92
Compare
Collaborator
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题
在
dff5a728的重构后,VDD 模式出现两个问题:1. 首次连接失败(物理显示器干扰)
apply_config不再跳过 VDD 模式的显示设置,但get_current_topology_metadata返回了整个系统拓扑(物理+VDD),导致handle_display_mode_configuration尝试对所有设备(包括可能不稳定的物理显示器)设置分辨率/刷新率。当物理显示器设备路径查询失败时,整个流程中断。2. 切换应用时 VDD 陈旧 GUID(Cancel → Launch)
用户切换游戏时,nvhttp Cancel handler 无条件调用
restore_state()销毁 VDD,persistent_data中保留了旧 GUID。紧接着 Launch 创建新 VDD(新 GUID),后续set_display_modes用旧 GUID 查找设备失败。解决方案
Commit 1: VDD 拓扑范围限定
get_current_topology_metadata:metadata.current_topology改为仅包含 VDD 设备所在的拓扑组,不包含无关的物理显示器wait_for_display_stability: 拓扑比较改为 subset 检查,避免 VDD 模式下因部分拓扑不匹配导致 5 秒超时等待Commit 2: 延迟 VDD 销毁(Grace Period)
当 Cancel 触发
restore_state()时,如果 VDD 存在且非常驻模式,不再立即销毁,而是设置 5 秒延迟:vdd_prep不同(例如从ensure_only_display切到no_operation),先执行完整恢复再重新配置,避免 persistent_data 与新模式不匹配附带修复:
remove_stale_device_entries模板参数从std::unordered_map<string,T>改为泛型MapT,兼容device_display_mode_map_t(std::map)。影响范围
所有 VDD 显示模式都受益于延迟销毁,消除了应用切换时不必要的 VDD 销毁/重建循环。
修改文件
session.hdeferred_restore_、deferred_restore_reason_、execute_deferred_restore()session.cpprestore_state_impl拆分为入口+延迟执行;configure_display增加延迟恢复取消/模式变更处理settings.cppremove_stale_device_entries模板泛型化settings_topology.cppget_current_topology_metadata限定为 VDD-only 拓扑