10 KiB
Windows 云桌面渲染优化执行记录(2026-11-02)
执行顺序
- 复核 GPU、实际编码器、客户机解码器、显示刷新率,保存原始证据。
- 用持续动画做同步参数 A/B;排除静态桌面的按需发帧影响。
- 在独立目录接通 MPP、RKMPP、DRM PRIME,先验证真实视频解码,再验证 Moonlight 串流。
- 只有真实串流通过后才启用新客户端,保留系统 Moonlight 的回退入口。
- 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 字段,不执行配置文件:
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,不通过添加第二个光标
或重新设置透明光标来掩盖视频延迟。
后续顺序与验收要求
- 先验证硬解实际串流与 EGL 呈现,记录持续动画下的接收、解码、呈现 FPS, 解码/排队/呈现耗时及丢帧;没有通过则保留系统软件客户端默认入口。
- 通过后接入页面启动链,验证过场层退出、快捷键回列表、再次连接及持久配置。 保留2K20现有配置作为基线,只有实测更好才提高请求帧率。
- 服务端 GPU 修复需匹配板卡的生产 ROM 或可稳定直通的替代设备,并重复通过 PnP、NVML、DXGI/D3D11、真实 NVENC 以及重启后的验收。
- 服务端恢复后按1080p60、1440p30、1440p60逐档验证,并同步虚拟屏刷新率。 1440p60还需要将当前30Hz虚拟屏调整到60Hz,不能只改客户端FPS参数。
- 用高速摄像或外部触发测输入到显示的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任务已删除,未关闭其他浏览器。