169 lines
10 KiB
Markdown
169 lines
10 KiB
Markdown
|
|
# Windows 云桌面渲染优化执行记录(2026-11-02)
|
|||
|
|
|
|||
|
|
## 执行顺序
|
|||
|
|
|
|||
|
|
1. 复核 GPU、实际编码器、客户机解码器、显示刷新率,保存原始证据。
|
|||
|
|
2. 用持续动画做同步参数 A/B;排除静态桌面的按需发帧影响。
|
|||
|
|
3. 在独立目录接通 MPP、RKMPP、DRM PRIME,先验证真实视频解码,再验证 Moonlight 串流。
|
|||
|
|
4. 只有真实串流通过后才启用新客户端,保留系统 Moonlight 的回退入口。
|
|||
|
|
5. GPU/NVENC 恢复后再做 1080p60、1440p30/60 和输入到屏幕延迟验收。
|
|||
|
|
|
|||
|
|
## 当前 GPU 证据
|
|||
|
|
|
|||
|
|
本轮经 Guest Agent 重新采集:GTX 965M 的 ConfigManagerErrorCode=43,NVML 查询失败,
|
|||
|
|
DXGI 没有枚举到 NVIDIA 适配器,Sunshine 的最新实际编码器为 `libx264`。配置已是
|
|||
|
|
`sw_preset=ultrafast`,当前 Windows 虚拟屏为 2560x1440@30。
|
|||
|
|
|
|||
|
|
没有再次复位设备、重载 VFIO、替换 ROM 或重启宿主机。本轮未改变其他 VM。
|
|||
|
|
仍没有证据确认唯一故障原因;匹配此板卡的生产版 vBIOS 或另一块可稳定直通的 GPU
|
|||
|
|
是下一轮服务端验证的候选条件,而非已完成修复。
|
|||
|
|
|
|||
|
|
验收工具更新为 `tools/validate-sunshine-nvenc.ps1` + `tools/probe-nvidia-d3d.cs`:
|
|||
|
|
实际创建 NVIDIA D3D11 设备、检查 PnP 错误码、检查最新一次实际编码器创建及时间,
|
|||
|
|
并核验 NVENC 会话与编码利用率。不会把启动阶段的编码器探测记录当作实际串流。
|
|||
|
|
|
|||
|
|
## 同步参数 A/B
|
|||
|
|
|
|||
|
|
环境:系统 Moonlight 6.2.0,H.264 软件解码,2560x1440@20、30Mbps,输出约60Hz,
|
|||
|
|
MATE compositor 已关闭,SDL OpenGL ES 2。Windows 用
|
|||
|
|
`tools/stream-motion-test.html` 持续移动条纹与棋盘;源 RAF 约30 FPS。
|
|||
|
|
125% DPI 下页面显示逻辑2048x1152,视频流和 HDMI 仍是物理2560x1440。
|
|||
|
|
|
|||
|
|
下表来自两段完整会话结束日志,包含启动/退出阶段,时长不同;属于现场初步对照,
|
|||
|
|
不构成严格统计学基准。原始日志与叠图保存在 `evidence/moonlight-20261102/`。
|
|||
|
|
|
|||
|
|
| 指标 | smooth | low-latency |
|
|||
|
|
|---|---:|---:|
|
|||
|
|
| 接收/解码 FPS | 17.16 | 17.07 |
|
|||
|
|
| 渲染 FPS | 17.07 | 17.01 |
|
|||
|
|
| 主机处理平均 ms | 33.6 | 35.4 |
|
|||
|
|
| 网络丢帧 | 0.00% | 0.00% |
|
|||
|
|
| jitter 分类丢帧 | 0.44% | 0.29% |
|
|||
|
|
| 网络延迟平均 ms | 11 | 11 |
|
|||
|
|
| 解码平均 ms | 14.07 | 16.96 |
|
|||
|
|
| 帧队列平均 ms | 0.95 | 1.14 |
|
|||
|
|
| 呈现平均 ms(含同步) | 8.38 | 10.87 |
|
|||
|
|
|
|||
|
|
系统客户端软件解码的对照中,关闭同步没有改善帧率或排队,因此软件基线保留 smooth。上述耗时
|
|||
|
|
不能直接相加当作端到端输入延迟;后续须用高速摄像/外部触发测量 P50/P95。
|
|||
|
|
|
|||
|
|
日志中的启动测试 EGLImage 导出失败和单次队列溢出,不能单独证明持续运行时故障。
|
|||
|
|
最终选中的系统路径是软件视频帧上传后的 SDL 呈现;`Using DRM renderer` 也不等于
|
|||
|
|
已经使用 VPU 或直接扫描输出。
|
|||
|
|
|
|||
|
|
## RKMPP 已验证部分
|
|||
|
|
|
|||
|
|
- 为 `/dev/mpp_service`、`/dev/rga`、`/dev/dma_heap/*` 增加 video 组读写权限;
|
|||
|
|
持久化规则为 `terminal/kiosk-shell/etc/70-vdi-rockchip-video.rules`。
|
|||
|
|
- 普通用户执行 MPP H.264 初始化,create/init/destroy 全部返回0。
|
|||
|
|
- 从固定提交构建 MPP 和 FFmpeg-Rockchip 6.1,目录是
|
|||
|
|
`/home/armbian/vdi-build/rkmpp-experiment`;依赖只下载解包,不安装或升级系统包。
|
|||
|
|
- 用 `generate-h264-sample.c` 生成60帧2560x1440 H.264样本。`h264_rkmpp` 全部解出,0错误。
|
|||
|
|
- CPU NV12输出耗时2.620秒;`-hwaccel rkmpp -hwaccel_output_format drm_prime` 输出耗时
|
|||
|
|
0.290秒,CPU时间0.120秒,日志明确为 DRM PRIME 帧,0解码错误。
|
|||
|
|
|
|||
|
|
样本纹理简单且测试期间有编译负载;这些数字仅证明硬解/帧导出可工作,不能替代
|
|||
|
|
Moonlight 真实串流、显示呈现、复杂内容或2K60验收。
|
|||
|
|
|
|||
|
|
## 产品接入点
|
|||
|
|
|
|||
|
|
`VDI_STREAM_STATS=1` 独立于 profile,可公平比较两档。解码器覆盖只接受
|
|||
|
|
software/hardware/auto;RKMPP通过 `H264_DECODER_HINT=h264_rkmpp` 选择,不把
|
|||
|
|
`h264_rkmpp` 当作 Moonlight `--video-decoder` 的值。
|
|||
|
|
|
|||
|
|
`VDI_MOONLIGHT_PROGRAM` 可指定独立客户端启动器。`vdi-kiosk-start` 支持读取
|
|||
|
|
`~/.config/vdi-terminal/render.conf` 的 allowlist 字段,不执行配置文件:
|
|||
|
|
|
|||
|
|
```ini
|
|||
|
|
profile=smooth
|
|||
|
|
stats=0
|
|||
|
|
program=/home/armbian/vdi-terminal/bin/vdi-moonlight-rkmpp
|
|||
|
|
decoder=hardware
|
|||
|
|
codec=H.264
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
文件不存在时沿用系统客户端。上述为 smooth 档示例;本机实际部署档位见下表后说明。
|
|||
|
|
|
|||
|
|
## 构建与页面接入修正
|
|||
|
|
|
|||
|
|
私有客户端固定为 Moonlight v6.2.0 `de2467e433821664cdd2224aad8c89a625be1ad9`,
|
|||
|
|
MPP `7916c3cc000fefc0bdf96636b7d54fe174724f44`,FFmpeg-Rockchip 6.1
|
|||
|
|
`797387de1c9caa9170100d7217ee093d1897f750`。复现入口为
|
|||
|
|
`tools/build-rkmpp-client.sh`,仅在盒子的用户目录下载、解包和构建依赖。
|
|||
|
|
|
|||
|
|
- Qt 5 构建需要显式为上游 `drm.h` 补入 `<optional>`,脚本幂等应用。
|
|||
|
|
- 补齐 EGL 开发依赖,重新执行 qmake 功能探测,并在缺少 HAVE_EGL 时终止构建。
|
|||
|
|
- qmake 改变功能开关不会自动使旧对象失效;构建脚本记录编译/链接参数指纹,
|
|||
|
|
参数变化时清理应用对象,防止“探测有 EGL、实际对象无 EGL”。
|
|||
|
|
- RKMPP 使用独立测试解码器,上游成功路径不输出旧的 `Test decode successful`,
|
|||
|
|
而输出 `Not reusing test decoder for h264_rkmpp`。页面就绪解析同时兼容两者,
|
|||
|
|
仍要求实际 renderer 已选中,并在连接失败时拒绝进入就绪状态。
|
|||
|
|
- 私有启动器设置 QML、Qt 插件和共享库目录,系统 Moonlight 不被覆盖。
|
|||
|
|
|
|||
|
|
第一轮真实串流已输出 2560x1440 的 `h264_rkmpp / drm_prime`,但显示选中 SDL,
|
|||
|
|
并出现 `Selected hwframe->swframe ... (mapping: yes)`,因此该轮不作为零拷贝验收。
|
|||
|
|
对应证据为 `rkmpp-stale-sdl.txt` 与 `rkmpp-first.png`,包含构建负载和启动阶段。
|
|||
|
|
|
|||
|
|
另已核查用户注册表:`MouseTrails=0`、`DragFullWindows=1`,不通过添加第二个光标
|
|||
|
|
或重新设置透明光标来掩盖视频延迟。
|
|||
|
|
|
|||
|
|
## 后续顺序与验收要求
|
|||
|
|
|
|||
|
|
1. 先验证硬解实际串流与 EGL 呈现,记录持续动画下的接收、解码、呈现 FPS,
|
|||
|
|
解码/排队/呈现耗时及丢帧;没有通过则保留系统软件客户端默认入口。
|
|||
|
|
2. 通过后接入页面启动链,验证过场层退出、快捷键回列表、再次连接及持久配置。
|
|||
|
|
保留2K20现有配置作为基线,只有实测更好才提高请求帧率。
|
|||
|
|
3. 服务端 GPU 修复需匹配板卡的生产 ROM 或可稳定直通的替代设备,并重复通过
|
|||
|
|
PnP、NVML、DXGI/D3D11、真实 NVENC 以及重启后的验收。
|
|||
|
|
4. 服务端恢复后按1080p60、1440p30、1440p60逐档验证,并同步虚拟屏刷新率。
|
|||
|
|
1440p60还需要将当前30Hz虚拟屏调整到60Hz,不能只改客户端FPS参数。
|
|||
|
|
5. 用高速摄像或外部触发测输入到显示的P50/P95,另外观察快速拖窗与光标残影。
|
|||
|
|
如延迟仍主要来自光标随视频传输,再评估服务端光标位置/形状侧通道与客户端
|
|||
|
|
单光标显示的二次开发,需同时保证隐藏视频中的旧光标,不能直接叠加本地光标。
|
|||
|
|
|
|||
|
|
客户端应优先接通硬解与显示路径;镜像内安装补帧/运动插值插件不能修复 GPU Code 43,
|
|||
|
|
也不能代替真实输入响应。当前不把插帧作为低延迟方案。
|
|||
|
|
|
|||
|
|
## 真实串流对照与现场选择
|
|||
|
|
|
|||
|
|
清理旧对象后,日志明确选择 `Renderer 'EGL/GLES' with 'DRM' backend chosen`,
|
|||
|
|
实际解码尺寸2560x1440、`h264_rkmpp`、`drm_prime`,呈现使用 EGLImage。
|
|||
|
|
未见实际运行路径的 hwframe→swframe 映射回退。四组均为持续动画、30Mbps、
|
|||
|
|
源RAF30FPS、终端HDMI约60Hz、服务端libx264;均为约2分钟会话,统计包含启动/退出。
|
|||
|
|
会话按顺序进行,网络与服务端负载会波动,不能当作严格控制变量的实验室基准。
|
|||
|
|
|
|||
|
|
| 客户端/请求档位 | 接收/解码 FPS | 呈现 FPS | 主机平均 ms | 解码 ms | 队列 ms | 呈现 ms | 网络/jitter丢帧 |
|
|||
|
|
|---|---:|---:|---:|---:|---:|---:|---|
|
|||
|
|
| 系统软件解码 / 2K20 smooth(先前基线) | 17.16 | 17.07 | 33.6 | 14.07 | 0.95 | 8.38 | 0% / 0.44% |
|
|||
|
|
| RKMPP+EGL / 2K20 smooth | 19.14 | 18.97 | 38.4 | 10.53 | 2.78 | 2.54 | 0% / 0.20% |
|
|||
|
|
| RKMPP+EGL / 2K30 smooth | 24.21 | 23.29 | 46.2 | 8.24 | 31.95 | 4.19 | 0% / 3.02% |
|
|||
|
|
| RKMPP+EGL / 2K30 low-latency | 23.56 | 23.46 | 46.8 | 9.11 | 2.39 | 5.41 | 0% / 0.10% |
|
|||
|
|
| RKMPP+EGL / 2K30 VSync开、Frame Pacing关 | 23.26 | 22.63 | 47.5 | 8.28 | 28.93 | 4.14 | 0% / 2.23% |
|
|||
|
|
|
|||
|
|
对应原始统计分别为 `rkmpp-egl-20-smooth.txt`、`rkmpp-egl-30-smooth.txt`、
|
|||
|
|
`rkmpp-egl-30-lowlatency.txt`、`rkmpp-egl-30-vsync-no-pacing.txt`,均在证据目录中。
|
|||
|
|
|
|||
|
|
本机选择2K30、`profile=low-latency`、RKMPP硬解、H.264,常态关闭叠图。
|
|||
|
|
这是在当前设备上的取舍:相较2K30 smooth,平均帧队列少约30ms;关闭VSync存在
|
|||
|
|
撕裂风险,需要现场动态观察。保留2K20 smooth作为平稳显示的回退档,不将其删除。
|
|||
|
|
截图可见单个白色远程光标,但静态截图不能证明快速移动没有残影或输入延迟为零。
|
|||
|
|
|
|||
|
|
当前会话平均呈现仍只有约23FPS,未达到请求的30FPS;服务端GPU故障和libx264路径
|
|||
|
|
仍未修复。不能将这一轮称为2K60、NVENC恢复或“鼠标无延迟”验收通过。
|
|||
|
|
|
|||
|
|
## 正式入口部署验证
|
|||
|
|
|
|||
|
|
已运行 `tools/deploy_kiosk.sh` 同步、编译、CTest、安装和重启盒子的kiosk受管栈;
|
|||
|
|
CTest 2/2通过。render.conf选择上述私有硬解客户端,桌面卡请求帧率持久保存为30,
|
|||
|
|
原文件备份在盒子 `~/.config/vdi-terminal/desktops.before-rkmpp-20261102.json`。
|
|||
|
|
|
|||
|
|
两次从实际列表页点击Windows连接,日志分别在约10.1秒、9.7秒进入stream_ready,
|
|||
|
|
均明确选中 `EGL/GLES + DRM`、`h264_rkmpp`,过场层退出后画面可见。
|
|||
|
|
`Ctrl+Alt+Shift+Q` 正常退出code=0并回列表,再次连接通过;没有遗留第二条串流。
|
|||
|
|
配置已经写入现有自启链,但本轮未重启盒子、VM或宿主机;不声称完成重启后验收。
|
|||
|
|
|
|||
|
|
截图 `kiosk-rkmpp-session.png`、`kiosk-rkmpp-disconnect.png`、
|
|||
|
|
`kiosk-rkmpp-reconnect.png` 保留了产品入口验证。单白光标可见,未修改原光标策略。
|
|||
|
|
自动化拖窗未形成可计量的动态验收结果,仍需现场鼠标操作与外部摄像测量。
|
|||
|
|
专用Edge测试浏览器已关闭,临时VDIRenderBench任务已删除,未关闭其他浏览器。
|