vdi-cloud/docs/rendering-execution-20261102.md

10 KiB
Raw Blame History

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 字段,不执行配置文件:

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任务已删除,未关闭其他浏览器。