Skip to content

fix(vdd): 避免旋转后恢复串流错误重建虚拟显示器 - #889

Merged
qiin2333 merged 1 commit into
masterfrom
fix_rebuild_vdd
Aug 2, 2026
Merged

fix(vdd): 避免旋转后恢复串流错误重建虚拟显示器#889
qiin2333 merged 1 commit into
masterfrom
fix_rebuild_vdd

Conversation

@Yundi339

@Yundi339 Yundi339 commented Aug 2, 2026

Copy link
Copy Markdown
Member

说明

客户端跟随屏幕旋转后,Windows 会根据当前显示方向交换 VDD 模式的逻辑宽高。恢复串流请求仍使用原始分辨率,原有的精确匹配会将旋转后的等价模式判定为缺失,触发无效重建,并可能导致恢复请求返回 503。

修改

  • 读取 VDD 当前显示方向,仅在 90° 或 270° 时将宽高互换识别为旋转等价模式。
  • 保留刷新率校验;精确匹配和旋转等价匹配均复用现有 VDD,只有模式确实缺失时才重建。
  • 补充旋转等价匹配测试,覆盖未旋转、旋转和刷新率不匹配场景。

该修改不改变客户端协议,也不放宽未旋转状态下的模式匹配。

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Summary by CodeRabbit

  • 新功能
    • 改进显示模式识别,可根据当前显示方向匹配宽高互换的旋转等价分辨率。
    • 保留刷新率校验,提升显示模式匹配的准确性。
  • 测试
    • 新增旋转模式匹配测试,覆盖方向、分辨率及刷新率不匹配等场景。

Walkthrough

新增显示方向辅助函数和广告模式匹配分类器。is_mode_advertised 现在支持精确匹配与方向允许时的旋转等价匹配,并记录旋转方向日志。单元测试覆盖相关分类结果。

Changes

广告显示模式匹配

Layer / File(s) Summary
匹配分类契约
src/display_device/vdd_utils.h, tests/unit/test_vdd_safety.cpp
新增 advertised_mode_match_eclassify_advertised_mode。分类逻辑校验刷新率,并区分精确匹配、旋转等价匹配和不匹配。单元测试覆盖这些情况。
方向识别与发布检查
src/display_device/vdd_utils.cpp
新增显示方向转换和坐标轴交换辅助函数。is_mode_advertised 使用统一分类器,并在旋转等价匹配时记录方向日志。

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • AlkaidLab/foundation-sunshine#833:两者都修改 vdd_utils 的广告显示模式匹配逻辑和单元测试。本次变更扩展了该匹配逻辑以支持方向等价分辨率。

Suggested reviewers: qiin2333

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed 标题准确概括了屏幕旋转后恢复串流时避免错误重建虚拟显示器的主要修复。
Description check ✅ Passed 描述与变更内容一致,说明了旋转等价模式匹配、刷新率校验和新增测试。
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix_rebuild_vdd

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/display_device/vdd_utils.cpp`:
- Around line 817-844: 在 wait_for_mode_publication 的超时返回 false
路径中补充一次诊断日志,记录当前显示方向以及 Windows 实际枚举到的每个模式的宽度、高度和刷新率;复用或扩展 is_mode_advertised
的枚举结果传递方式,确保完整列表只在最终超时时输出一次,而不是每次轮询重复记录。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: aeb748ab-ba6b-4290-8f6b-5576e8dec6cc

📥 Commits

Reviewing files that changed from the base of the PR and between 48d221d and 1ee6f54.

📒 Files selected for processing (3)
  • src/display_device/vdd_utils.cpp
  • src/display_device/vdd_utils.h
  • tests/unit/test_vdd_safety.cpp
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/unit/test_vdd_safety.cpp
  • src/display_device/vdd_utils.h
📜 Review details
🧰 Additional context used
📓 Path-based instructions (1)
src/**/*.{cpp,c,h}

⚙️ CodeRabbit configuration file

src/**/*.{cpp,c,h}: Sunshine 核心 C++ 源码,自托管游戏串流服务器。审查要点:内存安全、 线程安全、RAII 资源管理、安全漏洞。注意预处理宏控制的平台相关代码。

Files:

  • src/display_device/vdd_utils.cpp
🔇 Additional comments (1)
src/display_device/vdd_utils.cpp (1)

58-77: LGTM!

Comment on lines +817 to +844
DEVMODEW current_mode {};
current_mode.dmSize = sizeof(current_mode);
const bool orientation_known =
EnumDisplaySettingsW(wide_display_name.c_str(), ENUM_CURRENT_SETTINGS, &current_mode) &&
(current_mode.dmFields & DM_DISPLAYORIENTATION) != 0;
const bool swaps_axes = orientation_known && orientation_swaps_axes(current_mode.dmDisplayOrientation);

for (DWORD index = 0; index < 4096; ++index) {
DEVMODEW mode {};
mode.dmSize = sizeof(mode);
if (!EnumDisplaySettingsW(wide_display_name.c_str(), index, &mode)) {
break;
}

if (advertised_mode_matches(
mode.dmPelsWidth,
mode.dmPelsHeight,
mode.dmDisplayFrequency,
requested_mode)) {
const auto match = classify_advertised_mode(
mode.dmPelsWidth,
mode.dmPelsHeight,
mode.dmDisplayFrequency,
requested_mode,
swaps_axes);
if (match == advertised_mode_match_e::rotation_equivalent) {
BOOST_LOG(info) << "VDD mode "
<< requested_mode.resolution.width << 'x' << requested_mode.resolution.height
<< " is available through the current "
<< orientation_degrees(current_mode.dmDisplayOrientation)
<< "-degree display orientation; reusing the existing monitor";
}
if (match != advertised_mode_match_e::none) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

补齐模式发布超时的诊断信息。

is_mode_advertised 只在发现 rotation_equivalent 时记录方向。若没有匹配,wait_for_mode_publication 会在 Line 863 直接返回 false,但当前代码没有记录当前方向或 Windows 实际枚举的 (width, height, refresh) 列表。请在超时路径记录一次这些信息,并避免在每次轮询时重复输出完整列表。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/display_device/vdd_utils.cpp` around lines 817 - 844, 在
wait_for_mode_publication 的超时返回 false 路径中补充一次诊断日志,记录当前显示方向以及 Windows
实际枚举到的每个模式的宽度、高度和刷新率;复用或扩展 is_mode_advertised
的枚举结果传递方式,确保完整列表只在最终超时时输出一次,而不是每次轮询重复记录。

@qiin2333
qiin2333 merged commit fa7a830 into master Aug 2, 2026
3 checks passed
@qiin2333
qiin2333 deleted the fix_rebuild_vdd branch August 2, 2026 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants