优化:完成Ubuntu 2K画质与拖拽响应调优

This commit is contained in:
宋一鸣 2026-11-05 19:18:17 +08:00
parent 65f92df8b7
commit a14f028402
97 changed files with 6959 additions and 3 deletions

View File

@ -1,7 +1,66 @@
# 继续开发前必读
## 2026-11-05 Ubuntu 深度响应调优(最新)
- Ubuntu VM102 已在正常会话中启用 KMS 捕获 + 原生独立光标:virtio_gpu atomic 唯一 primary plane,2K geometry,cursor hotspot plane 不暴露;盒子客户端 SHA 未变。KMS 守护按 `CRTC_W/H=2560x1440` 校验,不能依赖 virtio atomic 客户端的 legacy `crtc_id/fb_id=0`。
- KMS 45FPS 与 X11 45FPS 长按框选回显 P50/P95=195.9/246.6ms vs 250.1/311.5ms;更新约16.0/s vs10.6/s。28次原生光标点击、7种形状/热点/隐显通过,像素差0;正常退出、空闲重连、guard强杀恢复、再次重连通过。证据 `docs/evidence/ubuntu-deep-latency-20261105/`,报告 `docs/ubuntu-deep-latency-20261105.md`。
- 真实GTK按钮/ masked entry 定量仅为当前应用内回显,不能代表真实后端认证;KMS按钮约304/378ms、字符约165/182ms。硬编和 `min_threads=4` 均失败/无收益并已撤回;Ubuntu仍软件x264,未达到Windows约90ms或零延迟。
- 盒子 Ubuntu 卡片暂保持45FPS请求用于当前联调,2K/30Mbps;若收尾要回30FPS,先正常退出并改仅 Ubuntu 对象。当前现场应保持 `vdi-sunshine.service capture=kms` 与 guard active;检查时不要用 `fb_id/crtc_id` 作为活动判据。
完整对话总结在:`D:\DAIMA\vdi-cloud\PROJECT_CONTEXT.md`
## 2026-11-05 Ubuntu框选/渲染后续(优先于旧VM102硬件描述)
- 后续用户要求清理锁屏Sunshine卡片:已确认是Stream Started/Paused通知,非多份安装。Ubuntu sunshine.conf新增system_tray=disabled(同时移除托盘图标),正常退出/入口重连后新进程日志确认生效;仅当前4条通知均为Sunshine时,通过GNOME通知面板清除并确认0剩余。原配置备份~/vdi-terminal/backups/sunshine-notifications-20261105/sunshine.conf;不改全局通知或锁屏策略,串流/guard active,退回普通桌面。下方“Sunshine配置与原配置一致”仅指渲染调优结束时,现多此一项。
- 用户要求先只处理Ubuntu,已明确允许正常关闭启动、A/B及必要回退。本轮VM102正常关闭启动3次,最终4核/6144MB、cpu=host、vga=virtio-gl;宿主Intel i915共享渲染,Windows/麒麟/独占NVIDIA配置未动。宿主仅补GL/EGL/Mesa依赖,0升级10新增0移除。
- Xorg确认virgl Intel HD4600/glamor生效,x264确认AVX2/FMA3/BMI2。仍X11捕获/libx264软件编码,renderD128不代表硬件编码。最终2K30/30Mbps/limited、默认线程;45FPS及min_threads=4试验无明显延迟收益,已撤回。盒子desktops JSON结构与本轮备份完全相同,客户端SHA仍5d4330…。
- 受控60Hz长按框选:基线回显P50/P95=398.3/634.6ms,最终224.4/308.3ms;独立编号更新2.0→12.4/s,不等于总视频FPS。有效轮次最终编号300及释放均见;中位改善约44%,短样本未随机重复,非USB/光子延迟,尚未达到Windows/原生目标。
- 回归16编号点击+2快速点击,源18按/18放,最大坐标误差1.375px;2K及12灰阶核对通过。临时测试服务已停,最后留Ubuntu普通桌面,Sunshine/guard active。不要自动进一步改麒麟。
- 备份PVE /root/vdi-ubuntu-render-20261105/102.conf.before,Ubuntu/盒子各自~/vdi-terminal/backups/ubuntu-render-20261105/。回退只还原cpu/删除vga字段,需正常关闭启动;别整份覆盖VM配置。
- 报告docs/ubuntu-drag-render-20261105.md,原始证据docs/evidence/ubuntu-drag-20261105/。剩余瓶颈为捕获/GPU读回/软件编码;未部署硬编方案或更换协议。
## 2026-11-05 Linux原生独立光标(优先于下方旧样式/原型状态)
- 用户要求保留原生样式并直接实施低延迟方案;Ubuntu恢复Adwaita/24、default加速,关闭动画保留。两Linux真实2560×1440/30FPS请求/30Mbps/limited/软件编码保留。
- 已部署0005 + terminal/native-cursor:受限独立SSH密钥/固定主机公钥同步XFixes真实形状、热点、显隐,本地X11指针移动不等待视频。单座席X11/2K/绝对鼠标,最多128×128;状态2秒过期或源几何改变则结束串流恢复原服务,不做运行中帧交接。
- 私有原版Sunshine精确SHA + 进程级adapter只清除捕获副本像素。Ubuntu原/usr/bin/sunshine的capabilities保留,租约内用同SHA无cap副本;麒麟仅host.py/私有sunshine/.so认证KYSEC。guard按需启动,ExecStopPost恢复;原服务永久文件不改。
- 盒子最终客户端SHA 5d4330f703d7f8e053bc3795ca42bdaf231c9e9dd8ebb00a612013adbcccee03,.71/.72 profile固定该值;helper在远端租约前核验,旧备份实测拒绝且原服务PID不变。修改二进制须停用profile并重新验证。备份~/vdi-terminal/backups/native-cursor-20261105/;回退先退出等恢复,再停用两JSON。
- 最终版两系统七种光标形状/热点一致、静态像素最大差0、视频无混入指针;各28编号点击与源事件完全匹配,Ubuntu误差最大1.055px、麒麟0.829px。较早各16次40ms短按和双击补测通过;最终版暂停Moonlight指针仍移动,较早服务器主动warp(400,600)两台读回正确。
- 最终页面视频回显Ubuntu P50/P95 188.38/522.42ms,麒麟134.37/165.56ms;不是本地指针或物理USB延迟,未定量证明Windows等效。Ubuntu两次强制暂停恢复后首击未回显,根因未定;完整SDL失焦未验收,不可称全部场景无丢输入。
- agent/guard SIGKILL恢复、Ubuntu bridge冻结退出、麒麟真实分辨率变化退出及恢复2K重连均已测。4项单测和清洁patch应用通过。构建器会规范CRLF但严格上下文;现场本轮未重建部署其他任务0004,不能据构建器宣称现场包含0004。
- 普通Ubuntu初次收尾约4分42秒触发stale/mismatched退出,发现校验时间在读取前取得的原子替换竞态,改为读后取时间。该轮未区分未来/实际过期,不能认定唯一根因。仅修时序版先6分钟通过,之后9分32秒真实heartbeat超时;最终状态等待上限改2秒、主机TTL4秒,增加X11读耗时诊断。已测暂停Ubuntu代理1.1秒时指针继续移动且会话存活。旧1da552…形状/点击证据保留;最终版持续运行另记。
- Ubuntu原Sunshine在11:12:07恢复测试阶段停止超过10秒、看门狗SIGTRAP,11:12:14恢复;未修复上游停止看门狗问题,原crash报告保留且未外发。
- 最终2秒策略Ubuntu6分钟/65960次状态读取存活,含1.1秒暂停;读前时间出现1次合法未来值、读后0次,证实竞态检查顺序需要修正。随后同会话七形状/28点击通过;bridge冻结2.6秒后2.904秒检查客户端退出,原服务恢复。详见ubuntu-final-soak/release-probe/final-stale-state等最终证据。
- 最终新SHA的Windows2K45/RKMPP/EGL无独立光标env回归;麒麟2K30七形状/28点击及普通桌面重连后退出,原服务active且无临时drop-in。Ubuntu保留2K30/原生指针PID299860/父235482,guard按设计active,临时GTK源/盒子探针均已停。报告docs/linux-native-cursor-20261105.md,证据docs/evidence/native-cursor-20261105/。
## 2026-11-05 Ubuntu画质与鼠标样式调优
- Ubuntu .72/test2 已由1080p升级真实2560×1440,盒子只改Ubuntu对象为2K30,自动请求30Mbps。原VM虚拟VGA在当前内核可直接切2K,未改PVE硬件或重启VM/GDM。
- 用户服务启动前newmode/addmode/output创建2K;删模式后服务启动重建通过。GNOME monitors.xml保存单屏2K/100%缩放,最终锁屏/解锁仍2K;整机重启恢复未验收。DisplayConfig持久调用曾待确认后回退,已重新保存显示配置并重新核验最终尺寸。
- DMZ-White/24px、flat鼠标加速、关闭GNOME动画;不是复制Windows整套主题,也没有叠加本地假箭头。无GPU render节点,仍X11/libx264 ultrafast/zerolatency默认线程。
- .72 host-color-range=0,正常kiosk最终PID240476/父235482,2K30/30Mbps、RKMPP/EGL、服务端MPEG和真实源2K核对;最终保留Ubuntu普通桌面连接,临时GTK服务已停止。
- 正常入口2K短测:45请求full21.49FPS/F9 P50 373.2ms;limited22.83/376.7ms;单线程+无动画17.98/402.9ms(单线程已撤回);最终30请求limited/默认线程/无动画21.40/320.9ms。F9每轮24翻转无超时,但一轮客体有额外F9事件且无序号,不能证明逐键延迟。四轮启动快速点击只记录24/24/23/21且单线程有坐标重复,不能说全部通过;补做稳定正常会话24次慢速交替点击24/24、误差<1px、F8收到,见final-input-check.json。源GTK本身约15–20绘制/秒,视频含重复帧;不能声称独立运动21–23帧、稳定30/45或物理延迟降低/Windows等效。
- limited灰阶保持黑白层次,未显著截断;单像素/彩字仍受4:2:0限制。两端备份~/vdi-terminal/backups/ubuntu-quality-20261105/,Ubuntu monitors.xml原不存在;.72 range原不存在。原Sunshine配置/服务、gsettings原值均保留。测试仅补装python3-gi-cairo,无整体升级。
- 文档docs/ubuntu-quality-20261105.md、证据docs/evidence/ubuntu-quality-20261105/。Windows/麒麟卡片结构比较未变,未改客户端二进制、全局渲染或USB任务修改。
## 2026-11-05 Windows固定PCI设备不再可弹出
- 用户要求日常体验像普通电脑、托盘只留真实U盘,授权“你自己保存然后重启”。交互会话仅设置/系统窗口,无打开文档;未强制关闭应用。
- 09:28正常shutdown.exe /s /t 0后冷启动VM100。原args保留GPU子厂商设置,追加三个global:ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off、pci-bridge.shpc=off、pcie-root-port.hotplug=off。PCI增删须关机,USB设备级热插拔保留;没改总线/设备地址/驱动,没有重启USB隧道。
- 原托盘四项(GTX965M/VirtIO网卡/串口/附加AHCI)Capabilities从6变0,InstanceId相同,Status OK;GPU错误0,系统盘Online/Healthy,IP .70、Sunshine及Guest Agent正常。
- PVE备份/工具/root/vdi-fixed-pci-20261105/(backup/plan.json、vm.conf.before),set-fixed-pci.py支持prepare/apply/restore且拒绝在线变更。4项单测和无磁盘/网络后端/直通GPU的隔离QEMU测试通过(PCI关闭、usb-redir添加/删除)。
- 盒子无物理U盘,仅键鼠,USB服务active;Moonlight随关机退出,用户须重连Windows。托盘UIA未暴露传统图标子项,外观与真实U盘插拔待用户验收,不冒充目视完成。文档docs/fixed-pci-tray-20261105.md及evidence/fixed-pci-20261105。
## 2026-11-04 云桌面图形关机/重启按钮限制
- 用户明确要求Windows/Ubuntu/麒麟桌面内图形关机、重启按钮也禁用,前面的快捷键补丁不足。本轮已通过PVE Guest Agent实际部署,不依赖未构建的Moonlight 0004。
- Windows VM100/test HKU Explorer NoClose=1,交互用户任务广播Policy并SHRestricted(2)=1;无Explorer重启/注销/VM重启,任务已删除。首次原值备份C:\ProgramData\VDI\power-policy\original.clixml。
- 麒麟VM101/test1使用polkit .pkla,Ubuntu VM102/test2使用.rules。两台均额外部署/etc/dbus-1/system.d/zz-vdi-desktop-power.conf,按客户UID拒绝login1电源方法和Can*查询,只ReloadConfig。root CanPowerOff仍yes。
- 两台实际图形进程pkcheck基础reboot仍授权(内部原因未确定),所以不能只靠polkit宣称已屏蔽。D-Bus错误签名安全探测八项全部Access denied,七项Can*拒绝;并未发送有效关机请求。麒麟定位时仅重启过polkit一次,Sunshine保持active。
- 三台running,Windows LastBoot及Linux boot ID与部署前一致;未逐项目视验收菜单外观、未重启验收。限制当前客户账户图形电源入口,不防管理员命令/改策略,不涉及注销/锁屏,不实现盒子开关联动VM生命周期。新用户需重新针对账户应用。
- 工具tools/deploy-guest-power-policy.py apply/query/restore --vm 100或--vm 101 --user test1或--vm 102 --user test2;Linux首次备份/var/lib/vdi/power-policy。详见docs/guest-power-policy-20261104.md及evidence/guest-power-policy-20261104。
## 2026-11-04 盒子过夜重启观察(最新)
- 用户要求今晚开机观察并记录重启/原因。19:35启用vdi-overnight-observer.service,active/enabled,每60秒fsync心跳、boot ID/uptime计数、温度/负载/内存/网络/进程/桌面几何;跨午夜分日志。当前计数0是启用后范围,不代表历史没重启。
- 中文汇总~/vdi-terminal/logs/overnight-summary.txt;JSON行overnight-health-YYYYMMDD.log;持久状态~/vdi-terminal/state/overnight-state.json。同boot的服务重启不计为整机重启;11项状态/证据/跨日测试通过,实际分钟样本和服务重启状态保持已验证,未实际重启盒子。
- /var/log是zram,journal链接到eMMC /var/log.hdd/journal。新增70-vdi-observer-journal.conf配置persistent/64MB/7day/30s,flush/sync确认磁盘journal;只重启journald和本观察服务,不动Moonlight/显示/网络/GPU。
- root拥有/usr/local/libexec/vdi-observer-pstore只读采集pstore到/var/lib/vdi-observer/pstore.json(root:systemd-journal 640),观察服务低权限读取。旧归档41字节reboot行仅基线;仅内容变化作为新线索。无法确认的断电/硬复位明确标原因未确认,不能伪造重启因果。
- 最后Windows串流PID137139、2K45和显示守护保留,boot ID afb6a02f-ba7c-478a-8704-c78a993d23c6。文档docs/overnight-box-observation-20261104.md及evidence/overnight-observer-20261104;备份~/vdi-terminal/backups/overnight-observer-20261104-*。明早读取两天日志和汇总,无明早自动通知任务。
## 2026-11-04 麒麟鼠标掉帧继续排查(最新)
- 保留原版Sunshine SHA256 1c3099bf924db3aee759b3d7c05e012569ef8650c400d1479144398795decc71、单线程、暂停合成器、真实2K30/30Mbps。未改PVE或其他桌面。
- wrapper支持~/.config/vdi-terminal/host-color-range/<host>的0/1协商;仅.71设0,消除软件full-range额外转换。同场景2K45请求:原full21.42FPS,limited28.81FPS;不代表真实45或物理延迟与Windows一致。

View File

@ -66,7 +66,7 @@ vdi-cloud/
- 会话退出后返回桌面列表。
不同客户部署环境的桌面地址不同:换环境时在“设置”里改地址即可,不需要改代码。
VPN 属于网络层能力(盒子上的 VPN 客户端建立隧道后),地址字段直接填隧道地址即可。
这里的 VPN 仅指网络层能力:盒子上的 VPN 客户端建立隧道后,桌面地址字段可以填写隧道地址。让云桌面内部浏览器和应用通过 Clash/Mihomo 访问 GPT 等外部服务属于后续规划,见“下一步计划”第 8 项。
设备身份自动登录是正式认证 API 上线前的临时实现。后续通过 `DesktopService` 适配层接入真实的用户认证、桌面列表和一次性连接票据接口,页面流程不需要重写。
@ -86,7 +86,9 @@ VPN 属于网络层能力(盒子上的 VPN 客户端建立隧道后),地
- `vsync`、`frame-pacing`、性能叠图等低延迟参数可配置;
- 独立 Moonlight 启动脚本保留作调试用途,但不再作为产品开机入口。
2026-11-04 现场已接通 Windows、Ubuntu、麒麟三种桌面的正常选择与连接流程。Ubuntu 当前采用 1080p / 30 FPS 配置,麒麟已升级真实 2K / 30 FPS 配置与30Mbps;两者使用 `libx264` 软件编码,盒子使用 RKMPP 硬解。麒麟后续采用逐主机limited视频范围协商,同场景动态短测由约21提高至29FPS,仍未达到Windows水平,长期性能及物理输入延迟尚未验收。配置、备份与证据见 [Linux 桌面接入记录](docs/linux-desktop-onboarding-20261104.md)、[麒麟2K调优记录](docs/kylin-quality-20261104.md) 和 [鼠标掉帧继续排查](docs/kylin-mouse-20261104.md)。
2026-11-04 现场已接通 Windows、Ubuntu、麒麟三种桌面的正常选择与连接流程。Ubuntu 与麒麟现均为真实 2K / 30 FPS 请求配置与30Mbps,使用 `libx264` 软件编码和逐主机limited范围协商,盒子使用 RKMPP 硬解。2026-11-05 两套 Linux 已启用受限 X11 原生独立光标:同步实际形状/热点/显隐,由盒子显示指针位置,移动不再等待视频;Ubuntu恢复Adwaita/24px及默认鼠标加速,保留关闭动画。Windows保持原视频光标路径。形状、编号点击、断线恢复已实测,完整失焦与物理输入延迟尚未验收;点击页面及拖窗内容仍受软件编码限制,不能称定量等同Windows。方案和边界见 [原生独立光标实施记录](docs/linux-native-cursor-20261105.md);历史画质证据见 [Linux接入](docs/linux-desktop-onboarding-20261104.md)、[Ubuntu调优](docs/ubuntu-quality-20261105.md)、[麒麟2K调优](docs/kylin-quality-20261104.md)。
2026-11-05 后续只对 Ubuntu VM102 启用 `cpu=host`(AVX2)及 `virtio-gl`(共享Intel核显渲染)。受控长按框选的回显中位数约398→224ms,2K与原生光标保留;45FPS和4编码线程未继续改善延迟,最终仍用30FPS及默认线程。尚未达到Windows/原生目标,仍需解决捕获和软件编码瓶颈,详见 [Ubuntu框选与渲染调优](docs/ubuntu-drag-render-20261105.md)。
### 3. 状态机
@ -250,7 +252,9 @@ Moonlight 调试配置路径:
4. 实现 Ubuntu、麒麟桌面连接配置;
5. 适配 RK3528 MPP/VPU 硬解;
6. 切换到 Weston/Wayland 正式显示路径;
7. 开发 `vdt-agent`、OTA、USB、云端服务和 Web 控制台。
7. 开发 `vdt-agent`、OTA、USB、云端服务和 Web 控制台;
8. **云桌面内上网代理(规划)**:在终端登录首页提供代理配置入口,支持导入/更新 Clash 或 Mihomo 订阅、选择节点、启停和连通性测试;由云端服务将策略分别下发到 Windows、Ubuntu 和麒麟云桌面,使桌面内的浏览器和应用可以访问 GPT 等外部服务,同时为 Moonlight 串流、管理平台和必要内网地址保留稳定的直连/专用路由。该功能当前不实现、不部署;
9. **云桌面软件白名单与商业合规(规划)**:建立按客户/桌面生效的软件允许列表、版本校验、策略下发、审计和回滚流程。Windows 与麒麟计划通过签名的系统插件或代理组件执行白名单策略;Ubuntu 计划在系统底层实施,并在定版前完成权限模型、更新机制和例外流程评审。该功能当前不实现、不部署,正式销售前必须完成授权范围和合规审查。
## 十、开发规范

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

View File

@ -0,0 +1,66 @@
# To display the perf.data header info, please use --header/--header-only options.
#
#
# Total Lost Samples: 0
#
# Samples: 870 of event 'cpu-clock'
# Event count (approx.): 8787878700
#
# Overhead Command Shared Object Symbol IPC [IPC Coverage]
# ........ ............... ................. ........................................... ....................
#
4.48% Xorg libc.so.6 [.] __memmove_avx_unaligned_erms - -
|
---__memmove_avx_unaligned_erms
0x74d4c87b443d
0x74d4c880cc9a
0x74d4c87b4d39
0x74d4c87b50d4
0x74d4cb12577a
0x74d4cb1178b1
0x59b1b67f953d
0x59b1b675babf
0x59b1b675fed9
__libc_start_call_main
__libc_start_main_impl (inlined)
_start
4.37% session::video libc.so.6 [.] __memmove_avx_unaligned_erms - -
|
---__memmove_avx_unaligned_erms
|
--4.25%--0x556749141015
0x556749141d3c
0x556749129542
0x556749129747
0x55674905a9fc
0x55674905b4b4
0x556748d841f8
0x556748d89a5f
0x556748d8a838
0x556748d8aeed
0x556748d717dc
0x55674a019223
start_thread
__clone3 (inlined)
3.56% video::capture libc.so.6 [.] __memmove_avx_unaligned_erms - -
2.99% session::video sunshine [.] 0x000000000065ff08 - -
|
--1.49%--0x556749090f08
0x55674905dd70
0x55674905907f
0x55674905a5b3
0x55674905b86c
0x556749156dbd
0x55674905abca
0x55674905b51c
0x556748d841f8
0x556748d89a5f
0x556748d8a838
0x556748d8aeed
0x556748d717dc
0x55674a019223
start_thread
__clone3 (inlined)

View File

@ -0,0 +1,457 @@
{
"host": "192.168.1.72",
"pid": 40222,
"shapes": [
{
"name": "default",
"source": {
"w": 24,
"h": 24,
"hx": 3,
"hy": 1,
"x": 181,
"y": 599,
"sw": 2560,
"sh": 1440
},
"local": {
"x": 182,
"y": 600,
"w": 24,
"h": 24,
"hx": 3,
"hy": 1
},
"geometry_matches": true,
"max_pixel_difference": 0,
"visible_pixels": 254,
"video": {
"reference": 15726330,
"nonuniform_pixels": 0
}
},
{
"name": "text",
"source": {
"w": 24,
"h": 24,
"hx": 11,
"hy": 12,
"x": 547,
"y": 599,
"sw": 2560,
"sh": 1440
},
"local": {
"x": 548,
"y": 600,
"w": 24,
"h": 24,
"hx": 11,
"hy": 12
},
"geometry_matches": true,
"max_pixel_difference": 0,
"visible_pixels": 240,
"video": {
"reference": 15791866,
"nonuniform_pixels": 0
}
},
{
"name": "ew-resize",
"source": {
"w": 24,
"h": 24,
"hx": 12,
"hy": 12,
"x": 913,
"y": 599,
"sw": 2560,
"sh": 1440
},
"local": {
"x": 914,
"y": 600,
"w": 24,
"h": 24,
"hx": 12,
"hy": 12
},
"geometry_matches": true,
"max_pixel_difference": 0,
"visible_pixels": 301,
"video": {
"reference": 15726330,
"nonuniform_pixels": 0
}
},
{
"name": "wait",
"source": {
"w": 24,
"h": 24,
"hx": 11,
"hy": 11,
"x": 1280,
"y": 599,
"sw": 2560,
"sh": 1440
},
"local": {
"x": 1280,
"y": 600,
"w": 24,
"h": 24,
"hx": 11,
"hy": 11
},
"geometry_matches": true,
"max_pixel_difference": 0,
"visible_pixels": 433,
"video": {
"reference": 15791866,
"nonuniform_pixels": 0
}
},
{
"name": "none",
"source": {
"w": 1,
"h": 1,
"hx": 0,
"hy": 0,
"x": 1645,
"y": 599,
"sw": 2560,
"sh": 1440
},
"local": {
"x": 1645,
"y": 600,
"w": 1,
"h": 1,
"hx": 0,
"hy": 0
},
"geometry_matches": true,
"max_pixel_difference": 0,
"visible_pixels": 0,
"video": {
"reference": 15726074,
"nonuniform_pixels": 0
}
},
{
"name": "crosshair",
"source": {
"w": 24,
"h": 24,
"hx": 11,
"hy": 11,
"x": 2011,
"y": 599,
"sw": 2560,
"sh": 1440
},
"local": {
"x": 2011,
"y": 600,
"w": 24,
"h": 24,
"hx": 11,
"hy": 11
},
"geometry_matches": true,
"max_pixel_difference": 0,
"visible_pixels": 281,
"video": {
"reference": 15726074,
"nonuniform_pixels": 0
}
},
{
"name": "custom",
"source": {
"w": 24,
"h": 24,
"hx": 7,
"hy": 9,
"x": 2377,
"y": 599,
"sw": 2560,
"sh": 1440
},
"local": {
"x": 2377,
"y": 600,
"w": 24,
"h": 24,
"hx": 7,
"hy": 9
},
"geometry_matches": true,
"max_pixel_difference": 0,
"visible_pixels": 576,
"video": {
"reference": 15726074,
"nonuniform_pixels": 0
}
}
],
"paused_client": {
"position": [
350,
700
],
"elapsed_ms": 255.453621,
"same_shape": true,
"steps": [
{
"target": [
250,
650
],
"position": [
250,
650
],
"query_ms": 8.327664
},
{
"target": [
280,
670
],
"position": [
280,
670
],
"query_ms": 2.16409
},
{
"target": [
300,
690
],
"position": [
300,
690
],
"query_ms": 2.175173
},
{
"target": [
350,
700
],
"position": [
350,
700
],
"query_ms": 2.244587
}
]
},
"clicks": [
{
"seq": 1,
"x": 182,
"y": 750,
"seen": 1,
"decoded_ms": 160.545435
},
{
"seq": 2,
"x": 548,
"y": 850,
"seen": 2,
"decoded_ms": 135.850311
},
{
"seq": 3,
"x": 914,
"y": 750,
"seen": 3,
"decoded_ms": 138.104231
},
{
"seq": 4,
"x": 1280,
"y": 850,
"seen": 4,
"decoded_ms": 160.524437
},
{
"seq": 5,
"x": 1645,
"y": 750,
"seen": 5,
"decoded_ms": 151.550171
},
{
"seq": 6,
"x": 2011,
"y": 850,
"seen": 6,
"decoded_ms": 133.429855
},
{
"seq": 7,
"x": 2377,
"y": 750,
"seen": 7,
"decoded_ms": 131.276556
},
{
"seq": 8,
"x": 182,
"y": 850,
"seen": 8,
"decoded_ms": 132.176608
},
{
"seq": 9,
"x": 548,
"y": 750,
"seen": 9,
"decoded_ms": 119.835754
},
{
"seq": 10,
"x": 914,
"y": 850,
"seen": 10,
"decoded_ms": 146.008994
},
{
"seq": 11,
"x": 1280,
"y": 750,
"seen": 11,
"decoded_ms": 147.967174
},
{
"seq": 12,
"x": 1645,
"y": 850,
"seen": 12,
"decoded_ms": 153.74022
},
{
"seq": 13,
"x": 2011,
"y": 750,
"seen": 13,
"decoded_ms": 122.392997
},
{
"seq": 14,
"x": 2377,
"y": 850,
"seen": 14,
"decoded_ms": 211.141978
},
{
"seq": 15,
"x": 182,
"y": 750,
"seen": 15,
"decoded_ms": 161.193497
},
{
"seq": 16,
"x": 548,
"y": 850,
"seen": 16,
"decoded_ms": 204.8912
},
{
"seq": 17,
"x": 914,
"y": 750,
"seen": 17,
"decoded_ms": 135.677069
},
{
"seq": 18,
"x": 1280,
"y": 850,
"seen": 18,
"decoded_ms": 210.982152
},
{
"seq": 19,
"x": 1645,
"y": 750,
"seen": 19,
"decoded_ms": 126.295068
},
{
"seq": 20,
"x": 2011,
"y": 850,
"seen": 20,
"decoded_ms": 164.353012
},
{
"seq": 21,
"x": 2377,
"y": 750,
"seen": 21,
"decoded_ms": 201.544444
},
{
"seq": 22,
"x": 182,
"y": 850,
"seen": 22,
"decoded_ms": 201.614734
},
{
"seq": 23,
"x": 548,
"y": 750,
"seen": 23,
"decoded_ms": 181.206665
},
{
"seq": 24,
"x": 914,
"y": 850,
"seen": 24,
"decoded_ms": 208.485283
},
{
"seq": 25,
"x": 1280,
"y": 750,
"seen": 25,
"decoded_ms": 159.208195
},
{
"seq": 26,
"x": 1645,
"y": 850,
"seen": 26,
"decoded_ms": 164.559797
},
{
"seq": 27,
"x": 2011,
"y": 750,
"seen": 27,
"decoded_ms": 177.386552
},
{
"seq": 28,
"x": 2377,
"y": 850,
"seen": 28,
"decoded_ms": 156.205302
}
],
"p50_ms": 157.7067485,
"p95_ms": 210.982152,
"method": "XTest click-down to unique decoded sequence; excludes USB and scanout"
}

View File

@ -0,0 +1,351 @@
{
"pid": 333281,
"sent": 300,
"elapsed": 6.029666734000784,
"frames": [
{
"seq": 0,
"t": 104512.239431477,
"age_ms": null
},
{
"seq": 1,
"t": 104512.383192034,
"age_ms": 144.5594520046143
},
{
"seq": 4,
"t": 104512.466121068,
"age_ms": 177.34973100596108
},
{
"seq": 7,
"t": 104512.566346951,
"age_ms": 227.791242999956
},
{
"seq": 13,
"t": 104512.599408487,
"age_ms": 160.80744100327138
},
{
"seq": 16,
"t": 104512.699652746,
"age_ms": 210.9896559995832
},
{
"seq": 21,
"t": 104512.767006974,
"age_ms": 194.81691799592227
},
{
"seq": 24,
"t": 104512.799459786,
"age_ms": 177.2593119967496
},
{
"seq": 31,
"t": 104512.933637389,
"age_ms": 167.96715700183995
},
{
"seq": 35,
"t": 104513.017511149,
"age_ms": 212.23217499209568
},
{
"seq": 38,
"t": 104513.077507896,
"age_ms": 222.03037499275524
},
{
"seq": 42,
"t": 104513.132969697,
"age_ms": 195.8896810101578
},
{
"seq": 52,
"t": 104513.260996184,
"age_ms": 172.20925701258238
},
{
"seq": 55,
"t": 104513.366535776,
"age_ms": 227.11804301070515
},
{
"seq": 63,
"t": 104513.465344117,
"age_ms": 193.3882849989459
},
{
"seq": 66,
"t": 104513.516390558,
"age_ms": 194.36976799624972
},
{
"seq": 70,
"t": 104513.54974114,
"age_ms": 161.18718999496195
},
{
"seq": 71,
"t": 104513.599913142,
"age_ms": 194.61827399209142
},
{
"seq": 73,
"t": 104513.716206753,
"age_ms": 233.85862799477763
},
{
"seq": 81,
"t": 104513.819435121,
"age_ms": 247.10120899544563
},
{
"seq": 84,
"t": 104513.85580132,
"age_ms": 206.37856698886026
},
{
"seq": 91,
"t": 104513.967067338,
"age_ms": 228.50377700524405
},
{
"seq": 96,
"t": 104513.99077197,
"age_ms": 153.5435719997622
},
{
"seq": 99,
"t": 104514.04972977,
"age_ms": 177.30712000047788
},
{
"seq": 102,
"t": 104514.099714514,
"age_ms": 177.70408900105394
},
{
"seq": 105,
"t": 104514.149824094,
"age_ms": 177.65946200233884
},
{
"seq": 107,
"t": 104514.216565505,
"age_ms": 211.3130910001928
},
{
"seq": 111,
"t": 104514.299878954,
"age_ms": 227.67745799501427
},
{
"seq": 117,
"t": 104514.34970561,
"age_ms": 177.40133100596722
},
{
"seq": 120,
"t": 104514.433450736,
"age_ms": 210.84291400620714
},
{
"seq": 125,
"t": 104514.499795178,
"age_ms": 194.53979899117257
},
{
"seq": 131,
"t": 104514.599880169,
"age_ms": 194.1547900059959
},
{
"seq": 134,
"t": 104514.633181748,
"age_ms": 177.9598869907204
},
{
"seq": 137,
"t": 104514.683211993,
"age_ms": 177.33920500904787
},
{
"seq": 139,
"t": 104514.766731654,
"age_ms": 228.18322000966873
},
{
"seq": 146,
"t": 104514.8164396,
"age_ms": 161.06146700622048
},
{
"seq": 148,
"t": 104514.916416666,
"age_ms": 227.66141100146342
},
{
"seq": 154,
"t": 104514.967151008,
"age_ms": 177.8076239861548
},
{
"seq": 156,
"t": 104515.050657538,
"age_ms": 228.57900700182654
},
{
"seq": 162,
"t": 104515.133192794,
"age_ms": 211.316576009267
},
{
"seq": 167,
"t": 104515.233260569,
"age_ms": 227.95861400663853
},
{
"seq": 173,
"t": 104515.333358094,
"age_ms": 227.58614699705504
},
{
"seq": 181,
"t": 104515.481023841,
"age_ms": 242.47522400401067
},
{
"seq": 187,
"t": 104515.516803771,
"age_ms": 177.49932099832222
},
{
"seq": 190,
"t": 104515.586970887,
"age_ms": 198.40358999499585
},
{
"seq": 195,
"t": 104515.666858619,
"age_ms": 183.13621100969613
},
{
"seq": 198,
"t": 104515.749984223,
"age_ms": 228.0977430054918
},
{
"seq": 204,
"t": 104515.799814376,
"age_ms": 177.78516100952402
},
{
"seq": 206,
"t": 104515.902322874,
"age_ms": 234.46643899660558
},
{
"seq": 212,
"t": 104515.933265681,
"age_ms": 177.80323899933137
},
{
"seq": 218,
"t": 104516.050162448,
"age_ms": 194.68852499267086
},
{
"seq": 221,
"t": 104516.20082805,
"age_ms": 295.25534600543324
},
{
"seq": 227,
"t": 104516.233473358,
"age_ms": 228.16218600200955
},
{
"seq": 232,
"t": 104516.266585927,
"age_ms": 177.10263100161683
},
{
"seq": 234,
"t": 104516.383193354,
"age_ms": 261.2750469997991
},
{
"seq": 244,
"t": 104516.489367314,
"age_ms": 190.34345900581684
},
{
"seq": 248,
"t": 104516.549978313,
"age_ms": 194.10167701425962
},
{
"seq": 251,
"t": 104516.70027524,
"age_ms": 295.0441739958478
},
{
"seq": 258,
"t": 104516.733220096,
"age_ms": 210.86271599051543
},
{
"seq": 261,
"t": 104516.866613062,
"age_ms": 294.4065740011865
},
{
"seq": 268,
"t": 104516.95033221,
"age_ms": 251.20849900122266
},
{
"seq": 277,
"t": 104517.049994544,
"age_ms": 210.87874499789905
},
{
"seq": 279,
"t": 104517.241374306,
"age_ms": 369.3924030085327
},
{
"seq": 290,
"t": 104517.340214702,
"age_ms": 284.98286299873143
},
{
"seq": 296,
"t": 104517.37882853,
"age_ms": 223.49597098946106
},
{
"seq": 300,
"t": 104517.463400824,
"age_ms": 241.15040600008797
}
],
"fresh_video_updates_per_second": 12.4,
"motion_to_decoded_marker_ms": {
"p50": 206.37856698886026,
"p95": 294.4065740011865,
"maximum": 369.3924030085327
},
"frame_gap_ms": {
"p50": 83.12560399645008,
"p95": 147.66574700479396,
"maximum": 191.3797620072728
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
}

View File

@ -0,0 +1,421 @@
{
"pid": 354371,
"sent": 300,
"elapsed": 5.965802310995059,
"frames": [
{
"seq": 0,
"t": 106125.563317136,
"age_ms": null
},
{
"seq": 1,
"t": 106125.714375512,
"age_ms": 151.8925330019556
},
{
"seq": 4,
"t": 106125.749306594,
"age_ms": 136.80098700569943
},
{
"seq": 6,
"t": 106125.821857897,
"age_ms": 176.10760599200148
},
{
"seq": 10,
"t": 106125.878653244,
"age_ms": 163.65532200143207
},
{
"seq": 14,
"t": 106125.941070989,
"age_ms": 161.94938200351316
},
{
"seq": 15,
"t": 106125.973142894,
"age_ms": 177.1826769981999
},
{
"seq": 19,
"t": 106126.037015165,
"age_ms": 174.32379099773243
},
{
"seq": 23,
"t": 106126.091339831,
"age_ms": 161.95229899312835
},
{
"seq": 27,
"t": 106126.161715324,
"age_ms": 165.82442399521824
},
{
"seq": 30,
"t": 106126.243443236,
"age_ms": 197.618082005647
},
{
"seq": 35,
"t": 106126.292928912,
"age_ms": 163.7372799887089
},
{
"seq": 38,
"t": 106126.393147834,
"age_ms": 214.06423900043592
},
{
"seq": 40,
"t": 106126.460498776,
"age_ms": 246.99188499653246
},
{
"seq": 45,
"t": 106126.506483739,
"age_ms": 210.74756600137334
},
{
"seq": 49,
"t": 106126.558515346,
"age_ms": 195.6083539989777
},
{
"seq": 54,
"t": 106126.611094405,
"age_ms": 165.05193199554924
},
{
"seq": 56,
"t": 106126.660565498,
"age_ms": 180.8705959992949
},
{
"seq": 60,
"t": 106126.757307082,
"age_ms": 211.40385000035167
},
{
"seq": 65,
"t": 106126.816025658,
"age_ms": 186.94115499965847
},
{
"seq": 70,
"t": 106126.877746619,
"age_ms": 165.35134500009008
},
{
"seq": 71,
"t": 106126.921906811,
"age_ms": 192.67438499082346
},
{
"seq": 74,
"t": 106126.96888068,
"age_ms": 189.77524900401477
},
{
"seq": 77,
"t": 106127.017848945,
"age_ms": 188.69784400158096
},
{
"seq": 81,
"t": 106127.074083131,
"age_ms": 178.1332079990534
},
{
"seq": 84,
"t": 106127.171377709,
"age_ms": 225.33719999773894
},
{
"seq": 90,
"t": 106127.218476994,
"age_ms": 172.71351600356866
},
{
"seq": 94,
"t": 106127.282473805,
"age_ms": 169.98646200227086
},
{
"seq": 98,
"t": 106127.368655127,
"age_ms": 189.55737599753775
},
{
"seq": 102,
"t": 106127.432980935,
"age_ms": 187.2170679998817
},
{
"seq": 106,
"t": 106127.515914292,
"age_ms": 203.32652000070084
},
{
"seq": 111,
"t": 106127.567239198,
"age_ms": 171.3380310102366
},
{
"seq": 115,
"t": 106127.631536423,
"age_ms": 169.0268889942672
},
{
"seq": 120,
"t": 106127.707620062,
"age_ms": 161.641385013354
},
{
"seq": 127,
"t": 106127.815789315,
"age_ms": 153.22135100723244
},
{
"seq": 130,
"t": 106127.874282727,
"age_ms": 161.84380000049714
},
{
"seq": 133,
"t": 106127.931842816,
"age_ms": 169.38884400587995
},
{
"seq": 138,
"t": 106128.013466603,
"age_ms": 167.70273601287045
},
{
"seq": 141,
"t": 106128.044233606,
"age_ms": 148.4322359901853
},
{
"seq": 145,
"t": 106128.137089648,
"age_ms": 174.65745299705304
},
{
"seq": 149,
"t": 106128.197354332,
"age_ms": 168.1769810093101
},
{
"seq": 153,
"t": 106128.277546344,
"age_ms": 181.73671000113245
},
{
"seq": 154,
"t": 106128.331110642,
"age_ms": 218.22410900495015
},
{
"seq": 160,
"t": 106128.405224969,
"age_ms": 192.82984000165015
},
{
"seq": 164,
"t": 106128.511843363,
"age_ms": 232.710953001515
},
{
"seq": 165,
"t": 106128.549592498,
"age_ms": 253.84868300170638
},
{
"seq": 171,
"t": 106128.594834178,
"age_ms": 198.86777600913774
},
{
"seq": 177,
"t": 106128.66914042,
"age_ms": 173.21013599575963
},
{
"seq": 180,
"t": 106128.731889494,
"age_ms": 185.88008199003525
},
{
"seq": 183,
"t": 106128.790431905,
"age_ms": 194.43107300321572
},
{
"seq": 187,
"t": 106128.853490435,
"age_ms": 190.642948000459
},
{
"seq": 191,
"t": 106128.922401651,
"age_ms": 192.91196500125807
},
{
"seq": 192,
"t": 106129.000728766,
"age_ms": 254.81375599338207
},
{
"seq": 197,
"t": 106129.046423399,
"age_ms": 216.86658200633246
},
{
"seq": 201,
"t": 106129.163282474,
"age_ms": 267.04729099583346
},
{
"seq": 207,
"t": 106129.245888292,
"age_ms": 249.72814400098287
},
{
"seq": 210,
"t": 106129.277642284,
"age_ms": 230.3109369968297
},
{
"seq": 213,
"t": 106129.322393093,
"age_ms": 226.60680899571162
},
{
"seq": 218,
"t": 106129.408518708,
"age_ms": 229.4254459993681
},
{
"seq": 224,
"t": 106129.495256232,
"age_ms": 216.1567969887983
},
{
"seq": 228,
"t": 106129.536706286,
"age_ms": 190.93461100419518
},
{
"seq": 230,
"t": 106129.586514541,
"age_ms": 207.26135199947748
},
{
"seq": 235,
"t": 106129.648752037,
"age_ms": 186.0731630004011
},
{
"seq": 238,
"t": 106129.708485019,
"age_ms": 195.9757230069954
},
{
"seq": 243,
"t": 106129.772917867,
"age_ms": 177.09225999715272
},
{
"seq": 246,
"t": 106129.827104283,
"age_ms": 181.23534000187647
},
{
"seq": 250,
"t": 106129.91438226,
"age_ms": 201.94811699911952
},
{
"seq": 256,
"t": 106129.970676528,
"age_ms": 158.1014629919082
},
{
"seq": 258,
"t": 106130.02146594,
"age_ms": 175.6849829980638
},
{
"seq": 262,
"t": 106130.103489306,
"age_ms": 190.86286099627614
},
{
"seq": 263,
"t": 106130.151932284,
"age_ms": 222.61918500589672
},
{
"seq": 270,
"t": 106130.214829523,
"age_ms": 169.0382619999582
},
{
"seq": 273,
"t": 106130.266302302,
"age_ms": 162.1599609934492
},
{
"seq": 276,
"t": 106130.326758901,
"age_ms": 180.80601100518834
},
{
"seq": 281,
"t": 106130.390516547,
"age_ms": 161.41096901264973
},
{
"seq": 284,
"t": 106130.443561976,
"age_ms": 164.49706100684125
},
{
"seq": 289,
"t": 106130.503064543,
"age_ms": 140.13586498913355
},
{
"seq": 292,
"t": 106130.579826008,
"age_ms": 167.37519700836856
},
{
"seq": 295,
"t": 106130.61713619,
"age_ms": 154.48571099841502
},
{
"seq": 300,
"t": 106130.723035424,
"age_ms": 177.01467699953355
}
],
"fresh_video_updates_per_second": 15.4,
"motion_to_decoded_marker_ms": {
"p50": 181.23534000187647,
"p95": 249.72814400098287,
"maximum": 267.04729099583346
},
"frame_gap_ms": {
"p50": 61.72096099180635,
"p95": 106.61839399836026,
"maximum": 151.05837601004168
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
}

View File

@ -0,0 +1,391 @@
{
"pid": 34534,
"sent": 300,
"elapsed": 6.0406107769999835,
"frames": [
{
"seq": 0,
"t": 3431.244445763,
"age_ms": null
},
{
"seq": 4,
"t": 3431.461263847,
"age_ms": 172.3552179996659
},
{
"seq": 6,
"t": 3431.493808798,
"age_ms": 172.23155600004247
},
{
"seq": 9,
"t": 3431.577781054,
"age_ms": 206.21495099976528
},
{
"seq": 14,
"t": 3431.602662177,
"age_ms": 140.2410420000706
},
{
"seq": 18,
"t": 3431.710441389,
"age_ms": 188.83929000003263
},
{
"seq": 23,
"t": 3431.793798835,
"age_ms": 182.29074999999284
},
{
"seq": 27,
"t": 3431.860748916,
"age_ms": 189.01282399974662
},
{
"seq": 31,
"t": 3431.943923787,
"age_ms": 205.59285100034685
},
{
"seq": 36,
"t": 3431.990334328,
"age_ms": 168.25775099960083
},
{
"seq": 39,
"t": 3432.077464922,
"age_ms": 205.77047000006132
},
{
"seq": 45,
"t": 3432.143944271,
"age_ms": 171.88419499962038
},
{
"seq": 46,
"t": 3432.193929341,
"age_ms": 201.2387290001243
},
{
"seq": 51,
"t": 3432.277223499,
"age_ms": 198.89731899957042
},
{
"seq": 56,
"t": 3432.326931788,
"age_ms": 171.98773299969616
},
{
"seq": 60,
"t": 3432.443708278,
"age_ms": 222.12767100018027
},
{
"seq": 61,
"t": 3432.493954963,
"age_ms": 255.37493000001632
},
{
"seq": 67,
"t": 3432.523106796,
"age_ms": 184.65374399966095
},
{
"seq": 71,
"t": 3432.593761192,
"age_ms": 188.33385199968689
},
{
"seq": 73,
"t": 3432.644055417,
"age_ms": 199.60400099989783
},
{
"seq": 76,
"t": 3432.710660178,
"age_ms": 215.88566300033563
},
{
"seq": 80,
"t": 3432.777038614,
"age_ms": 222.14312899996003
},
{
"seq": 83,
"t": 3432.843847534,
"age_ms": 238.76107099977162
},
{
"seq": 87,
"t": 3432.894341543,
"age_ms": 222.06788299990876
},
{
"seq": 91,
"t": 3432.944063248,
"age_ms": 205.58497799993347
},
{
"seq": 95,
"t": 3432.976939229,
"age_ms": 171.92502799980502
},
{
"seq": 98,
"t": 3433.060685162,
"age_ms": 205.7812630000626
},
{
"seq": 101,
"t": 3433.144084025,
"age_ms": 239.19068100030927
},
{
"seq": 107,
"t": 3433.194192174,
"age_ms": 189.06940799979566
},
{
"seq": 112,
"t": 3433.277305798,
"age_ms": 189.0250759997798
},
{
"seq": 116,
"t": 3433.343900936,
"age_ms": 188.48463999984233
},
{
"seq": 120,
"t": 3433.394165412,
"age_ms": 172.6255849998779
},
{
"seq": 125,
"t": 3433.493910977,
"age_ms": 188.51992999998402
},
{
"seq": 130,
"t": 3433.577120848,
"age_ms": 181.59982199995284
},
{
"seq": 131,
"t": 3433.610360523,
"age_ms": 183.59445299984145
},
{
"seq": 138,
"t": 3433.693979586,
"age_ms": 172.39284399965982
},
{
"seq": 142,
"t": 3433.794087387,
"age_ms": 205.4382760002227
},
{
"seq": 146,
"t": 3433.860823978,
"age_ms": 205.23615999991307
},
{
"seq": 152,
"t": 3433.944030349,
"age_ms": 189.14144800010035
},
{
"seq": 156,
"t": 3433.993801053,
"age_ms": 172.22631000004185
},
{
"seq": 161,
"t": 3434.060665388,
"age_ms": 155.32808699981615
},
{
"seq": 164,
"t": 3434.160480952,
"age_ms": 204.94625599985739
},
{
"seq": 168,
"t": 3434.227263041,
"age_ms": 205.68851899997753
},
{
"seq": 172,
"t": 3434.310492745,
"age_ms": 222.25396299973
},
{
"seq": 175,
"t": 3434.377123464,
"age_ms": 215.89412399998764
},
{
"seq": 182,
"t": 3434.477372428,
"age_ms": 222.4764959996719
},
{
"seq": 187,
"t": 3434.560593674,
"age_ms": 222.19475699967006
},
{
"seq": 192,
"t": 3434.6106537,
"age_ms": 189.07553500002905
},
{
"seq": 197,
"t": 3434.710504554,
"age_ms": 205.62785500032987
},
{
"seq": 198,
"t": 3434.760702824,
"age_ms": 238.46066999976756
},
{
"seq": 202,
"t": 3434.827379917,
"age_ms": 217.65514000026087
},
{
"seq": 209,
"t": 3434.933724479,
"age_ms": 222.29071099991415
},
{
"seq": 213,
"t": 3435.027398947,
"age_ms": 255.79841900025713
},
{
"seq": 217,
"t": 3435.077319854,
"age_ms": 239.01306700008718
},
{
"seq": 223,
"t": 3435.144122359,
"age_ms": 199.344432000089
},
{
"seq": 229,
"t": 3435.260626155,
"age_ms": 222.42049999977098
},
{
"seq": 232,
"t": 3435.294209983,
"age_ms": 205.85418000018763
},
{
"seq": 237,
"t": 3435.394271997,
"age_ms": 222.29362999996738
},
{
"seq": 241,
"t": 3435.443899206,
"age_ms": 184.16872499983583
},
{
"seq": 246,
"t": 3435.527625017,
"age_ms": 205.94575999984954
},
{
"seq": 247,
"t": 3435.547092141,
"age_ms": 208.79844199998843
},
{
"seq": 253,
"t": 3435.660602676,
"age_ms": 215.84337800004505
},
{
"seq": 256,
"t": 3435.727331976,
"age_ms": 238.4364640001877
},
{
"seq": 258,
"t": 3435.777296048,
"age_ms": 248.30200099995636
},
{
"seq": 264,
"t": 3435.827309993,
"age_ms": 205.18891500023528
},
{
"seq": 266,
"t": 3435.927812406,
"age_ms": 266.4240100002644
},
{
"seq": 268,
"t": 3435.977364952,
"age_ms": 288.6516519997713
},
{
"seq": 277,
"t": 3436.027469019,
"age_ms": 188.94575100011934
},
{
"seq": 280,
"t": 3436.110579437,
"age_ms": 221.74765199997637
},
{
"seq": 286,
"t": 3436.177311071,
"age_ms": 188.751800999853
},
{
"seq": 290,
"t": 3436.244002164,
"age_ms": 188.9267930000642
},
{
"seq": 295,
"t": 3436.287856347,
"age_ms": 149.54923000004783
},
{
"seq": 297,
"t": 3436.367445318,
"age_ms": 189.14145200005805
},
{
"seq": 300,
"t": 3436.473359398,
"age_ms": 230.2628239999649
}
],
"fresh_video_updates_per_second": 14.0,
"motion_to_decoded_marker_ms": {
"p50": 205.23615999991307,
"p95": 255.37493000001632,
"maximum": 288.6516519997713
},
"frame_gap_ms": {
"p50": 66.78208899984384,
"p95": 113.51053499993213,
"maximum": 216.81808399989677
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
}

View File

@ -0,0 +1,391 @@
{
"pid": 36868,
"sent": 300,
"elapsed": 5.9589984410004035,
"frames": [
{
"seq": 0,
"t": 3640.386110834,
"age_ms": null
},
{
"seq": 1,
"t": 3640.519373332,
"age_ms": 134.4022890002634
},
{
"seq": 3,
"t": 3640.602775811,
"age_ms": 180.1231290000942
},
{
"seq": 7,
"t": 3640.686827223,
"age_ms": 202.1667660001185
},
{
"seq": 12,
"t": 3640.719559755,
"age_ms": 151.21741299981295
},
{
"seq": 16,
"t": 3640.886160553,
"age_ms": 251.06752900001084
},
{
"seq": 21,
"t": 3640.952684036,
"age_ms": 232.05332099996667
},
{
"seq": 28,
"t": 3641.019270224,
"age_ms": 184.72633300007146
},
{
"seq": 31,
"t": 3641.08601974,
"age_ms": 197.41423599998598
},
{
"seq": 33,
"t": 3641.136477653,
"age_ms": 218.50386699998126
},
{
"seq": 39,
"t": 3641.253744581,
"age_ms": 233.55622400003995
},
{
"seq": 44,
"t": 3641.302773964,
"age_ms": 201.0841410001376
},
{
"seq": 48,
"t": 3641.352620567,
"age_ms": 184.09052300012263
},
{
"seq": 54,
"t": 3641.419806983,
"age_ms": 151.48398700011967
},
{
"seq": 58,
"t": 3641.469275309,
"age_ms": 134.2054219999227
},
{
"seq": 61,
"t": 3641.550360582,
"age_ms": 165.7757049997599
},
{
"seq": 66,
"t": 3641.602734675,
"age_ms": 132.61152300037793
},
{
"seq": 68,
"t": 3641.669524731,
"age_ms": 168.2404889997997
},
{
"seq": 72,
"t": 3641.735955758,
"age_ms": 168.02757899995413
},
{
"seq": 76,
"t": 3641.825930701,
"age_ms": 191.08063799967567
},
{
"seq": 80,
"t": 3641.886014715,
"age_ms": 184.69220999986646
},
{
"seq": 84,
"t": 3641.942853183,
"age_ms": 174.62308499989376
},
{
"seq": 88,
"t": 3642.01955662,
"age_ms": 180.3497470000366
},
{
"seq": 92,
"t": 3642.069425098,
"age_ms": 168.1019530001322
},
{
"seq": 97,
"t": 3642.151479252,
"age_ms": 166.5138860003026
},
{
"seq": 102,
"t": 3642.236618834,
"age_ms": 166.25868800019816
},
{
"seq": 104,
"t": 3642.303523803,
"age_ms": 202.06527200025448
},
{
"seq": 110,
"t": 3642.383756275,
"age_ms": 181.81065099997795
},
{
"seq": 114,
"t": 3642.452824163,
"age_ms": 184.7937060001641
},
{
"seq": 115,
"t": 3642.502808136,
"age_ms": 200.88727400025164
},
{
"seq": 122,
"t": 3642.56962765,
"age_ms": 168.23873899966202
},
{
"seq": 126,
"t": 3642.636211214,
"age_ms": 168.06987100017068
},
{
"seq": 130,
"t": 3642.736057248,
"age_ms": 201.29267600032108
},
{
"seq": 133,
"t": 3642.786491538,
"age_ms": 201.8608220000715
},
{
"seq": 138,
"t": 3642.869465575,
"age_ms": 201.49245999982668
},
{
"seq": 142,
"t": 3642.936706531,
"age_ms": 199.6734029999061
},
{
"seq": 147,
"t": 3642.970636602,
"age_ms": 152.74627400003737
},
{
"seq": 151,
"t": 3643.103158296,
"age_ms": 218.58144999987417
},
{
"seq": 155,
"t": 3643.186588192,
"age_ms": 217.62627699990844
},
{
"seq": 161,
"t": 3643.219949826,
"age_ms": 168.2127830003992
},
{
"seq": 166,
"t": 3643.386168849,
"age_ms": 248.8666980002563
},
{
"seq": 167,
"t": 3643.419431903,
"age_ms": 267.89432299983673
},
{
"seq": 172,
"t": 3643.469876985,
"age_ms": 235.0979190000544
},
{
"seq": 174,
"t": 3643.536069147,
"age_ms": 264.59336400012035
},
{
"seq": 181,
"t": 3643.586186115,
"age_ms": 199.1352990003179
},
{
"seq": 184,
"t": 3643.652388194,
"age_ms": 217.85114400017846
},
{
"seq": 188,
"t": 3643.719702647,
"age_ms": 218.2440039996436
},
{
"seq": 191,
"t": 3643.769954944,
"age_ms": 218.46157999971183
},
{
"seq": 196,
"t": 3643.836222937,
"age_ms": 201.32009300004938
},
{
"seq": 201,
"t": 3643.90293833,
"age_ms": 182.37821499997153
},
{
"seq": 206,
"t": 3643.969618141,
"age_ms": 167.77938299992456
},
{
"seq": 210,
"t": 3644.069398845,
"age_ms": 201.0048139995888
},
{
"seq": 214,
"t": 3644.13643331,
"age_ms": 201.597750000019
},
{
"seq": 220,
"t": 3644.252838979,
"age_ms": 218.2553799998459
},
{
"seq": 227,
"t": 3644.319017434,
"age_ms": 167.78171700025268
},
{
"seq": 228,
"t": 3644.386198309,
"age_ms": 217.88031100004446
},
{
"seq": 231,
"t": 3644.486060386,
"age_ms": 268.07806900023934
},
{
"seq": 234,
"t": 3644.536142939,
"age_ms": 233.4952709998106
},
{
"seq": 242,
"t": 3644.569764438,
"age_ms": 168.36531900025875
},
{
"seq": 245,
"t": 3644.653021966,
"age_ms": 201.83865799981504
},
{
"seq": 247,
"t": 3644.703262597,
"age_ms": 216.3491179999255
},
{
"seq": 250,
"t": 3644.722097729,
"age_ms": 185.04074099973877
},
{
"seq": 251,
"t": 3644.836617552,
"age_ms": 267.9818219999106
},
{
"seq": 258,
"t": 3644.953858233,
"age_ms": 285.3023870002289
},
{
"seq": 263,
"t": 3644.98666922,
"age_ms": 235.29682999969737
},
{
"seq": 267,
"t": 3645.036247501,
"age_ms": 198.78414699996938
},
{
"seq": 270,
"t": 3645.069559845,
"age_ms": 201.00598099998024
},
{
"seq": 274,
"t": 3645.136220116,
"age_ms": 184.05027900007553
},
{
"seq": 279,
"t": 3645.219745967,
"age_ms": 184.3165600002976
},
{
"seq": 283,
"t": 3645.26959578,
"age_ms": 185.01186799994684
},
{
"seq": 288,
"t": 3645.353489409,
"age_ms": 185.59401299989986
},
{
"seq": 292,
"t": 3645.412158018,
"age_ms": 177.5848520001091
},
{
"seq": 296,
"t": 3645.48232895,
"age_ms": 180.9187710000515
},
{
"seq": 300,
"t": 3645.539078755,
"age_ms": 171.13896699993347
}
],
"fresh_video_updates_per_second": 14.2,
"motion_to_decoded_marker_ms": {
"p50": 197.41423599998598,
"p95": 267.89432299983673,
"maximum": 285.3023870002289
},
"frame_gap_ms": {
"p50": 66.67981100008546,
"p95": 132.52169399993363,
"maximum": 166.60079800021776
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
}

View File

@ -0,0 +1,441 @@
{
"pid": 35562,
"sent": 300,
"elapsed": 6.017804186000376,
"frames": [
{
"seq": 0,
"t": 3536.620144655,
"age_ms": null
},
{
"seq": 1,
"t": 3536.814883409,
"age_ms": 196.04478799965364
},
{
"seq": 5,
"t": 3536.865073259,
"age_ms": 167.73844199997257
},
{
"seq": 10,
"t": 3536.948258403,
"age_ms": 179.12438700022904
},
{
"seq": 13,
"t": 3537.015249368,
"age_ms": 196.2264909998339
},
{
"seq": 17,
"t": 3537.097523087,
"age_ms": 211.9371039998441
},
{
"seq": 21,
"t": 3537.164810374,
"age_ms": 212.40958599992155
},
{
"seq": 26,
"t": 3537.220110615,
"age_ms": 184.36631500026124
},
{
"seq": 28,
"t": 3537.281839237,
"age_ms": 212.57670500017412
},
{
"seq": 31,
"t": 3537.365558111,
"age_ms": 246.66220700009944
},
{
"seq": 35,
"t": 3537.415416932,
"age_ms": 229.73451400002887
},
{
"seq": 36,
"t": 3537.449159155,
"age_ms": 246.3244699997631
},
{
"seq": 42,
"t": 3537.481623052,
"age_ms": 178.97855999990497
},
{
"seq": 43,
"t": 3537.531908274,
"age_ms": 212.8173220003191
},
{
"seq": 46,
"t": 3537.598891364,
"age_ms": 229.01879199980613
},
{
"seq": 48,
"t": 3537.631467839,
"age_ms": 215.03536199998052
},
{
"seq": 53,
"t": 3537.681592942,
"age_ms": 195.88962799980436
},
{
"seq": 57,
"t": 3537.748287293,
"age_ms": 195.9409589999268
},
{
"seq": 62,
"t": 3537.798581557,
"age_ms": 162.83571299982214
},
{
"seq": 66,
"t": 3537.949134193,
"age_ms": 246.6181670001788
},
{
"seq": 71,
"t": 3537.981714752,
"age_ms": 184.30827599968325
},
{
"seq": 72,
"t": 3538.031659029,
"age_ms": 229.41952700011825
},
{
"seq": 78,
"t": 3538.082010749,
"age_ms": 178.810859999885
},
{
"seq": 82,
"t": 3538.148348114,
"age_ms": 167.53107799968348
},
{
"seq": 84,
"t": 3538.215343745,
"age_ms": 212.66187000037462
},
{
"seq": 85,
"t": 3538.298310148,
"age_ms": 267.565459999787
},
{
"seq": 90,
"t": 3538.331726008,
"age_ms": 229.3749039999966
},
{
"seq": 93,
"t": 3538.381578122,
"age_ms": 228.9849610001511
},
{
"seq": 94,
"t": 3538.431567022,
"age_ms": 262.6405619998877
},
{
"seq": 99,
"t": 3538.481737916,
"age_ms": 228.9499620001152
},
{
"seq": 104,
"t": 3538.532109468,
"age_ms": 195.71026099993105
},
{
"seq": 107,
"t": 3538.598420876,
"age_ms": 212.85611300027085
},
{
"seq": 110,
"t": 3538.666771831,
"age_ms": 231.00555100018028
},
{
"seq": 114,
"t": 3538.698401884,
"age_ms": 195.13919899964094
},
{
"seq": 120,
"t": 3538.764949533,
"age_ms": 162.70388500015542
},
{
"seq": 121,
"t": 3538.815146675,
"age_ms": 196.05733100024736
},
{
"seq": 125,
"t": 3538.848538912,
"age_ms": 151.06507600012264
},
{
"seq": 127,
"t": 3538.898356027,
"age_ms": 179.4002950000504
},
{
"seq": 129,
"t": 3538.948557836,
"age_ms": 184.40189800003282
},
{
"seq": 134,
"t": 3539.015454889,
"age_ms": 168.0350599999656
},
{
"seq": 137,
"t": 3539.081556305,
"age_ms": 184.1154930002631
},
{
"seq": 142,
"t": 3539.131946232,
"age_ms": 162.97366799972224
},
{
"seq": 143,
"t": 3539.164969233,
"age_ms": 178.9348140000584
},
{
"seq": 146,
"t": 3539.231701208,
"age_ms": 196.0328339996522
},
{
"seq": 151,
"t": 3539.28183652,
"age_ms": 150.95570599987695
},
{
"seq": 152,
"t": 3539.36490821,
"age_ms": 228.91642300010062
},
{
"seq": 156,
"t": 3539.403856195,
"age_ms": 201.30859200025952
},
{
"seq": 159,
"t": 3539.465066838,
"age_ms": 212.45683799998005
},
{
"seq": 163,
"t": 3539.521298919,
"age_ms": 202.32530400016913
},
{
"seq": 167,
"t": 3539.564986016,
"age_ms": 178.99314500027685
},
{
"seq": 174,
"t": 3539.631711867,
"age_ms": 129.02699400001438
},
{
"seq": 177,
"t": 3539.715022132,
"age_ms": 150.9297479997258
},
{
"seq": 180,
"t": 3539.78181623,
"age_ms": 178.8400260002163
},
{
"seq": 184,
"t": 3539.837261716,
"age_ms": 156.23292299960667
},
{
"seq": 188,
"t": 3539.915345804,
"age_ms": 179.68466100001024
},
{
"seq": 193,
"t": 3540.065381629,
"age_ms": 245.27509700010341
},
{
"seq": 196,
"t": 3540.164939738,
"age_ms": 296.0185110000566
},
{
"seq": 204,
"t": 3540.198514843,
"age_ms": 196.2652839997645
},
{
"seq": 209,
"t": 3540.299446067,
"age_ms": 212.7537440001106
},
{
"seq": 214,
"t": 3540.331958088,
"age_ms": 161.82571300032578
},
{
"seq": 216,
"t": 3540.398769686,
"age_ms": 196.42248799982553
},
{
"seq": 220,
"t": 3540.448549469,
"age_ms": 178.3809610001299
},
{
"seq": 221,
"t": 3540.482114366,
"age_ms": 184.0417050002543
},
{
"seq": 225,
"t": 3540.548644517,
"age_ms": 196.15066400001524
},
{
"seq": 231,
"t": 3540.629612204,
"age_ms": 175.98646799979178
},
{
"seq": 234,
"t": 3540.698265899,
"age_ms": 195.91996400004064
},
{
"seq": 238,
"t": 3540.764972501,
"age_ms": 195.91938100029438
},
{
"seq": 240,
"t": 3540.799238538,
"age_ms": 196.48665099975915
},
{
"seq": 243,
"t": 3540.831778557,
"age_ms": 179.49158499959594
},
{
"seq": 247,
"t": 3540.915131988,
"age_ms": 196.2151200000335
},
{
"seq": 252,
"t": 3540.94839823,
"age_ms": 146.04568499999004
},
{
"seq": 256,
"t": 3541.031627416,
"age_ms": 162.32473599984587
},
{
"seq": 258,
"t": 3541.109307562,
"age_ms": 193.32685600011246
},
{
"seq": 263,
"t": 3541.165125784,
"age_ms": 179.53125199983333
},
{
"seq": 267,
"t": 3541.231790388,
"age_ms": 179.26876199999242
},
{
"seq": 270,
"t": 3541.298284373,
"age_ms": 182.62805099993784
},
{
"seq": 275,
"t": 3541.348325189,
"age_ms": 162.70272200017644
},
{
"seq": 279,
"t": 3541.415016334,
"age_ms": 162.76163700013058
},
{
"seq": 282,
"t": 3541.480711474,
"age_ms": 178.45212600013838
},
{
"seq": 287,
"t": 3541.564962622,
"age_ms": 178.97010700016835
},
{
"seq": 290,
"t": 3541.63167564,
"age_ms": 195.87796700034232
},
{
"seq": 294,
"t": 3541.707457108,
"age_ms": 204.93854200003625
},
{
"seq": 299,
"t": 3541.778955904,
"age_ms": 193.3583540003383
},
{
"seq": 300,
"t": 3541.832077187,
"age_ms": 201.21118299994123
}
],
"fresh_video_updates_per_second": 16.0,
"motion_to_decoded_marker_ms": {
"p50": 195.87796700034232,
"p95": 246.6181670001788,
"maximum": 296.0185110000566
},
"frame_gap_ms": {
"p50": 65.69514000011623,
"p95": 99.55810900009965,
"maximum": 194.73875399989993
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
}

View File

@ -0,0 +1,426 @@
{
"pid": 352658,
"sent": 300,
"elapsed": 5.995556267997017,
"frames": [
{
"seq": 0,
"t": 105822.364914285,
"age_ms": null
},
{
"seq": 1,
"t": 105822.585777361,
"age_ms": 222.01077300996985
},
{
"seq": 2,
"t": 105822.633395286,
"age_ms": 252.87143999594264
},
{
"seq": 7,
"t": 105822.689622253,
"age_ms": 226.022027010913
},
{
"seq": 10,
"t": 105822.742185339,
"age_ms": 228.2570469978964
},
{
"seq": 16,
"t": 105822.79771698,
"age_ms": 183.7351360009052
},
{
"seq": 21,
"t": 105822.861982205,
"age_ms": 164.93943899695296
},
{
"seq": 23,
"t": 105822.950869113,
"age_ms": 220.40866300812922
},
{
"seq": 28,
"t": 105823.019618087,
"age_ms": 205.75517599354498
},
{
"seq": 33,
"t": 105823.121072793,
"age_ms": 224.04250300314743
},
{
"seq": 37,
"t": 105823.175335695,
"age_ms": 211.7217440099921
},
{
"seq": 40,
"t": 105823.237644438,
"age_ms": 223.70738101017196
},
{
"seq": 42,
"t": 105823.324132994,
"age_ms": 277.0209180016536
},
{
"seq": 45,
"t": 105823.382827147,
"age_ms": 285.76791899104137
},
{
"seq": 51,
"t": 105823.455156878,
"age_ms": 258.1867209955817
},
{
"seq": 57,
"t": 105823.514103903,
"age_ms": 216.88186199753545
},
{
"seq": 60,
"t": 105823.561138791,
"age_ms": 214.07255600206554
},
{
"seq": 63,
"t": 105823.605551037,
"age_ms": 208.5913160117343
},
{
"seq": 67,
"t": 105823.659636816,
"age_ms": 196.04647599044256
},
{
"seq": 73,
"t": 105823.753416386,
"age_ms": 189.77045199426357
},
{
"seq": 76,
"t": 105823.803806576,
"age_ms": 190.11899099859875
},
{
"seq": 79,
"t": 105823.869725451,
"age_ms": 205.90471600007731
},
{
"seq": 83,
"t": 105823.95639163,
"age_ms": 225.8787350001512
},
{
"seq": 87,
"t": 105824.013852919,
"age_ms": 216.4352410036372
},
{
"seq": 92,
"t": 105824.094019076,
"age_ms": 213.65897500072606
},
{
"seq": 97,
"t": 105824.13580518,
"age_ms": 172.12632700102404
},
{
"seq": 98,
"t": 105824.193087387,
"age_ms": 212.82773300481495
},
{
"seq": 101,
"t": 105824.254351098,
"age_ms": 224.0923759964062
},
{
"seq": 104,
"t": 105824.286978663,
"age_ms": 206.35425200453028
},
{
"seq": 110,
"t": 105824.342255098,
"age_ms": 161.75242500321474
},
{
"seq": 114,
"t": 105824.421301557,
"age_ms": 174.21901499619707
},
{
"seq": 117,
"t": 105824.498500034,
"age_ms": 201.53275699703954
},
{
"seq": 121,
"t": 105824.540304513,
"age_ms": 176.58061899419408
},
{
"seq": 125,
"t": 105824.61779757,
"age_ms": 187.53464000474196
},
{
"seq": 130,
"t": 105824.683076618,
"age_ms": 169.4389360054629
},
{
"seq": 131,
"t": 105824.726741037,
"age_ms": 196.3230559922522
},
{
"seq": 134,
"t": 105824.773524511,
"age_ms": 193.21187799505424
},
{
"seq": 136,
"t": 105824.822325131,
"age_ms": 208.38627500052098
},
{
"seq": 139,
"t": 105824.870169386,
"age_ms": 206.38254401274025
},
{
"seq": 142,
"t": 105824.917264065,
"age_ms": 203.22382400627248
},
{
"seq": 145,
"t": 105824.98236753,
"age_ms": 218.49155299423728
},
{
"seq": 148,
"t": 105825.0198443,
"age_ms": 205.89196399669163
},
{
"seq": 151,
"t": 105825.071297604,
"age_ms": 207.4841579888016
},
{
"seq": 155,
"t": 105825.137494809,
"age_ms": 207.23215899488423
},
{
"seq": 159,
"t": 105825.178862375,
"age_ms": 181.62698599917348
},
{
"seq": 160,
"t": 105825.244621502,
"age_ms": 230.6874790083384
},
{
"seq": 163,
"t": 105825.306028419,
"age_ms": 242.21345300611574
},
{
"seq": 169,
"t": 105825.375719467,
"age_ms": 211.78678300930187
},
{
"seq": 175,
"t": 105825.477803874,
"age_ms": 214.2023440101184
},
{
"seq": 179,
"t": 105825.526652619,
"age_ms": 196.3563049939694
},
{
"seq": 181,
"t": 105825.608244429,
"age_ms": 244.46072398859542
},
{
"seq": 186,
"t": 105825.680501243,
"age_ms": 233.48074399109464
},
{
"seq": 189,
"t": 105825.728851535,
"age_ms": 231.71705300046597
},
{
"seq": 192,
"t": 105825.786867276,
"age_ms": 239.71972599974833
},
{
"seq": 195,
"t": 105825.858277224,
"age_ms": 261.23618900601286
},
{
"seq": 200,
"t": 105825.918178281,
"age_ms": 236.96246100007556
},
{
"seq": 202,
"t": 105825.991665917,
"age_ms": 277.66999100276735
},
{
"seq": 206,
"t": 105826.046724269,
"age_ms": 266.1855160113191
},
{
"seq": 211,
"t": 105826.100238761,
"age_ms": 236.50946401176043
},
{
"seq": 215,
"t": 105826.147476938,
"age_ms": 217.01610699528828
},
{
"seq": 217,
"t": 105826.203798987,
"age_ms": 239.63930900208652
},
{
"seq": 220,
"t": 105826.257033774,
"age_ms": 243.18652600049973
},
{
"seq": 226,
"t": 105826.303624165,
"age_ms": 190.02428000385407
},
{
"seq": 231,
"t": 105826.405311617,
"age_ms": 208.14740000059828
},
{
"seq": 235,
"t": 105826.485612813,
"age_ms": 222.0297260064399
},
{
"seq": 240,
"t": 105826.542371191,
"age_ms": 195.36727099330164
},
{
"seq": 244,
"t": 105826.595525478,
"age_ms": 181.71944200003054
},
{
"seq": 248,
"t": 105826.685236336,
"age_ms": 198.72986499103718
},
{
"seq": 253,
"t": 105826.741214221,
"age_ms": 177.6253559946781
},
{
"seq": 256,
"t": 105826.804943658,
"age_ms": 191.22826900274958
},
{
"seq": 260,
"t": 105826.869890208,
"age_ms": 183.9346290071262
},
{
"seq": 264,
"t": 105826.929818681,
"age_ms": 182.7495990000898
},
{
"seq": 268,
"t": 105827.003753437,
"age_ms": 190.08757000847254
},
{
"seq": 271,
"t": 105827.057522552,
"age_ms": 193.68845300050452
},
{
"seq": 275,
"t": 105827.141712794,
"age_ms": 211.24341098766308
},
{
"seq": 280,
"t": 105827.180840381,
"age_ms": 167.17212100047618
},
{
"seq": 284,
"t": 105827.248257616,
"age_ms": 167.93278099794406
},
{
"seq": 287,
"t": 105827.309382202,
"age_ms": 178.86346799787134
},
{
"seq": 291,
"t": 105827.381741682,
"age_ms": 184.77957899449393
},
{
"seq": 296,
"t": 105827.456995634,
"age_ms": 176.64273899572436
},
{
"seq": 300,
"t": 105827.554913621,
"age_ms": 207.49961299588904
}
],
"fresh_video_updates_per_second": 15.6,
"motion_to_decoded_marker_ms": {
"p50": 207.82350649824366,
"p95": 266.1855160113191,
"maximum": 285.76791899104137
},
"frame_gap_ms": {
"p50": 59.91476499912096,
"p95": 101.45470600400586,
"maximum": 220.8630759996595
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
}

View File

@ -0,0 +1,461 @@
{
"pid": 350123,
"sent": 300,
"elapsed": 6.023475266003516,
"frames": [
{
"seq": 0,
"t": 105660.588609923,
"age_ms": null
},
{
"seq": 1,
"t": 105660.728732414,
"age_ms": 141.1517740052659
},
{
"seq": 4,
"t": 105660.836533842,
"age_ms": 198.7703319900902
},
{
"seq": 5,
"t": 105660.868549532,
"age_ms": 214.22766099567525
},
{
"seq": 12,
"t": 105660.933176781,
"age_ms": 162.11922200454865
},
{
"seq": 16,
"t": 105660.994850055,
"age_ms": 157.3341789917322
},
{
"seq": 17,
"t": 105661.029248641,
"age_ms": 174.83140699914657
},
{
"seq": 21,
"t": 105661.077943732,
"age_ms": 156.695434008725
},
{
"seq": 25,
"t": 105661.168224599,
"age_ms": 180.32752799626905
},
{
"seq": 26,
"t": 105661.208675217,
"age_ms": 203.9161620050436
},
{
"seq": 30,
"t": 105661.265637822,
"age_ms": 194.48724199901335
},
{
"seq": 32,
"t": 105661.319675618,
"age_ms": 215.41969099780545
},
{
"seq": 35,
"t": 105661.429639736,
"age_ms": 275.0498560053529
},
{
"seq": 41,
"t": 105661.455474478,
"age_ms": 200.9788120049052
},
{
"seq": 45,
"t": 105661.497347251,
"age_ms": 176.45801800244953
},
{
"seq": 50,
"t": 105661.578405112,
"age_ms": 173.97303899633698
},
{
"seq": 53,
"t": 105661.621562375,
"age_ms": 167.18922099971678
},
{
"seq": 58,
"t": 105661.695048049,
"age_ms": 157.4301360087702
},
{
"seq": 59,
"t": 105661.740765832,
"age_ms": 185.9015219961293
},
{
"seq": 62,
"t": 105661.787493356,
"age_ms": 182.19709499680903
},
{
"seq": 69,
"t": 105661.845759992,
"age_ms": 124.71561999700498
},
{
"seq": 72,
"t": 105661.908735254,
"age_ms": 137.61592700029723
},
{
"seq": 74,
"t": 105661.988176836,
"age_ms": 183.88741300441325
},
{
"seq": 79,
"t": 105662.09039406,
"age_ms": 202.43375599966384
},
{
"seq": 80,
"t": 105662.132361249,
"age_ms": 227.86475099564996
},
{
"seq": 84,
"t": 105662.155326306,
"age_ms": 183.80145500123035
},
{
"seq": 88,
"t": 105662.212096996,
"age_ms": 174.33811799855903
},
{
"seq": 92,
"t": 105662.271132749,
"age_ms": 166.46639199461788
},
{
"seq": 94,
"t": 105662.316158121,
"age_ms": 178.17154400108848
},
{
"seq": 97,
"t": 105662.371606696,
"age_ms": 183.591831009835
},
{
"seq": 99,
"t": 105662.405071957,
"age_ms": 184.02670299110468
},
{
"seq": 100,
"t": 105662.440496326,
"age_ms": 202.81075399543624
},
{
"seq": 106,
"t": 105662.493489089,
"age_ms": 155.86506499676034
},
{
"seq": 107,
"t": 105662.527463303,
"age_ms": 172.80754700186662
},
{
"seq": 109,
"t": 105662.566961346,
"age_ms": 178.92199600464664
},
{
"seq": 116,
"t": 105662.68981148,
"age_ms": 185.20619299670216
},
{
"seq": 120,
"t": 105662.72076347,
"age_ms": 149.8561990010785
},
{
"seq": 122,
"t": 105662.767262621,
"age_ms": 163.00062999653164
},
{
"seq": 127,
"t": 105662.8539706,
"age_ms": 166.13281199533958
},
{
"seq": 128,
"t": 105662.890777457,
"age_ms": 186.3407670025481
},
{
"seq": 131,
"t": 105662.934899544,
"age_ms": 180.14873498759698
},
{
"seq": 133,
"t": 105662.986473943,
"age_ms": 198.8916600093944
},
{
"seq": 135,
"t": 105663.018901171,
"age_ms": 197.4135060008848
},
{
"seq": 136,
"t": 105663.061461979,
"age_ms": 223.7712000060128
},
{
"seq": 140,
"t": 105663.104748157,
"age_ms": 200.50718799757306
},
{
"seq": 142,
"t": 105663.14064648,
"age_ms": 203.0799579952145
},
{
"seq": 147,
"t": 105663.185304354,
"age_ms": 164.23786799714435
},
{
"seq": 151,
"t": 105663.273962108,
"age_ms": 186.10305899346713
},
{
"seq": 155,
"t": 105663.324079353,
"age_ms": 169.7001559950877
},
{
"seq": 158,
"t": 105663.384112014,
"age_ms": 179.16990899539087
},
{
"seq": 160,
"t": 105663.410937539,
"age_ms": 173.36433299351484
},
{
"seq": 163,
"t": 105663.475446371,
"age_ms": 187.761170003796
},
{
"seq": 168,
"t": 105663.566514438,
"age_ms": 195.42668900976423
},
{
"seq": 172,
"t": 105663.630936646,
"age_ms": 193.3637480105972
},
{
"seq": 175,
"t": 105663.67644968,
"age_ms": 188.81203699856997
},
{
"seq": 177,
"t": 105663.715756391,
"age_ms": 194.76752799528185
},
{
"seq": 180,
"t": 105663.753589031,
"age_ms": 182.69000499276444
},
{
"seq": 184,
"t": 105663.822438993,
"age_ms": 184.85823599621654
},
{
"seq": 186,
"t": 105663.871551163,
"age_ms": 200.2852309960872
},
{
"seq": 190,
"t": 105663.914979381,
"age_ms": 177.12505100644194
},
{
"seq": 191,
"t": 105663.983808926,
"age_ms": 229.52398400229868
},
{
"seq": 193,
"t": 105664.040300492,
"age_ms": 252.6649139908841
},
{
"seq": 198,
"t": 105664.109830323,
"age_ms": 237.5882069900399
},
{
"seq": 201,
"t": 105664.160752478,
"age_ms": 239.84793899580836
},
{
"seq": 202,
"t": 105664.220458183,
"age_ms": 282.8468259976944
},
{
"seq": 207,
"t": 105664.247748328,
"age_ms": 226.65771598985884
},
{
"seq": 213,
"t": 105664.290144346,
"age_ms": 169.0602430026047
},
{
"seq": 215,
"t": 105664.328379066,
"age_ms": 173.7471619999269
},
{
"seq": 220,
"t": 105664.427703271,
"age_ms": 189.75544298882596
},
{
"seq": 224,
"t": 105664.485993239,
"age_ms": 181.2134739884641
},
{
"seq": 228,
"t": 105664.533541797,
"age_ms": 162.6477140089264
},
{
"seq": 232,
"t": 105664.621815428,
"age_ms": 184.23494801390916
},
{
"seq": 237,
"t": 105664.702844704,
"age_ms": 181.76659400342032
},
{
"seq": 242,
"t": 105664.754943515,
"age_ms": 150.48910699260887
},
{
"seq": 246,
"t": 105664.830002425,
"age_ms": 159.09641000325792
},
{
"seq": 250,
"t": 105664.889416466,
"age_ms": 151.0499779979
},
{
"seq": 254,
"t": 105664.954948747,
"age_ms": 150.31352500955109
},
{
"seq": 258,
"t": 105665.044959821,
"age_ms": 173.59241099620704
},
{
"seq": 262,
"t": 105665.103812117,
"age_ms": 165.720977995079
},
{
"seq": 266,
"t": 105665.20514618,
"age_ms": 200.88197400036734
},
{
"seq": 271,
"t": 105665.259916635,
"age_ms": 172.009842004627
},
{
"seq": 273,
"t": 105665.324900878,
"age_ms": 203.94911400217097
},
{
"seq": 277,
"t": 105665.392394018,
"age_ms": 204.61089999298565
},
{
"seq": 285,
"t": 105665.503136293,
"age_ms": 182.03171600180212
},
{
"seq": 289,
"t": 105665.605121641,
"age_ms": 217.33883400156628
},
{
"seq": 293,
"t": 105665.624316355,
"age_ms": 169.64444499171805
},
{
"seq": 297,
"t": 105665.67254799,
"age_ms": 151.6277640039334
},
{
"seq": 300,
"t": 105665.806498277,
"age_ms": 235.17030899529345
}
],
"fresh_video_updates_per_second": 16.8,
"motion_to_decoded_marker_ms": {
"p50": 182.69000499276444,
"p95": 237.5882069900399,
"maximum": 282.8468259976944
},
"frame_gap_ms": {
"p50": 54.770454997196794,
"p95": 109.96411800442729,
"maximum": 140.12249100778718
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
}

View File

@ -0,0 +1,301 @@
{
"pid": 38284,
"sent": 300,
"elapsed": 6.014295583999683,
"frames": [
{
"seq": 0,
"t": 3787.859476511,
"age_ms": null
},
{
"seq": 2,
"t": 3788.092472917,
"age_ms": 226.71267700025055
},
{
"seq": 5,
"t": 3788.175824123,
"age_ms": 260.7124770001974
},
{
"seq": 10,
"t": 3788.275966548,
"age_ms": 277.91959799969845
},
{
"seq": 21,
"t": 3788.409275804,
"age_ms": 227.99071400004323
},
{
"seq": 25,
"t": 3788.499590005,
"age_ms": 251.19836599969858
},
{
"seq": 30,
"t": 3788.576047629,
"age_ms": 244.42028100020252
},
{
"seq": 38,
"t": 3788.676070767,
"age_ms": 211.41036100016208
},
{
"seq": 41,
"t": 3788.809415313,
"age_ms": 294.83360599988373
},
{
"seq": 48,
"t": 3788.842632599,
"age_ms": 211.36836200003017
},
{
"seq": 51,
"t": 3788.993322804,
"age_ms": 311.54462099993907
},
{
"seq": 56,
"t": 3789.016962982,
"age_ms": 252.36411600008068
},
{
"seq": 59,
"t": 3789.159079083,
"age_ms": 343.99310200024047
},
{
"seq": 65,
"t": 3789.225854311,
"age_ms": 311.1680930001057
},
{
"seq": 67,
"t": 3789.259320089,
"age_ms": 311.3147970002501
},
{
"seq": 76,
"t": 3789.392587346,
"age_ms": 294.14004799991744
},
{
"seq": 81,
"t": 3789.442516815,
"age_ms": 261.26254200016774
},
{
"seq": 86,
"t": 3789.52590856,
"age_ms": 261.2806229999478
},
{
"seq": 92,
"t": 3789.642666921,
"age_ms": 277.9292240002178
},
{
"seq": 99,
"t": 3789.726031835,
"age_ms": 244.51215299995965
},
{
"seq": 103,
"t": 3789.825976518,
"age_ms": 250.37648099987564
},
{
"seq": 111,
"t": 3789.925941034,
"age_ms": 244.56144299983862
},
{
"seq": 116,
"t": 3790.025928882,
"age_ms": 249.16610799982664
},
{
"seq": 123,
"t": 3790.142752866,
"age_ms": 261.45474400027524
},
{
"seq": 129,
"t": 3790.242694049,
"age_ms": 248.77616499998112
},
{
"seq": 136,
"t": 3790.342592943,
"age_ms": 244.67110700015837
},
{
"seq": 142,
"t": 3790.442789034,
"age_ms": 244.74197899962746
},
{
"seq": 148,
"t": 3790.482821447,
"age_ms": 184.80229299984785
},
{
"seq": 150,
"t": 3790.592687976,
"age_ms": 250.9090449998439
},
{
"seq": 154,
"t": 3790.642761523,
"age_ms": 244.52061200008757
},
{
"seq": 158,
"t": 3790.759334974,
"age_ms": 294.2185060001066
},
{
"seq": 169,
"t": 3790.85937532,
"age_ms": 211.51360899966676
},
{
"seq": 175,
"t": 3790.942703194,
"age_ms": 184.29335300015737
},
{
"seq": 178,
"t": 3791.092760798,
"age_ms": 294.5976590003738
},
{
"seq": 185,
"t": 3791.159227746,
"age_ms": 244.03675499979727
},
{
"seq": 189,
"t": 3791.309405513,
"age_ms": 300.9365120001348
},
{
"seq": 197,
"t": 3791.376129993,
"age_ms": 261.5256170001885
},
{
"seq": 200,
"t": 3791.409295948,
"age_ms": 244.7492709998187
},
{
"seq": 204,
"t": 3791.559292596,
"age_ms": 327.64374399994267
},
{
"seq": 210,
"t": 3791.609347185,
"age_ms": 277.9158099997403
},
{
"seq": 216,
"t": 3791.69270685,
"age_ms": 261.0411769996972
},
{
"seq": 222,
"t": 3791.826089312,
"age_ms": 294.3526680001014
},
{
"seq": 230,
"t": 3791.876044447,
"age_ms": 211.1697479999748
},
{
"seq": 233,
"t": 3792.009430702,
"age_ms": 294.8169860001144
},
{
"seq": 240,
"t": 3792.109578378,
"age_ms": 278.3293790002972
},
{
"seq": 246,
"t": 3792.17617278,
"age_ms": 244.72856400007004
},
{
"seq": 251,
"t": 3792.276059133,
"age_ms": 261.44307900040076
},
{
"seq": 256,
"t": 3792.343641666,
"age_ms": 233.05911600027684
},
{
"seq": 258,
"t": 3792.376834162,
"age_ms": 245.4212469997401
},
{
"seq": 265,
"t": 3792.459423272,
"age_ms": 210.72089000017513
},
{
"seq": 276,
"t": 3792.578765415,
"age_ms": 146.6606869998941
},
{
"seq": 278,
"t": 3792.692758003,
"age_ms": 228.04350800015527
},
{
"seq": 282,
"t": 3792.782370773,
"age_ms": 250.07753699992463
},
{
"seq": 289,
"t": 3792.883536037,
"age_ms": 235.47986099993068
},
{
"seq": 295,
"t": 3792.968493394,
"age_ms": 220.19416899956923
},
{
"seq": 300,
"t": 3793.057073994,
"age_ms": 225.8108819996778
}
],
"fresh_video_updates_per_second": 10.6,
"motion_to_decoded_marker_ms": {
"p50": 250.07753699992463,
"p95": 311.54462099993907,
"maximum": 343.99310200024047
},
"frame_gap_ms": {
"p50": 99.89889400003449,
"p95": 150.17776700005925,
"maximum": 232.99640599998384
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

View File

@ -0,0 +1,13 @@
{
"normal_exit": "MainPID=16035\nExecStart={ path=/usr/bin/sunshine ; argv[]=/usr/bin/sunshine /home/test2/.config/sunshine/sunshine.conf ; ignore_errors=no ; start_time=[Thu 2026-11-05 17:15:15 CST] ; stop_time=[n/a] ; pid=16035 ; code=(null) ; status=0/0 }\nActiveState=active\nActiveState=inactive\nno-dropin\n",
"reconnect_from_idle": {
"host": "MainPID=16178\nExecStart={ path=/usr/bin/sunshine ; argv[]=/usr/bin/sunshine /home/test2/.config/sunshine/sunshine.conf capture=kms ; ignore_errors=no ; start_time=[Thu 2026-11-05 17:15:21 CST] ; stop_time=[n/a] ; pid=16178 ; code=(null) ; status=0/0 }\nActiveState=active\nActiveState=active\n",
"client_pid": 42247
},
"guard_kill": "MainPID=16391\nExecStart={ path=/usr/bin/sunshine ; argv[]=/usr/bin/sunshine /home/test2/.config/sunshine/sunshine.conf ; ignore_errors=no ; start_time=[Thu 2026-11-05 17:15:32 CST] ; stop_time=[n/a] ; pid=16391 ; code=(null) ; status=0/0 }\nActiveState=active\nActiveState=failed\nno-dropin\n",
"client_after_guard_kill": "",
"final_reconnect": {
"host": "MainPID=16529\nExecStart={ path=/usr/bin/sunshine ; argv[]=/usr/bin/sunshine /home/test2/.config/sunshine/sunshine.conf capture=kms ; ignore_errors=no ; start_time=[Thu 2026-11-05 17:15:39 CST] ; stop_time=[n/a] ; pid=16529 ; code=(null) ; status=0/0 }\nActiveState=active\nActiveState=active\n",
"client_pid": 42381
}
}

View File

@ -0,0 +1 @@
{"pid": 354371, "method": "XTest to decoded unique GTK marker; actual buttons/masked entry; submit has no backend; no USB/scanout", "hover": {"samples_ms": [178.57448200811632, 197.69827400159556, 162.49186400091276, 146.33253899228293, 183.9545060065575, 146.01579200825654, 166.1364909959957, 192.4687470018398, 140.93326398869976, 170.40761098905932, 130.25429600384086, 149.79033399140462, 147.36502699088305, 171.34793299192097, 140.67922400136013, 209.93443099723663, 171.2703499943018, 196.47124300536234, 161.18245999678038, 180.97574400599115, 166.86477199255023, 151.43810700101312, 183.07192900101654, 141.6548370034434], "p50": 166.50063149427297, "p95": 197.69827400159556, "maximum": 209.93443099723663}, "click_release": {"samples_ms": [257.4923289939761, 303.3968300005654, 307.51015900750645, 273.22628200636245, 289.78947599534877, 220.67785200488288, 307.0895790006034, 233.37104699749034, 247.0398559962632, 291.9942420121515, 270.1069380127592, 265.9521909954492, 286.96012900036294, 283.32125100132544, 331.5912260004552, 283.4998309990624, 340.8977479994064, 230.6568220083136, 227.89726899645757, 290.9694980044151, 322.98202499805484, 309.3181730073411, 278.06292999594007, 269.26877499499824], "p50": 283.4105410001939, "p95": 331.5912260004552, "maximum": 340.8977479994064}, "masked_character": {"samples_ms": [244.65199999394827, 168.10375200293493, 152.95970799343195, 185.5787690001307, 190.88075299805496, 159.54021899960935, 151.98876000067685, 149.26637199823745, 142.085617990233, 182.01551600941457, 164.85578600259032, 169.318653002847, 168.0935420008609, 178.00193399307318, 153.05012199678458, 152.86141600518022, 153.40886800549924, 131.56268899911083, 155.47442898969166, 141.60670500132255, 142.74031699460465, 134.45744900673162, 136.85492299555335, 148.39983900310472], "p50": 153.2294950011419, "p95": 190.88075299805496, "maximum": 244.65199999394827}, "synthetic_submit_ms": 151.72217699000612}

View File

@ -0,0 +1,98 @@
{
"pid": 40222,
"method": "XTest to decoded unique GTK marker; actual buttons/masked entry; submit has no backend; no USB/scanout",
"hover": {
"samples_ms": [
179.4374070000231,
177.66267800016067,
208.36882899993725,
199.27586399990105,
148.48014099970896,
213.92079799989006,
198.48197600003914,
178.2961570002044,
197.5781329997517,
214.10600099989097,
177.7525100001185,
212.00228400039123,
196.16214400002718,
160.70637099983287,
152.5974529999985,
183.83500199979608,
156.91950700011148,
225.2300620002643,
215.25687800021842,
188.55662499981918,
198.21802900014518,
219.25752600009218,
206.12453800004005,
150.1562919997923
],
"p50": 196.87013849988944,
"p95": 219.25752600009218,
"maximum": 225.2300620002643
},
"click_release": {
"samples_ms": [
326.73401400006696,
274.3639309996979,
349.7045670001171,
320.1542500000869,
308.8067819999196,
360.9321670001009,
399.3371690003187,
359.72587800006295,
298.4526960003677,
290.17870100005894,
311.8793829999049,
357.8887379999287,
377.508160999696,
288.05223700010174,
296.05907699988165,
283.28161699982957,
271.19392499980677,
261.88279999996666,
257.65757599992867,
246.06978300016635,
278.55853799974284,
336.5990040001634,
299.61845300022105,
312.11358900009145
],
"p50": 304.21261750007034,
"p95": 377.508160999696,
"maximum": 399.3371690003187
},
"masked_character": {
"samples_ms": [
152.01677300001393,
123.98044099973049,
159.24751500006096,
165.2842150001561,
141.40894399997705,
145.89140800035238,
155.53414799978782,
176.99567199997546,
154.7761330002686,
167.62854899980084,
140.38931400000365,
151.679619999868,
149.37670199969943,
150.03730399985216,
176.47535800006153,
175.34752400024445,
177.99022099961803,
164.80910900008894,
166.62204399972325,
176.02591600007145,
176.3773630000287,
181.4332240001022,
190.9327589996792,
181.52742900019803
],
"p50": 165.04666200012252,
"p95": 181.52742900019803,
"maximum": 190.9327589996792
},
"synthetic_submit_ms": 192.79906800011304
}

View File

@ -0,0 +1,67 @@
"""Run on box: XTest input to decoded marker. Excludes USB and scanout."""
import ctypes as C
import os
import json
import statistics
import subprocess
import time
os.environ.update(DISPLAY=':0',XAUTHORITY='/home/armbian/.Xauthority')
x=C.CDLL('libX11.so.6'); t=C.CDLL('libXtst.so.6')
x.XOpenDisplay.restype=C.c_void_p
x.XDefaultRootWindow.argtypes=[C.c_void_p]; x.XDefaultRootWindow.restype=C.c_ulong
x.XSync.argtypes=[C.c_void_p,C.c_int]
x.XGetImage.argtypes=[C.c_void_p,C.c_ulong,C.c_int,C.c_int,C.c_uint,C.c_uint,C.c_ulong,C.c_int]; x.XGetImage.restype=C.c_void_p
x.XGetPixel.argtypes=[C.c_void_p,C.c_int,C.c_int]; x.XGetPixel.restype=C.c_ulong
x.XDestroyImage.argtypes=[C.c_void_p]
x.XStringToKeysym.argtypes=[C.c_char_p]; x.XStringToKeysym.restype=C.c_ulong
x.XKeysymToKeycode.argtypes=[C.c_void_p,C.c_ulong];x.XKeysymToKeycode.restype=C.c_uint
t.XTestFakeMotionEvent.argtypes=[C.c_void_p,C.c_int,C.c_int,C.c_int,C.c_ulong]
t.XTestFakeButtonEvent.argtypes=[C.c_void_p,C.c_uint,C.c_int,C.c_ulong]
t.XTestFakeKeyEvent.argtypes=[C.c_void_p,C.c_uint,C.c_int,C.c_ulong]
d=x.XOpenDisplay(None);assert d;root=x.XDefaultRootWindow(d)
pid=int(subprocess.check_output(['pgrep','-x','moonlight']).strip())
assert int(subprocess.check_output(['xdotool','getwindowfocus','getwindowpid']).strip())==pid
def key(name):
code=x.XKeysymToKeycode(d,x.XStringToKeysym(name.encode()));assert code
t.XTestFakeKeyEvent(d,code,1,0);t.XTestFakeKeyEvent(d,code,0,0);x.XSync(d,0)
def move(px,py):
t.XTestFakeMotionEvent(d,-1,px,py,0);x.XSync(d,0)
def read():
im=x.XGetImage(d,root,40,1380,1320,1,0xffffffff,2);assert im
try:
def val(offset,n):
pixels=[x.XGetPixel(im,offset+20+i*40,0)&0xffffff for i in range(n)]
if any(0x404040<v<0xc0c0c0 for v in pixels):return -1
return sum((1<<i) for i,v in enumerate(pixels) if v>0xc0c0c0)
return val(0,16),val(760,8),val(1120,4)
finally:x.XDestroyImage(im)
def await_marker(m,s):
deadline=time.monotonic()+4
while time.monotonic()<deadline:
seen,magic,mode=read()
if (seen,magic,mode)==(s,0x5a,m):return
time.sleep(.002)
raise AssertionError(('marker timeout',m,s,read()))
def sample(m,s,action):
start=time.monotonic();action();await_marker(m,s);return (time.monotonic()-start)*1000
def stats(a):
b=sorted(a);return dict(samples_ms=a,p50=statistics.median(b),p95=b[int(len(b)*.95)],maximum=max(b))
result={'pid':pid,'method':'XTest to decoded unique GTK marker; actual buttons/masked entry; submit has no backend; no USB/scanout'}
for m in [1,2,3]:
move(300,300);time.sleep(.4);key('F'+str(m));await_marker(m,0)
values=[]
for i in range(1,25):
px=750 if i%2 else 1750
if m==1: action=lambda:move(px,550)
elif m==2:
move(px,550);time.sleep(.12)
def action():
t.XTestFakeButtonEvent(d,1,1,0);x.XSync(d,0);time.sleep(.04)
t.XTestFakeButtonEvent(d,1,0,0);x.XSync(d,0)
else:action=lambda:key('a')
values.append(sample(m,i,action));time.sleep(.12)
result[{1:'hover',2:'click_release',3:'masked_character'}[m]]=stats(values)
if m==3:result['synthetic_submit_ms']=sample(m,1024,lambda:key('Return'))
print(json.dumps(result))

View File

@ -0,0 +1,72 @@
"""Temporary real GTK buttons and masked entry; no authentication or passwords saved."""
import json
import time
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GLib
w = Gtk.Window(title='VDI response probe')
overlay = Gtk.Overlay(); w.add(overlay)
area = Gtk.DrawingArea(); overlay.add(area)
fixed = Gtk.Fixed(); overlay.add_overlay(fixed)
seq = mode = 0
entry = Gtk.Entry(); entry.set_visibility(False); entry.set_size_request(600, 70)
entry.set_placeholder_text('Synthetic masked input; no real credential')
fixed.put(entry, 900, 850)
buttons = []
for i in range(2):
b = Gtk.Button(label='Application '+str(i+1))
b.set_size_request(300, 250); fixed.put(b, 600+i*1000, 450); buttons.append(b)
def log(event):
print(json.dumps(dict(t=time.monotonic(), event=event, mode=mode, seq=seq)), flush=True)
def enter(button, event):
global seq
if mode == 1:
seq += 1; area.queue_draw(); log('hover')
return False
def click(button):
global seq
if mode == 2:
seq += 1; area.queue_draw(); log('click')
def changed(widget):
global seq
if mode == 3:
seq = widget.get_text_length(); area.queue_draw(); log('masked-count')
def submit(widget):
global seq
if mode == 3:
seq = 1000 + widget.get_text_length(); area.queue_draw(); log('synthetic-submit')
def key(widget, event):
global mode, seq
if event.keyval in (Gdk.KEY_F1, Gdk.KEY_F2, Gdk.KEY_F3):
mode = 0; entry.set_text(''); mode = event.keyval-Gdk.KEY_F1+1; seq = 0
if mode == 3: entry.grab_focus()
else: area.grab_focus()
area.queue_draw(); log('mode'); return True
return False
def draw(widget, cr):
cr.set_source_rgb(.94, .96, .98); cr.paint()
cr.set_source_rgb(.1, .15, .2); cr.set_font_size(26); cr.move_to(60, 80)
cr.show_text('VDI: GTK hover / click / masked input and synthetic page response')
if seq >= 1000:
cr.move_to(60, 180); cr.show_text('Synthetic page ready (no backend authentication)')
for start, bits, val in [(40,16,seq),(800,8,0x5a),(1160,4,mode)]:
for i in range(bits):
v = float(bool(val & (1 << i))); cr.set_source_rgb(v,v,v)
cr.rectangle(start+i*40,1350,40,70); cr.fill()
return False
for b in buttons:
b.connect('enter-notify-event',enter); b.connect('clicked',click)
entry.connect('changed',changed); entry.connect('activate',submit)
area.set_can_focus(True); area.connect('draw',draw)
w.connect('key-press-event',key); w.connect('destroy',Gtk.main_quit)
GLib.timeout_add_seconds(600, lambda: (Gtk.main_quit(),False)[1])
w.fullscreen(); w.show_all(); w.present(); log('ready'); Gtk.main()

View File

@ -0,0 +1,98 @@
{
"pid": 38284,
"method": "XTest to decoded unique GTK marker; actual buttons/masked entry; submit has no backend; no USB/scanout",
"hover": {
"samples_ms": [
161.9723610001529,
232.07568699990588,
235.94742100021904,
248.71466600006897,
234.44043499966938,
227.53052100006244,
220.13616399999592,
189.33990799996536,
301.9308159996399,
238.9576059999854,
221.49382399993556,
261.52157799970155,
251.48131800006013,
271.03219099990383,
232.2783919998983,
268.6922350003442,
302.4181780001527,
286.5821289997257,
236.30528800003958,
258.2019520000358,
178.59646900024018,
202.35885600004622,
229.3306270003086,
257.8586740000901
],
"p50": 236.1263545001293,
"p95": 301.9308159996399,
"maximum": 302.4181780001527
},
"click_release": {
"samples_ms": [
341.7477110001528,
312.60981200011884,
311.248653000348,
353.3086679999542,
293.28059899989967,
313.67231700005505,
274.033340999722,
335.19799499981673,
330.50933300000906,
373.78467899998213,
314.9255670000457,
376.5717470000709,
344.0299280000545,
363.27543900006276,
345.92948499994236,
387.3300670002209,
343.66623699997945,
379.99258499985444,
372.03504199987947,
331.58234399979847,
343.5160359999827,
290.8111579999968,
255.34694499992838,
335.03497199990306
],
"p50": 338.47285299998475,
"p95": 379.99258499985444,
"maximum": 387.3300670002209
},
"masked_character": {
"samples_ms": [
272.9139750003924,
219.77598600005877,
217.20095499995296,
178.2925749998867,
234.2179219999707,
185.61810199980755,
181.28263400012656,
182.37138599988612,
173.20171899973502,
161.4812279999569,
194.62385899987567,
203.74802900005307,
190.66841999983808,
219.02905900014957,
218.40374700013854,
224.31795100010277,
196.303799999896,
197.53867200006425,
209.46769900001527,
237.62271999976292,
210.94902000004367,
213.11194200006867,
197.15310399988084,
190.0804430001699
],
"p50": 200.64335050005866,
"p95": 237.62271999976292,
"maximum": 272.9139750003924
},
"synthetic_submit_ms": 225.34020800003418
}

View File

@ -0,0 +1,33 @@
"""Local SSH harness; uses existing credential helper without copying credentials."""
import json
import sys
import tempfile
import time
from pathlib import Path
sys.path.insert(0, tempfile.gettempdir())
from vdi_ubuntu_remote import ROOT, box, guest, password, run
g, b = guest(), box()
env = 'DISPLAY=:0 XAUTHORITY=/run/user/1000/gdm/Xauthority XDG_RUNTIME_DIR=/run/user/1000 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus '
try:
s = g.open_sftp()
s.put(str(ROOT/'docs/evidence/ubuntu-drag-20261105/drag-source.py'), '/tmp/vdi-ubuntu-drag-source.py')
s.close()
i, o, e = g.exec_command('sudo -S -p "" loginctl unlock-sessions')
i.write(password()+'\n'); i.flush(); i.channel.shutdown_write()
assert o.channel.recv_exit_status() == 0, e.read().decode()
print(run(b, 'DISPLAY=:0 XAUTHORITY=/home/armbian/.Xauthority xdotool key Escape'))
print(run(g, env+'systemd-run --user --unit=vdi-deep-drag --collect /usr/bin/python3 /tmp/vdi-ubuntu-drag-source.py'))
time.sleep(4)
s = b.open_sftp()
s.put(str(ROOT/'docs/evidence/ubuntu-drag-20261105/drag-probe.py'), '/tmp/vdi-deep-drag-probe.py')
s.close()
result = run(b, 'python3 /tmp/vdi-deep-drag-probe.py', 30)
print(result['err'])
assert result['rc'] == 0, result
d = json.loads(result['out'])
(Path(__file__).parent/(sys.argv[1]+'.json')).write_text(json.dumps(d, indent=2), encoding='utf-8')
print({k: v for k, v in d.items() if k != 'frames'})
finally:
print(run(g, 'XDG_RUNTIME_DIR=/run/user/1000 systemctl --user stop vdi-deep-drag'))
g.close(); b.close()

View File

@ -0,0 +1,50 @@
"""Ubuntu-only recovery checks, using the existing kiosk entry and SSH identities."""
import json
from pathlib import Path
import sys
import tempfile
import time
sys.path.insert(0, tempfile.gettempdir())
from vdi_ubuntu_remote import box, guest, run
b, g = box(), guest()
benv = 'DISPLAY=:0 XAUTHORITY=/home/armbian/.Xauthority '
genv = 'DISPLAY=:0 XAUTHORITY=/run/user/1000/gdm/Xauthority '
results = {}
def state():
r = run(g, 'systemctl --user show vdi-sunshine.service -p MainPID -p ExecStart -p ActiveState; '
'systemctl --user show vdi-native-cursor-guard.service -p ActiveState; '
'test ! -e /run/user/1000/systemd/user/vdi-sunshine.service.d/90-native-cursor.conf && echo no-dropin || true')
return r['out']
def connect():
assert run(b, benv+'xdotool mousemove 2390 320 click 1')['rc'] == 0
time.sleep(12)
s = state()
assert 'capture=kms' in s and s.count('ActiveState=active') == 2, s
client = run(b, 'pgrep -x moonlight')['out'].strip()
assert client.isdigit(), client
return dict(host=s, client_pid=int(client))
try:
assert run(b, benv+'xdotool key ctrl+alt+shift+q')['rc'] == 0
time.sleep(4)
results['normal_exit'] = state()
assert 'capture=kms' not in results['normal_exit'] and 'no-dropin' in results['normal_exit']
assert run(g, genv+'xset dpms force off')['rc'] == 0
time.sleep(1)
results['reconnect_from_idle'] = connect()
assert run(g, 'systemctl --user kill --kill-whom=main --signal=SIGKILL vdi-native-cursor-guard.service')['rc'] == 0
time.sleep(6)
results['guard_kill'] = state()
results['client_after_guard_kill'] = run(b, 'pgrep -x moonlight')['out'].strip()
assert 'capture=kms' not in results['guard_kill'] and 'no-dropin' in results['guard_kill']
assert results['client_after_guard_kill'] == ''
run(g, 'systemctl --user reset-failed vdi-native-cursor-guard.service')
results['final_reconnect'] = connect()
finally:
(Path(__file__).parent/'kms-lifecycle.json').write_text(json.dumps(results, indent=2), encoding='utf-8')
g.close()
b.close()
print(json.dumps(results))

View File

@ -0,0 +1,39 @@
"""Run the controlled GTK response or native-cursor check via existing SSH credentials."""
import json
from pathlib import Path
import sys
import tempfile
import time
sys.path.insert(0, tempfile.gettempdir())
from vdi_ubuntu_remote import ROOT, box, guest, run
kind, name = sys.argv[1:3]
assert kind in ('response', 'cursor')
folder = ROOT / 'docs/evidence' / ('native-cursor-20261105' if kind == 'cursor' else 'ubuntu-deep-latency-20261105')
source = folder / ('source.py' if kind == 'cursor' else 'response-source.py')
probe = folder / ('probe.py' if kind == 'cursor' else 'response-probe.py')
g, b = guest(), box()
env = 'DISPLAY=:0 XAUTHORITY=/run/user/1000/gdm/Xauthority XDG_RUNTIME_DIR=/run/user/1000 DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus '
unit = 'vdi-deep-response'
invocation = ''
try:
for client, local, remote in [(g, source, '/tmp/vdi-response-source.py'),
(b, probe, '/tmp/vdi-response-probe.py')]:
with client.open_sftp() as s:
s.put(str(local), remote)
started = run(g, env + 'systemd-run --user --unit=' + unit + ' --collect /usr/bin/python3 /tmp/vdi-response-source.py')
assert started['rc'] == 0, started
invocation = run(g, 'systemctl --user show ' + unit + ' -p InvocationID --value')['out'].strip()
time.sleep(4)
result = run(b, 'python3 /tmp/vdi-response-probe.py' + (' 192.168.1.72' if kind == 'cursor' else ''), 100)
if result['rc']:
raise RuntimeError(result)
data = json.loads(result['out'])
(Path(__file__).parent / (name + '.json')).write_text(json.dumps(data, indent=2), encoding='utf-8')
print(json.dumps(data, ensure_ascii=False))
finally:
print(run(g, env + 'systemctl --user stop ' + unit))
log = run(g, 'journalctl --user _SYSTEMD_INVOCATION_ID=' + invocation + ' --no-pager') if invocation else {'out': ''}
(Path(__file__).parent / (name + '-source.log')).write_text(log['out'], encoding='utf-8')
g.close()
b.close()

View File

@ -0,0 +1,28 @@
import base64
import runpy
import sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[3]
term = runpy.run_path(str(ROOT/'tools/pve_term_exec.py'))
vm = runpy.run_path(str(ROOT/'tools/pve_vm.py'))
ticket, csrf = term['login']()
task = 'VDIDeepLatencyReference20261105'
folder = r'C:\ProgramData\VDI\deep-latency-20261105'
if sys.argv[1] == 'start':
encoded = base64.b64encode(Path(__file__).with_name('windows-drag.ps1').read_bytes()).decode()
ps = r"""$ErrorActionPreference='Stop'; $folder='"""+folder+r"""';
New-Item -ItemType Directory -Force $folder | Out-Null
if (Get-ScheduledTask -TaskName '"""+task+r"""' -ErrorAction SilentlyContinue) { throw 'Task already exists' }
[IO.File]::WriteAllBytes("$folder\drag.ps1",[Convert]::FromBase64String('"""+encoded+r"""'))
$action=New-ScheduledTaskAction -Execute powershell.exe -Argument "-NoProfile -ExecutionPolicy Bypass -STA -WindowStyle Hidden -File $folder\drag.ps1"
$principal=New-ScheduledTaskPrincipal -UserId test -LogonType Interactive -RunLevel Limited
$settings=New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 10)
Register-ScheduledTask -TaskName '"""+task+r"""' -Action $action -Principal $principal -Settings $settings | Out-Null
Start-ScheduledTask -TaskName '"""+task+r"""'
'Started temporary reference'
"""
else:
ps = "Stop-ScheduledTask -TaskName '"+task+"' -ErrorAction SilentlyContinue; Unregister-ScheduledTask -TaskName '"+task+"' -Confirm:$false -ErrorAction SilentlyContinue; 'Stopped temporary reference'"
out, err = vm['agent'](ticket, csrf, ['powershell.exe','-NoProfile','-Command',ps])
print(out)
if err: raise RuntimeError(err)

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 KiB

View File

@ -0,0 +1,156 @@
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff1c10000 (LWP 4119)]
[New Thread 0x7ffff140f000 (LWP 4120)]
[2026-11-05 14:20:13.495941] [0x00007ffff1c17000] [info] config: 'adapter_name' = /dev/dri/renderD128
[2026-11-05 14:20:13.495974] [0x00007ffff1c17000] [info] config: 'system_tray' = disabled
[2026-11-05 14:20:13.495978] [0x00007ffff1c17000] [info] config: 'audio_sink' = vdi_audio
[2026-11-05 14:20:13.495981] [0x00007ffff1c17000] [info] config: 'origin_web_ui_allowed' = pc
[2026-11-05 14:20:13.495984] [0x00007ffff1c17000] [info] config: 'upnp' = disabled
[2026-11-05 14:20:13.495987] [0x00007ffff1c17000] [info] config: 'sw_tune' = zerolatency
[2026-11-05 14:20:13.495989] [0x00007ffff1c17000] [info] config: 'hevc_mode' = 1
[2026-11-05 14:20:13.495992] [0x00007ffff1c17000] [info] config: 'encoder' = vaapi
[2026-11-05 14:20:13.495994] [0x00007ffff1c17000] [info] config: 'capture' = x11
[2026-11-05 14:20:13.495997] [0x00007ffff1c17000] [info] config: 'sw_preset' = ultrafast
[2026-11-05 14:20:13.495999] [0x00007ffff1c17000] [info] config: 'sunshine_name' = VDI-Ubuntu
[New Thread 0x7ffff0c0e000 (LWP 4121)]
[2026-11-05 14:20:13.496]: Info: Sunshine version: 2026.914.233613 commit: 63d35f702ee9e362e43263742981836ec0710384
[2026-11-05 14:20:13.496]: Info: Package Publisher: LizardByte
[2026-11-05 14:20:13.496]: Info: Publisher Website: https://app.lizardbyte.dev
[2026-11-05 14:20:13.496]: Info: Get support: https://app.lizardbyte.dev/support
[2026-11-05 14:20:13.496]: Info: config: 'sunshine_name' = VDI-Ubuntu
[2026-11-05 14:20:13.496]: Info: config: 'sw_preset' = ultrafast
[2026-11-05 14:20:13.496]: Info: config: 'capture' = x11
[2026-11-05 14:20:13.496]: Info: config: 'encoder' = vaapi
[2026-11-05 14:20:13.496]: Info: config: 'hevc_mode' = 1
[2026-11-05 14:20:13.496]: Info: config: 'sw_tune' = zerolatency
[2026-11-05 14:20:13.496]: Info: config: 'upnp' = disabled
[2026-11-05 14:20:13.496]: Info: config: 'origin_web_ui_allowed' = pc
[2026-11-05 14:20:13.496]: Info: config: 'audio_sink' = vdi_audio
[2026-11-05 14:20:13.496]: Info: config: 'system_tray' = disabled
[2026-11-05 14:20:13.496]: Info: config: 'adapter_name' = /dev/dri/renderD128
[New Thread 0x7fffe83ff000 (LWP 4122)]
[2026-11-05 14:20:13.508]: Info: Detecting displays
[2026-11-05 14:20:13.510]: Info: Detected display: Virtual-1 (id: 0)Virtual-1 connected: true
[New Thread 0x7fffe93ff000 (LWP 4123)]
[2026-11-05 14:20:13.813]: Info: Trying encoder [vaapi]
[2026-11-05 14:20:13.813]: Error: Failed to gain CAP_SYS_ADMIN
[2026-11-05 14:20:13.813]: Info: [misc] drop_elevated_privileges succeeded in dropping capabilities
[2026-11-05 14:20:13.813]: Info: Screencasting with X11
[2026-11-05 14:20:13.822]: Warning: Couldn't get info for requested display [], defaulting to recording entire virtual desktop
[2026-11-05 14:20:13.823]: Info: Creating encoder [h264_vaapi]
[2026-11-05 14:20:13.823]: Info: Color coding: SDR (Rec. 601)
[2026-11-05 14:20:13.823]: Info: Color depth: 8-bit
[2026-11-05 14:20:13.823]: Info: Color range: JPEG
[New Thread 0x7fffde3ef000 (LWP 4135)]
[2026-11-05 14:20:13.855]: Warning: EGL: context priority set to MEDIUM but CAP_SYS_NICE capability is missing
[New Thread 0x7fffddbee000 (LWP 4136)]
[2026-11-05 14:20:13.864]: Info: vaapi vendor: Mesa Gallium driver 25.2.8-0ubuntu0.24.04.4 for virgl (Mesa Intel(R) HD Graphics 4600 (HSW GT2))
[2026-11-05 14:20:13.865]: Info: Streaming bitrate is 1000000
[2026-11-05 14:20:13.865]: Info: Using normal encoding mode
[2026-11-05 14:20:13.865]: Info: [VAAPI] Using VBR rate control with single frame VBV size (whitelist override)
Thread 1 "sunshine" received signal SIGSEGV, Segmentation fault.
0x00005555557259c7 in ?? ()
Thread 8 (Thread 0x7fffddbee000 (LWP 4136) "sunshin:disk$0"):
#0 0x00007ffff5898e51 in __futex_abstimed_wait_common64 (private=0, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555573216c8) at ./nptl/futex-internal.c:57
#1 __futex_abstimed_wait_common (cancel=true, private=0, abstime=0x0, clockid=0, expected=0, futex_word=0x5555573216c8) at ./nptl/futex-internal.c:87
#2 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x5555573216c8, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x0, private=private@entry=0) at ./nptl/futex-internal.c:139
#3 0x00007ffff589b8cd in __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x555557321670, cond=0x5555573216a0) at ./nptl/pthread_cond_wait.c:503
#4 ___pthread_cond_wait (cond=0x5555573216a0, mutex=0x555557321670) at ./nptl/pthread_cond_wait.c:627
#5 0x00007fffe9999edd in ?? () from /home/test2/vdi-terminal/experiments/virgl-video-20261105/root/usr/lib/x86_64-linux-gnu/libgallium-25.2.8-0ubuntu0.24.04.4.so
#6 0x00007fffe9965fbb in ?? () from /home/test2/vdi-terminal/experiments/virgl-video-20261105/root/usr/lib/x86_64-linux-gnu/libgallium-25.2.8-0ubuntu0.24.04.4.so
#7 0x00007fffe9999e0c in ?? () from /home/test2/vdi-terminal/experiments/virgl-video-20261105/root/usr/lib/x86_64-linux-gnu/libgallium-25.2.8-0ubuntu0.24.04.4.so
#8 0x00007ffff589cb84 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#9 0x00007ffff5929ecc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Thread 7 (Thread 0x7fffde3ef000 (LWP 4135) "sunshin:disk$0"):
#0 0x00007ffff5898e51 in __futex_abstimed_wait_common64 (private=0, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x5555572b1a08) at ./nptl/futex-internal.c:57
#1 __futex_abstimed_wait_common (cancel=true, private=0, abstime=0x0, clockid=0, expected=0, futex_word=0x5555572b1a08) at ./nptl/futex-internal.c:87
#2 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x5555572b1a08, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x0, private=private@entry=0) at ./nptl/futex-internal.c:139
#3 0x00007ffff589b8cd in __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x5555572b19b0, cond=0x5555572b19e0) at ./nptl/pthread_cond_wait.c:503
#4 ___pthread_cond_wait (cond=0x5555572b19e0, mutex=0x5555572b19b0) at ./nptl/pthread_cond_wait.c:627
#5 0x00007fffd5999edd in ?? () from /lib/x86_64-linux-gnu/libgallium-25.2.8-0ubuntu0.24.04.1.so
#6 0x00007fffd5965fbb in ?? () from /lib/x86_64-linux-gnu/libgallium-25.2.8-0ubuntu0.24.04.1.so
#7 0x00007fffd5999e0c in ?? () from /lib/x86_64-linux-gnu/libgallium-25.2.8-0ubuntu0.24.04.1.so
#8 0x00007ffff589cb84 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#9 0x00007ffff5929ecc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Thread 6 (Thread 0x7fffe93ff000 (LWP 4123) "sunshine"):
#0 0x00007ffff58ecbdf in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0, req=0x7fffe93fa7c0, rem=0x7fffe93fa7c0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
#1 0x00007ffff58f9b27 in __GI___nanosleep (req=<optimized out>, rem=<optimized out>) at ../sysdeps/unix/sysv/linux/nanosleep.c:25
#2 0x00005555559d0d0c in ?? ()
#3 0x0000555556b3c224 in ?? ()
#4 0x00007ffff589cb84 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#5 0x00007ffff5929ecc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Thread 5 (Thread 0x7fffe83ff000 (LWP 4122) "TaskPool::worke"):
#0 0x00007ffff5898e51 in __futex_abstimed_wait_common64 (private=0, cancel=true, abstime=0x7fffe83fa810, op=137, expected=0, futex_word=0x555556f84914) at ./nptl/futex-internal.c:57
#1 __futex_abstimed_wait_common (cancel=true, private=0, abstime=0x7fffe83fa810, clockid=0, expected=0, futex_word=0x555556f84914) at ./nptl/futex-internal.c:87
#2 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x555556f84914, expected=expected@entry=0, clockid=clockid@entry=1, abstime=abstime@entry=0x7fffe83fa810, private=private@entry=0) at ./nptl/futex-internal.c:139
#3 0x00007ffff589c1f6 in __pthread_cond_wait_common (abstime=<optimized out>, clockid=<optimized out>, mutex=0x555556f84918, cond=0x555556f848e8) at ./nptl/pthread_cond_wait.c:503
#4 ___pthread_cond_clockwait64 (abstime=<optimized out>, clockid=<optimized out>, mutex=0x555556f84918, cond=0x555556f848e8) at ./nptl/pthread_cond_wait.c:691
#5 ___pthread_cond_clockwait64 (cond=0x555556f848e8, mutex=0x555556f84918, clockid=<optimized out>, abstime=<optimized out>) at ./nptl/pthread_cond_wait.c:679
#6 0x0000555555784398 in ?? ()
#7 0x0000555556b3c224 in ?? ()
#8 0x00007ffff589cb84 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#9 0x00007ffff5929ecc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Thread 4 (Thread 0x7ffff0c0e000 (LWP 4121) "sunshine"):
#0 syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1 0x00005555569b1372 in ?? ()
#2 0x000055555577a37c in ?? ()
#3 0x0000555556b3c224 in ?? ()
#4 0x00007ffff589cb84 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#5 0x00007ffff5929ecc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Thread 3 (Thread 0x7ffff140f000 (LWP 4120) "egl_worker"):
#0 0x00007ffff5898e51 in __futex_abstimed_wait_common64 (private=21845, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x555556f8d03c) at ./nptl/futex-internal.c:57
#1 __futex_abstimed_wait_common (cancel=true, private=21845, abstime=0x0, clockid=0, expected=0, futex_word=0x555556f8d03c) at ./nptl/futex-internal.c:87
#2 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x555556f8d03c, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x0, private=private@entry=0) at ./nptl/futex-internal.c:139
#3 0x00007ffff589b8cd in __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x555556f8cfe8, cond=0x555556f8d010) at ./nptl/pthread_cond_wait.c:503
#4 ___pthread_cond_wait (cond=0x555556f8d010, mutex=0x555556f8cfe8) at ./nptl/pthread_cond_wait.c:627
#5 0x000055555596411c in ?? ()
#6 0x0000555556b3c224 in ?? ()
#7 0x00007ffff589cb84 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#8 0x00007ffff5929ecc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Thread 2 (Thread 0x7ffff1c10000 (LWP 4119) "drm_worker"):
#0 0x00007ffff5898e51 in __futex_abstimed_wait_common64 (private=21845, cancel=true, abstime=0x0, op=393, expected=0, futex_word=0x555556f863fc) at ./nptl/futex-internal.c:57
#1 __futex_abstimed_wait_common (cancel=true, private=21845, abstime=0x0, clockid=0, expected=0, futex_word=0x555556f863fc) at ./nptl/futex-internal.c:87
#2 __GI___futex_abstimed_wait_cancelable64 (futex_word=futex_word@entry=0x555556f863fc, expected=expected@entry=0, clockid=clockid@entry=0, abstime=abstime@entry=0x0, private=private@entry=0) at ./nptl/futex-internal.c:139
#3 0x00007ffff589b8cd in __pthread_cond_wait_common (abstime=0x0, clockid=0, mutex=0x555556f863a8, cond=0x555556f863d0) at ./nptl/pthread_cond_wait.c:503
#4 ___pthread_cond_wait (cond=0x555556f863d0, mutex=0x555556f863a8) at ./nptl/pthread_cond_wait.c:627
#5 0x00005555558ffa3c in ?? ()
#6 0x0000555556b3c224 in ?? ()
#7 0x00007ffff589cb84 in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:447
#8 0x00007ffff5929ecc in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
Thread 1 (Thread 0x7ffff1c17000 (LWP 4116) "sunshine"):
#0 0x00005555557259c7 in ?? ()
#1 0x00005555558aeb46 in ?? ()
#2 0x00005555558afc26 in ?? ()
#3 0x00005555558b0950 in ?? ()
#4 0x0000555555707092 in main ()
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libcap.so.2
warning: could not find '.gnu_debugaltlink' file for /home/test2/vdi-terminal/experiments/virgl-video-20261105/root/usr/lib/x86_64-linux-gnu/libgbm.so.1
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libgio-2.0.so.0
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libgobject-2.0.so.0
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libglib-2.0.so.0
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libpulse.so.0
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libpulse-simple.so.0
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libQt6Gui.so.6
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/liblber.so.2
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libbrotlidec.so.1
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libgmodule-2.0.so.0
warning: could not find '.gnu_debugaltlink' file for /usr/lib/x86_64-linux-gnu/pulseaudio/libpulsecommon-16.1.so
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libbrotlicommon.so.1
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libtinfo.so.6
warning: could not find '.gnu_debugaltlink' file for /usr/lib/x86_64-linux-gnu/gbm/dri_gbm.so
libva info: VA-API version 1.20.0
libva info: User environment variable requested driver 'virtio_gpu'
libva info: Trying to open /home/test2/vdi-terminal/experiments/virgl-video-20261105/root/usr/lib/x86_64-linux-gnu/dri/virtio_gpu_drv_video.so
libva info: Found init function __vaDriverInit_1_20
libva info: va_openDriver() returns 0

View File

@ -0,0 +1,57 @@
0
[AVHWDeviceContext @ 0x560b30ebdf80] libva: VA-API version 1.20.0
[AVHWDeviceContext @ 0x560b30ebdf80] libva: User environment variable requested driver 'virtio_gpu'
[AVHWDeviceContext @ 0x560b30ebdf80] libva: Trying to open /home/test2/vdi-terminal/experiments/virgl-video-20261105/root/usr/lib/x86_64-linux-gnu/dri/virtio_gpu_drv_video.so
[AVHWDeviceContext @ 0x560b30ebdf80] libva: Found init function __vaDriverInit_1_20
[AVHWDeviceContext @ 0x560b30ebdf80] libva: va_openDriver() returns 0
[AVHWDeviceContext @ 0x560b30ebdf80] Initialised VAAPI connection: version 1.20
[AVHWDeviceContext @ 0x560b30ebdf80] VAAPI driver: Mesa Gallium driver 25.2.8-0ubuntu0.24.04.4 for virgl (Mesa Intel(R) HD Graphics 4600 (HSW GT2)).
[AVHWDeviceContext @ 0x560b30ebdf80] Driver not found in known nonstandard list, using standard behaviour.
[Parsed_testsrc2_0 @ 0x560b30f39d40] size:2560x1440 rate:30/1 duration:-1.000000 sar:1/1
Input #0, lavfi, from 'testsrc2=size=2560x1440:rate=30':
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0: Video: wrapped_avframe, 1 reference frame, yuv420p, 2560x1440 [SAR 1:1 DAR 16:9], 30 fps, 30 tbr, 30 tbn
[out#0/h264 @ 0x560b30f28ac0] No explicit maps, mapping streams automatically...
[vost#0:0/h264_vaapi @ 0x560b30f3d780] Created video stream from input stream 0:0
Stream mapping:
Stream #0:0 -> #0:0 (wrapped_avframe (native) -> h264 (h264_vaapi))
Press [q] to stop, [?] for help
[graph 0 input from stream 0:0 @ 0x560b30f43bc0] w:2560 h:1440 pixfmt:yuv420p tb:1/30 fr:30/1 sar:1/1
[auto_scale_0 @ 0x560b30f44c40] w:iw h:ih flags:'' interl:0
[Parsed_format_0 @ 0x560b30f402c0] auto-inserting filter 'auto_scale_0' between the filter 'graph 0 input from stream 0:0' and the filter 'Parsed_format_0'
[auto_scale_0 @ 0x560b30f44c40] w:2560 h:1440 fmt:yuv420p sar:1/1 -> w:2560 h:1440 fmt:nv12 sar:1/1 flags:0x00000004
[h264_vaapi @ 0x560b30f3db40] Using input frames context (format vaapi) with h264_vaapi encoder.
[h264_vaapi @ 0x560b30f3db40] Input surface format is nv12.
[h264_vaapi @ 0x560b30f3db40] Using VAAPI profile VAProfileH264High (7).
[h264_vaapi @ 0x560b30f3db40] Using VAAPI entrypoint VAEntrypointEncSlice (6).
[h264_vaapi @ 0x560b30f3db40] Using VAAPI render target format YUV420 (0x1).
[h264_vaapi @ 0x560b30f3db40] RC mode: CBR.
[h264_vaapi @ 0x560b30f3db40] RC target: 100% of 30000000 bps over 33 ms.
[h264_vaapi @ 0x560b30f3db40] RC buffer: 1000000 bits, initial fullness 750000 bits.
[h264_vaapi @ 0x560b30f3db40] RC framerate: 30/1 (30.00 fps).
[h264_vaapi @ 0x560b30f3db40] Driver does not report any additional prediction constraints.
[h264_vaapi @ 0x560b30f3db40] Using intra and P-frames (supported references: 1 / 0).
[h264_vaapi @ 0x560b30f3db40] All wanted packed headers available (wanted 0xd, found 0x1f).
[h264_vaapi @ 0x560b30f3db40] Using level 5.
Output #0, h264, to '/tmp/vdi-vaapi-test.h264':
Metadata:
encoder : Lavf60.16.100
Stream #0:0: Video: h264 (High), 1 reference frame, vaapi(tv, progressive), 2560x1440 (0x0) [SAR 1:1 DAR 16:9], q=2-31, 30000 kb/s, 30 fps, 30 tbn
Metadata:
encoder : Lavc60.31.102 h264_vaapi
frame= 0 fps=0.0 q=0.0 size= 0kB time=N/A bitrate=N/A speed=N/A No more output streams to write to, finishing.
[out#0/h264 @ 0x560b30f28ac0] All streams finished
[out#0/h264 @ 0x560b30f28ac0] Terminating muxer thread
[vist#0:0/wrapped_avframe @ 0x560b30f3c740] Decoder thread received EOF packet
[vist#0:0/wrapped_avframe @ 0x560b30f3c740] Decoder returned EOF, finishing
[vist#0:0/wrapped_avframe @ 0x560b30f3c740] Terminating decoder thread
[AVIOContext @ 0x560b30f40640] Statistics: 0 bytes written, 0 seeks, 0 writeouts
[out#0/h264 @ 0x560b30f28ac0] Output file #0 (/tmp/vdi-vaapi-test.h264):
[out#0/h264 @ 0x560b30f28ac0] Output stream #0:0 (video): 90 frames encoded; 89 packets muxed (0 bytes);
[out#0/h264 @ 0x560b30f28ac0] Total: 89 packets (0 bytes) muxed
[out#0/h264 @ 0x560b30f28ac0] video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
frame= 89 fps=0.0 q=-0.0 Lsize= 0kB time=00:00:02.93 bitrate= 0.0kbits/s speed=7.61x
[in#0/lavfi @ 0x560b30f382c0] Terminating demuxer thread
[in#0/lavfi @ 0x560b30f382c0] Input file #0 (testsrc2=size=2560x1440:rate=30):
[in#0/lavfi @ 0x560b30f382c0] Input stream #0:0 (video): 92 packets read (44160 bytes); 90 frames decoded; 0 decode errors;
[in#0/lavfi @ 0x560b30f382c0] Total: 92 packets (44160 bytes) demuxed

View File

@ -0,0 +1,5 @@
{
"rc": 0,
"out": "",
"err": ""
}

View File

@ -0,0 +1,87 @@
/* Isolated VM102 experiment. Requires private virglrenderer >=1.2.0.
* Backport asynchronous completion delivery to the QEMU/GLib main thread.
* QEMU built against 1.1.0 has compiled out its native async-fence path.
* Never install as a global preload. No video acceleration flags are added.
*/
#define _GNU_SOURCE
#define VIRGL_RENDERER_UNSTABLE_APIS
#include <virgl/virglrenderer.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdatomic.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
extern unsigned int g_idle_add_full(int, int (*)(void *), void *, void (*)(void *));
static struct virgl_renderer_callbacks original, replaced;
static pthread_t main_thread;
static atomic_uint epoch;
struct completion { void *cookie; uint32_t ctx, ring; uint64_t fence; unsigned epoch; int context; };
static int deliver(void *opaque) {
struct completion *c = opaque;
if (!pthread_equal(main_thread, pthread_self())) abort();
if (c->epoch != atomic_load(&epoch)) return 0;
if (c->context) original.write_context_fence(c->cookie, c->ctx, c->ring, c->fence);
else original.write_fence(c->cookie, (uint32_t)c->fence);
return 0;
}
static void schedule(void *cookie, uint32_t ctx, uint32_t ring, uint64_t fence, int context) {
struct completion *c = malloc(sizeof(*c));
if (!c) abort();
*c = (struct completion){cookie, ctx, ring, fence, atomic_load(&epoch), context};
if (!g_idle_add_full(0, deliver, c, free)) abort();
}
static void fence(void *cookie, uint32_t id) { schedule(cookie, 0, 0, id, 0); }
static void context_fence(void *cookie, uint32_t ctx, uint32_t ring, uint64_t id) { schedule(cookie, ctx, ring, id, 1); }
static int target(void) {
char args[32768]; int fd = open("/proc/self/cmdline", O_RDONLY | O_CLOEXEC);
if (fd < 0) return 0;
ssize_t n = read(fd, args, sizeof(args)); close(fd);
if (n <= 0 || n == sizeof(args) || args[n-1]) return 0;
for (char *p=args; p<args+n; p+=strlen(p)+1) if (!strcmp(p,"-id")) {
p+=strlen(p)+1; return p<args+n && !strcmp(p,"102");
}
return 0;
}
int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cb) {
typedef int (*Init)(void *, int, struct virgl_renderer_callbacks *);
Init real=(Init)dlsym(RTLD_NEXT,"virgl_renderer_init"); if(!real) abort();
if (!target()) return real(cookie,flags,cb);
if (!cb || cb->version!=4 || !cb->get_egl_display || !cb->write_fence || !cb->write_context_fence || (flags & VIRGL_RENDERER_ASYNC_FENCE_CB)) return -1;
main_thread=pthread_self(); atomic_fetch_add(&epoch,1); original=*cb; replaced=*cb;
replaced.write_fence=fence; replaced.write_context_fence=context_fence;
fprintf(stderr,"VDI async shim: VM102 flags 0x%x -> 0x%x, main-thread GLib delivery\n",flags,flags|VIRGL_RENDERER_THREAD_SYNC|VIRGL_RENDERER_ASYNC_FENCE_CB);
return real(cookie,flags|VIRGL_RENDERER_THREAD_SYNC|VIRGL_RENDERER_ASYNC_FENCE_CB,&replaced);
}
void virgl_renderer_cleanup(void *cookie) {
typedef void (*Cleanup)(void *);
Cleanup real=(Cleanup)dlsym(RTLD_NEXT,"virgl_renderer_cleanup"); if(!real) abort();
real(cookie); atomic_fetch_add(&epoch,1);
}
void virgl_renderer_reset(void) {
typedef void (*Reset)(void);
Reset real=(Reset)dlsym(RTLD_NEXT,"virgl_renderer_reset"); if(!real) abort();
atomic_fetch_add(&epoch,1); real();
}
#ifdef VDI_TEST
extern int g_main_context_iteration(void *, int);
static int seen;
static void verify(void *c, uint32_t f) { if(c!=(void *)1 || f!=(uint32_t)++seen) abort(); }
static void *producer(void *unused) { (void)unused; for(uint32_t i=1;i<=1000;i++) fence((void *)1,i); return NULL; }
int main(void) {
main_thread=pthread_self(); original.write_fence=verify;
pthread_t t; if(pthread_create(&t,NULL,producer,NULL)) abort(); pthread_join(t,NULL);
while(seen<1000) g_main_context_iteration(NULL,1);
fence((void *)1,9999); atomic_fetch_add(&epoch,1);
while(g_main_context_iteration(NULL,0)) {}
if(seen!=1000) abort();
puts("PASS: 1000 ordered callbacks on main thread; stale epoch dropped");
return 0;
}
#endif

View File

@ -0,0 +1,51 @@
/* VM102-only proof of concept for virglrenderer 1.1.0 / QEMU 11.
* Never use /etc/ld.so.preload. No QEMU/library files are replaced.
* Normal start without the explicit LD_PRELOAD is the rollback.
*/
#define _GNU_SOURCE
#define VIRGL_RENDERER_UNSTABLE_APIS
#include <virgl/virglrenderer.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static struct virgl_renderer_callbacks callbacks;
static int vm102(void) {
char args[32768];
int fd = open("/proc/self/cmdline", O_RDONLY | O_CLOEXEC);
if (fd < 0) return 0;
ssize_t n = read(fd, args, sizeof(args));
close(fd);
if (n <= 0 || n == sizeof(args) || args[n-1]) return 0;
for (char *p = args; p < args+n; p += strlen(p)+1) {
if (!strcmp(p, "-id")) {
p += strlen(p)+1;
return p < args+n && !strcmp(p, "102");
}
}
return 0;
}
static int video_fd(void *cookie) {
(void)cookie;
int fd = open("/dev/dri/renderD128", O_RDWR | O_CLOEXEC);
fprintf(stderr, "VDI video shim: dedicated VA fd=%d\n", fd);
return fd;
}
int virgl_renderer_init(void *cookie, int flags, struct virgl_renderer_callbacks *cb) {
typedef int (*Init)(void *, int, struct virgl_renderer_callbacks *);
Init original = (Init)dlsym(RTLD_NEXT, "virgl_renderer_init");
if (!original) abort();
if (!vm102()) return original(cookie, flags, cb);
if (!cb || cb->version < 3 || cb->version > 4 || cb->get_drm_fd) {
fprintf(stderr, "VDI video shim: unsupported callback ABI; refusing\n");
return -1;
}
callbacks = *cb;
callbacks.get_drm_fd = video_fd;
fprintf(stderr, "VDI video shim: VM102 callbacks v%d flags 0x%x -> 0x%x\n",
cb->version, flags, flags | VIRGL_RENDERER_USE_VIDEO);
return original(cookie, flags | VIRGL_RENDERER_USE_VIDEO, &callbacks);
}

View File

@ -0,0 +1,956 @@
{
"pid": 347888,
"sent": 300,
"elapsed": 5.903147364006145,
"frames": [
{
"seq": 0,
"t": 105428.1534139,
"age_ms": null
},
{
"seq": 2,
"t": 105428.245812751,
"age_ms": 76.70932200562675
},
{
"seq": 3,
"t": 105428.270851015,
"age_ms": 84.91618899279274
},
{
"seq": 4,
"t": 105428.293949998,
"age_ms": 91.1621919949539
},
{
"seq": 7,
"t": 105428.313522754,
"age_ms": 60.63829601043835
},
{
"seq": 9,
"t": 105428.36120967,
"age_ms": 74.82516700110864
},
{
"seq": 10,
"t": 105428.404278657,
"age_ms": 101.67262800678145
},
{
"seq": 11,
"t": 105428.42481449,
"age_ms": 105.57918800623156
},
{
"seq": 14,
"t": 105428.446406732,
"age_ms": 77.16869399882853
},
{
"seq": 16,
"t": 105428.494538438,
"age_ms": 91.36139899783302
},
{
"seq": 17,
"t": 105428.52063457,
"age_ms": 101.27333899436053
},
{
"seq": 18,
"t": 105428.53777309,
"age_ms": 101.83479300758336
},
{
"seq": 20,
"t": 105428.55776001,
"age_ms": 87.8100879926933
},
{
"seq": 21,
"t": 105428.585062759,
"age_ms": 99.12376799911726
},
{
"seq": 23,
"t": 105428.607380956,
"age_ms": 88.16970999760088
},
{
"seq": 24,
"t": 105428.62803433,
"age_ms": 91.51044000464026
},
{
"seq": 26,
"t": 105428.653982296,
"age_ms": 84.73769000556786
},
{
"seq": 27,
"t": 105428.671523897,
"age_ms": 85.56135100661777
},
{
"seq": 29,
"t": 105428.693329056,
"age_ms": 73.62613300210796
},
{
"seq": 30,
"t": 105428.71554342,
"age_ms": 79.67409599223174
},
{
"seq": 33,
"t": 105428.759986148,
"age_ms": 73.51180099067278
},
{
"seq": 34,
"t": 105428.780384898,
"age_ms": 77.78031600173563
},
{
"seq": 35,
"t": 105428.804866082,
"age_ms": 85.44876900850795
},
{
"seq": 37,
"t": 105428.826849156,
"age_ms": 74.08988100360148
},
{
"seq": 38,
"t": 105428.846754409,
"age_ms": 77.54231798753608
},
{
"seq": 39,
"t": 105428.871434508,
"age_ms": 85.43885299877729
},
{
"seq": 41,
"t": 105428.891846674,
"age_ms": 72.09051700192504
},
{
"seq": 42,
"t": 105428.913852206,
"age_ms": 77.92352300020866
},
{
"seq": 44,
"t": 105428.958929596,
"age_ms": 89.06162100902293
},
{
"seq": 45,
"t": 105428.97957247,
"age_ms": 93.65009299654048
},
{
"seq": 47,
"t": 105429.004751899,
"age_ms": 85.4516850085929
},
{
"seq": 48,
"t": 105429.027443718,
"age_ms": 90.87490101228468
},
{
"seq": 50,
"t": 105429.053916972,
"age_ms": 84.66039699851535
},
{
"seq": 51,
"t": 105429.071056076,
"age_ms": 85.11160399939399
},
{
"seq": 53,
"t": 105429.092447945,
"age_ms": 73.20817701111082
},
{
"seq": 54,
"t": 105429.113320942,
"age_ms": 77.4183589965105
},
{
"seq": 56,
"t": 105429.162054476,
"age_ms": 92.15397598745767
},
{
"seq": 57,
"t": 105429.188391523,
"age_ms": 102.38120600115508
},
{
"seq": 59,
"t": 105429.207277699,
"age_ms": 87.94729399960488
},
{
"seq": 60,
"t": 105429.228784192,
"age_ms": 92.30301700881682
},
{
"seq": 62,
"t": 105429.254511368,
"age_ms": 85.08243699907325
},
{
"seq": 64,
"t": 105429.292430427,
"age_ms": 89.10770299553405
},
{
"seq": 65,
"t": 105429.316827028,
"age_ms": 97.27957099676132
},
{
"seq": 66,
"t": 105429.338625186,
"age_ms": 102.53099701367319
},
{
"seq": 69,
"t": 105429.358508689,
"age_ms": 72.28722400031984
},
{
"seq": 70,
"t": 105429.385677564,
"age_ms": 82.93824100110214
},
{
"seq": 72,
"t": 105429.428523718,
"age_ms": 91.8258540041279
},
{
"seq": 73,
"t": 105429.45409952,
"age_ms": 101.4579619950382
},
{
"seq": 74,
"t": 105429.472724364,
"age_ms": 103.49319899978582
},
{
"seq": 77,
"t": 105429.494538855,
"age_ms": 75.28862099570688
},
{
"seq": 79,
"t": 105429.539811953,
"age_ms": 86.78955100185703
},
{
"seq": 80,
"t": 105429.560813866,
"age_ms": 91.04115000809543
},
{
"seq": 82,
"t": 105429.604970762,
"age_ms": 102.33208099089097
},
{
"seq": 84,
"t": 105429.627038418,
"age_ms": 90.3449460020056
},
{
"seq": 85,
"t": 105429.670905108,
"age_ms": 118.16306799300946
},
{
"seq": 88,
"t": 105429.693498344,
"age_ms": 90.3846120054368
},
{
"seq": 89,
"t": 105429.714060718,
"age_ms": 94.75637700234074
},
{
"seq": 90,
"t": 105429.737692574,
"age_ms": 101.76654299721122
},
{
"seq": 92,
"t": 105429.758156073,
"age_ms": 88.57978999731131
},
{
"seq": 94,
"t": 105429.780499353,
"age_ms": 77.95064699894283
},
{
"seq": 95,
"t": 105429.804206458,
"age_ms": 84.9016049905913
},
{
"seq": 96,
"t": 105429.823491923,
"age_ms": 87.11388299707323
},
{
"seq": 98,
"t": 105429.849294056,
"age_ms": 79.98792600119486
},
{
"seq": 101,
"t": 105429.892663165,
"age_ms": 73.37909100169782
},
{
"seq": 102,
"t": 105429.912658542,
"age_ms": 75.98219999636058
},
{
"seq": 103,
"t": 105429.941161492,
"age_ms": 88.40245699684601
},
{
"seq": 104,
"t": 105429.961982864,
"age_ms": 91.98293500230648
},
{
"seq": 106,
"t": 105429.987757289,
"age_ms": 85.13668499654159
},
{
"seq": 107,
"t": 105430.027661419,
"age_ms": 108.37945899402257
},
{
"seq": 110,
"t": 105430.054136132,
"age_ms": 84.88089599995874
},
{
"seq": 111,
"t": 105430.071107527,
"age_ms": 84.7916459897533
},
{
"seq": 112,
"t": 105430.092316814,
"age_ms": 89.22232700570021
},
{
"seq": 113,
"t": 105430.113676016,
"age_ms": 94.38450400193688
},
{
"seq": 114,
"t": 105430.138229824,
"age_ms": 102.31720500451047
},
{
"seq": 116,
"t": 105430.159897899,
"age_ms": 90.03753098659217
},
{
"seq": 117,
"t": 105430.179952484,
"age_ms": 93.9825890091015
},
{
"seq": 120,
"t": 105430.229120474,
"age_ms": 92.66834800655488
},
{
"seq": 121,
"t": 105430.253855405,
"age_ms": 101.25029500341043
},
{
"seq": 123,
"t": 105430.271252632,
"age_ms": 85.17576899612322
},
{
"seq": 125,
"t": 105430.29235546,
"age_ms": 73.1212590035284
},
{
"seq": 126,
"t": 105430.314346992,
"age_ms": 78.40418499836233
},
{
"seq": 127,
"t": 105430.357702684,
"age_ms": 104.9824380024802
},
{
"seq": 129,
"t": 105430.411405188,
"age_ms": 125.40860500303097
},
{
"seq": 133,
"t": 105430.455217335,
"age_ms": 102.58903598878533
},
{
"seq": 134,
"t": 105430.473050893,
"age_ms": 103.76444699068088
},
{
"seq": 137,
"t": 105430.496897704,
"age_ms": 77.60648099065293
},
{
"seq": 139,
"t": 105430.538714573,
"age_ms": 82.67503400566056
},
{
"seq": 141,
"t": 105430.559114781,
"age_ms": 73.22888400813099
},
{
"seq": 142,
"t": 105430.580059235,
"age_ms": 77.5306479918072
},
{
"seq": 143,
"t": 105430.603617007,
"age_ms": 84.19373299693689
},
{
"seq": 145,
"t": 105430.636492597,
"age_ms": 83.92306799942162
},
{
"seq": 146,
"t": 105430.657736592,
"age_ms": 88.39924899803009
},
{
"seq": 148,
"t": 105430.704287764,
"age_ms": 101.67087501031347
},
{
"seq": 149,
"t": 105430.725742341,
"age_ms": 106.50697100209072
},
{
"seq": 150,
"t": 105430.74684342,
"age_ms": 109.20107999118045
},
{
"seq": 152,
"t": 105430.770608565,
"age_ms": 100.97029600001406
},
{
"seq": 153,
"t": 105430.787358296,
"age_ms": 101.42587700102013
},
{
"seq": 156,
"t": 105430.829396246,
"age_ms": 92.88359600759577
},
{
"seq": 158,
"t": 105430.87156807,
"age_ms": 102.28599699621554
},
{
"seq": 160,
"t": 105430.891616822,
"age_ms": 88.57103899936192
},
{
"seq": 162,
"t": 105430.918912279,
"age_ms": 83.00665600108914
},
{
"seq": 165,
"t": 105430.962190387,
"age_ms": 76.24323900381569
},
{
"seq": 166,
"t": 105431.004959541,
"age_ms": 102.39041199383792
},
{
"seq": 168,
"t": 105431.026766448,
"age_ms": 90.42427700478584
},
{
"seq": 169,
"t": 105431.047782944,
"age_ms": 95.17228900222108
},
{
"seq": 170,
"t": 105431.071592423,
"age_ms": 102.2690789977787
},
{
"seq": 173,
"t": 105431.09478503,
"age_ms": 75.593702000333
},
{
"seq": 174,
"t": 105431.120900411,
"age_ms": 84.53293799539097
},
{
"seq": 177,
"t": 105431.161776368,
"age_ms": 75.85619999736082
},
{
"seq": 178,
"t": 105431.187864332,
"age_ms": 85.16380899527576
},
{
"seq": 179,
"t": 105431.207349004,
"age_ms": 87.94950100127608
},
{
"seq": 180,
"t": 105431.228066835,
"age_ms": 91.59181200084276
},
{
"seq": 181,
"t": 105431.272055731,
"age_ms": 119.49655698845163
},
{
"seq": 185,
"t": 105431.292751979,
"age_ms": 73.5018819977995
},
{
"seq": 186,
"t": 105431.313710141,
"age_ms": 77.81531299406197
},
{
"seq": 187,
"t": 105431.34237759,
"age_ms": 89.66332300042268
},
{
"seq": 188,
"t": 105431.363299878,
"age_ms": 93.4575919964118
},
{
"seq": 189,
"t": 105431.387636686,
"age_ms": 101.75283200806007
},
{
"seq": 192,
"t": 105431.427538483,
"age_ms": 91.16306499345228
},
{
"seq": 193,
"t": 105431.454225527,
"age_ms": 101.59679201024119
},
{
"seq": 194,
"t": 105431.471497337,
"age_ms": 102.22970400354825
},
{
"seq": 197,
"t": 105431.494456904,
"age_ms": 75.2197869878728
},
{
"seq": 198,
"t": 105431.520849658,
"age_ms": 84.94651899673045
},
{
"seq": 199,
"t": 105431.540776202,
"age_ms": 87.99558300233912
},
{
"seq": 201,
"t": 105431.562194321,
"age_ms": 76.29194800392725
},
{
"seq": 202,
"t": 105431.587271958,
"age_ms": 84.68810399062932
},
{
"seq": 203,
"t": 105431.605494596,
"age_ms": 86.1228030116763
},
{
"seq": 205,
"t": 105431.626329093,
"age_ms": 73.76467098947614
},
{
"seq": 206,
"t": 105431.648745288,
"age_ms": 79.52388600097038
},
{
"seq": 207,
"t": 105431.674128299,
"age_ms": 88.0037509923568
},
{
"seq": 209,
"t": 105431.695154419,
"age_ms": 75.54732699645683
},
{
"seq": 210,
"t": 105431.738316154,
"age_ms": 102.39157899923157
},
{
"seq": 212,
"t": 105431.759552565,
"age_ms": 89.72282300237566
},
{
"seq": 213,
"t": 105431.780599102,
"age_ms": 94.7114589944249
},
{
"seq": 214,
"t": 105431.80417379,
"age_ms": 101.60816600546241
},
{
"seq": 217,
"t": 105431.829639633,
"age_ms": 77.03335898986552
},
{
"seq": 218,
"t": 105431.853820693,
"age_ms": 84.53789699706249
},
{
"seq": 219,
"t": 105431.872390412,
"age_ms": 86.20155300013721
},
{
"seq": 221,
"t": 105431.892316664,
"age_ms": 73.08888300030958
},
{
"seq": 222,
"t": 105431.916984512,
"age_ms": 81.07058401219547
},
{
"seq": 225,
"t": 105431.96153982,
"age_ms": 75.62286699248943
},
{
"seq": 227,
"t": 105432.005361592,
"age_ms": 85.29914100654423
},
{
"seq": 229,
"t": 105432.026606461,
"age_ms": 74.0560429985635
},
{
"seq": 230,
"t": 105432.059655882,
"age_ms": 90.4414839897072
},
{
"seq": 231,
"t": 105432.080805377,
"age_ms": 94.71175000362564
},
{
"seq": 232,
"t": 105432.104147025,
"age_ms": 100.76554601255339
},
{
"seq": 233,
"t": 105432.121930707,
"age_ms": 102.61295099917334
},
{
"seq": 236,
"t": 105432.170750447,
"age_ms": 100.93208600301296
},
{
"seq": 238,
"t": 105432.206429519,
"age_ms": 103.65856900170911
},
{
"seq": 240,
"t": 105432.227740013,
"age_ms": 91.39639500062913
},
{
"seq": 243,
"t": 105432.272488695,
"age_ms": 85.91980300843716
},
{
"seq": 245,
"t": 105432.293274775,
"age_ms": 74.0350429987302
},
{
"seq": 246,
"t": 105432.314011564,
"age_ms": 78.08451799792238
},
{
"seq": 247,
"t": 105432.339099701,
"age_ms": 86.04726099292748
},
{
"seq": 249,
"t": 105432.387091989,
"age_ms": 101.16104299959261
},
{
"seq": 250,
"t": 105432.407657862,
"age_ms": 105.06789399369154
},
{
"seq": 253,
"t": 105432.427561072,
"age_ms": 74.94941201002803
},
{
"seq": 255,
"t": 105432.45497407,
"age_ms": 68.98515799548477
},
{
"seq": 256,
"t": 105432.496899728,
"age_ms": 93.793004998588
},
{
"seq": 257,
"t": 105432.520948955,
"age_ms": 101.70062301040161
},
{
"seq": 260,
"t": 105432.562666656,
"age_ms": 92.8617189929355
},
{
"seq": 263,
"t": 105432.604811355,
"age_ms": 85.15914200688712
},
{
"seq": 264,
"t": 105432.627594756,
"age_ms": 91.31764501216821
},
{
"seq": 265,
"t": 105432.671091321,
"age_ms": 118.50606100051664
},
{
"seq": 267,
"t": 105432.695090965,
"age_ms": 108.60695599694736
},
{
"seq": 269,
"t": 105432.72072714,
"age_ms": 101.51191600016318
},
{
"seq": 270,
"t": 105432.738190282,
"age_ms": 102.24107799876947
},
{
"seq": 272,
"t": 105432.757900994,
"age_ms": 88.12858098826837
},
{
"seq": 273,
"t": 105432.784986161,
"age_ms": 99.06834800494835
},
{
"seq": 275,
"t": 105432.827612981,
"age_ms": 108.21612399013247
},
{
"seq": 276,
"t": 105432.85394186,
"age_ms": 117.43798399402294
},
{
"seq": 278,
"t": 105432.875595352,
"age_ms": 106.34567799570505
},
{
"seq": 280,
"t": 105432.896457264,
"age_ms": 93.35258998908103
},
{
"seq": 281,
"t": 105432.920738073,
"age_ms": 101.49383198586293
},
{
"seq": 282,
"t": 105432.938179632,
"age_ms": 102.25740999158006
},
{
"seq": 284,
"t": 105432.957464804,
"age_ms": 87.6137919985922
},
{
"seq": 285,
"t": 105432.988810611,
"age_ms": 102.87865699501708
},
{
"seq": 287,
"t": 105433.009949605,
"age_ms": 90.39889999257866
},
{
"seq": 288,
"t": 105433.030575853,
"age_ms": 94.14504400047008
},
{
"seq": 289,
"t": 105433.054055749,
"age_ms": 101.48070599825587
},
{
"seq": 290,
"t": 105433.072260303,
"age_ms": 102.54265800176654
},
{
"seq": 292,
"t": 105433.093066217,
"age_ms": 89.86952899431344
},
{
"seq": 295,
"t": 105433.138782351,
"age_ms": 85.84338599757757
},
{
"seq": 296,
"t": 105433.159999512,
"age_ms": 90.23323500878178
},
{
"seq": 297,
"t": 105433.180393011,
"age_ms": 94.282126010512
},
{
"seq": 299,
"t": 105433.210494575,
"age_ms": 91.20564500335604
},
{
"seq": 300,
"t": 105433.251180948,
"age_ms": 114.66658300196286
}
],
"fresh_video_updates_per_second": 36.6,
"motion_to_decoded_marker_ms": {
"p50": 89.69307300139917,
"p95": 108.21612399013247,
"maximum": 125.40860500303097
},
"frame_gap_ms": {
"p50": 23.267127500730567,
"p95": 45.71613400185015,
"maximum": 92.3988510039635
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
}

View File

@ -0,0 +1,31 @@
# Temporary Windows reference workload with the same geometry/marker as GTK.
$ErrorActionPreference='Stop'
Add-Type -ReferencedAssemblies System.Windows.Forms,System.Drawing -TypeDefinition @'
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
public class VDIDragReference : Form {
[DllImport("user32.dll")] public static extern bool SetProcessDPIAware();
int seq=0; bool held=false; Point target=new Point(800,700);
readonly Timer expiry=new Timer();
public VDIDragReference() {
Text="VDI temporary drag reference"; FormBorderStyle=FormBorderStyle.None;
Bounds=Screen.PrimaryScreen.Bounds; TopMost=true; DoubleBuffered=true;
expiry.Interval=600000; expiry.Tick+=delegate { Close(); }; expiry.Start();
}
protected override void OnMouseDown(MouseEventArgs e) { if(e.Button==MouseButtons.Left) { held=true; seq=0; Invalidate(); } base.OnMouseDown(e); }
protected override void OnMouseUp(MouseEventArgs e) { if(e.Button==MouseButtons.Left) { held=false; Invalidate(); } base.OnMouseUp(e); }
protected override void OnMouseMove(MouseEventArgs e) { if(held) { seq=Math.Max(0,Math.Min(300,(int)Math.Round((e.X-800)/4.0))); target=e.Location; Invalidate(); } base.OnMouseMove(e); }
protected override void OnPaint(PaintEventArgs e) {
var g=e.Graphics; g.Clear(Color.FromArgb(240,245,250));
using(var f=new Font("Arial",20)) g.DrawString("Windows 2560 x 1440: held-button selection / video response probe",f,Brushes.Black,60,50);
if(held) { using(var b=new SolidBrush(Color.FromArgb(50,40,100,230))) g.FillRectangle(b,500,350,Math.Max(1,target.X-500),Math.Max(1,target.Y-350)); g.DrawRectangle(Pens.Blue,500,350,Math.Max(1,target.X-500),Math.Max(1,target.Y-350)); }
for(int i=0;i<16;i++) g.FillRectangle((seq&(1<<i))!=0?Brushes.White:Brushes.Black,40+i*40,1350,40,70);
g.FillRectangle(held?Brushes.White:Brushes.Black,720,1350,40,70);
for(int i=0;i<8;i++) g.FillRectangle((0xa5&(1<<i))!=0?Brushes.White:Brushes.Black,800+i*40,1350,40,70);
}
}
'@
[VDIDragReference]::SetProcessDPIAware() | Out-Null
[Windows.Forms.Application]::Run((New-Object VDIDragReference))

View File

@ -0,0 +1 @@
{"pid": 310764, "sent": 300, "elapsed": 6.016666693991283, "frames": [{"seq": 0, "t": 101760.163802624, "age_ms": null}, {"seq": 1, "t": 101760.296015875, "age_ms": 133.10923000972252}, {"seq": 4, "t": 101760.379533579, "age_ms": 161.50291000667494}, {"seq": 7, "t": 101760.480417591, "age_ms": 217.41995699994732}, {"seq": 12, "t": 101760.512667599, "age_ms": 166.10180400311947}, {"seq": 14, "t": 101760.596377799, "age_ms": 215.97011599806137}, {"seq": 20, "t": 101760.67948922, "age_ms": 197.68070199643262}, {"seq": 25, "t": 101760.762840386, "age_ms": 199.35424700088333}, {"seq": 30, "t": 101760.829595517, "age_ms": 182.33180600509513}, {"seq": 33, "t": 101761.008848269, "age_ms": 312.2149850096321}, {"seq": 39, "t": 101761.062963149, "age_ms": 266.1207530036336}, {"seq": 47, "t": 101761.146170527, "age_ms": 216.5376860066317}, {"seq": 53, "t": 101761.197215686, "age_ms": 167.09928099589888}, {"seq": 55, "t": 101761.279807953, "age_ms": 215.96486600174103}, {"seq": 61, "t": 101761.363416363, "age_ms": 199.81915400421713}, {"seq": 66, "t": 101761.463394772, "age_ms": 216.6610580025008}, {"seq": 71, "t": 101761.546294156, "age_ms": 211.68329699139576}, {"seq": 84, "t": 101761.69342173, "age_ms": 146.2050529953558}, {"seq": 87, "t": 101761.796632606, "age_ms": 199.1086699999869}, {"seq": 90, "t": 101761.880199309, "age_ms": 229.0143150021322}, {"seq": 96, "t": 101761.962779618, "age_ms": 215.69070499390364}, {"seq": 101, "t": 101762.046435277, "age_ms": 213.67825201014057}, {"seq": 107, "t": 101762.129679404, "age_ms": 199.23175100120716}, {"seq": 112, "t": 101762.246941582, "age_ms": 233.63129299832508}, {"seq": 117, "t": 101762.279609539, "age_ms": 183.31936698814388}, {"seq": 120, "t": 101762.31287044, "age_ms": 166.52762799640186}, {"seq": 124, "t": 101762.396279063, "age_ms": 182.6619650091743}, {"seq": 128, "t": 101762.429745585, "age_ms": 149.0149050077889}, {"seq": 130, "t": 101762.529497666, "age_ms": 215.71520499128383}, {"seq": 135, "t": 101762.629958188, "age_ms": 232.73327099741437}, {"seq": 141, "t": 101762.712961988, "age_ms": 213.7640000000829}, {"seq": 147, "t": 101762.762934713, "age_ms": 166.24121800123248}, {"seq": 149, "t": 101762.846374544, "age_ms": 215.4815849935403}, {"seq": 154, "t": 101762.929672628, "age_ms": 215.74057900579646}, {"seq": 160, "t": 101763.030870759, "age_ms": 217.47566500562243}, {"seq": 165, "t": 101763.113285988, "age_ms": 216.7969720030669}, {"seq": 170, "t": 101763.196582322, "age_ms": 213.62983599829022}, {"seq": 176, "t": 101763.296267321, "age_ms": 216.60476799297612}, {"seq": 181, "t": 101763.362820915, "age_ms": 198.94067400309723}, {"seq": 184, "t": 101763.396304062, "age_ms": 183.33715799963102}, {"seq": 187, "t": 101763.479597771, "age_ms": 214.87551600148436}, {"seq": 193, "t": 101763.579797841, "age_ms": 215.9762410010444}, {"seq": 198, "t": 101763.679638295, "age_ms": 232.39523799566086}, {"seq": 207, "t": 101763.779802783, "age_ms": 183.4899880050216}, {"seq": 209, "t": 101763.863460775, "age_ms": 232.98468299617525}, {"seq": 215, "t": 101763.979812099, "age_ms": 248.9276910055196}, {"seq": 221, "t": 101764.029933571, "age_ms": 199.56832600291818}, {"seq": 225, "t": 101764.129736984, "age_ms": 232.58890000579413}, {"seq": 231, "t": 101764.213012902, "age_ms": 216.24281798722222}, {"seq": 237, "t": 101764.313547798, "age_ms": 216.62168399780057}, {"seq": 242, "t": 101764.396249438, "age_ms": 216.31660898856353}, {"seq": 248, "t": 101764.49642005, "age_ms": 216.22940099041443}, {"seq": 253, "t": 101764.596612246, "age_ms": 233.52746199816465}, {"seq": 259, "t": 101764.697007437, "age_ms": 233.67912600224372}, {"seq": 265, "t": 101764.780397102, "age_ms": 216.12790400104132}, {"seq": 271, "t": 101764.863004827, "age_ms": 199.87865300208796}, {"seq": 275, "t": 101764.979939471, "age_ms": 249.0676879970124}, {"seq": 281, "t": 101765.030203273, "age_ms": 199.91044299968053}, {"seq": 284, "t": 101765.138975813, "age_ms": 259.0967069991166}, {"seq": 291, "t": 101765.188345095, "age_ms": 191.91225299437065}, {"seq": 296, "t": 101765.288963114, "age_ms": 209.33922700351104}, {"seq": 300, "t": 101765.374608477, "age_ms": 227.49535099137574}], "fresh_video_updates_per_second": 11.8, "motion_to_decoded_marker_ms": {"p50": 215.69070499390364, "p95": 249.0676879970124, "maximum": 312.2149850096321}, "frame_gap_ms": {"p50": 83.43983099621255, "p95": 117.26217799878214, "maximum": 179.25275200104807}, "last_motion_seen": 300, "release_visible": true, "method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"pid": 299860, "sent": 300, "elapsed": 6.156590503000189, "frames": [{"seq": 0, "t": 101430.99398335, "age_ms": null}, {"seq": 1, "t": 101431.319368405, "age_ms": 326.33528200676665}, {"seq": 10, "t": 101431.560468432, "age_ms": 428.58509899815544}, {"seq": 27, "t": 101431.82799284, "age_ms": 410.26244399836287}, {"seq": 54, "t": 101432.243882278, "age_ms": 378.6818079970544}, {"seq": 68, "t": 101432.544293376, "age_ms": 445.7647390081547}, {"seq": 95, "t": 101432.94411119, "age_ms": 395.4152090009302}, {"seq": 199, "t": 101434.777525225, "age_ms": 495.6079499970656}, {"seq": 220, "t": 101435.030036152, "age_ms": 398.25189400289673}, {"seq": 239, "t": 101435.59441137, "age_ms": 634.569867994287}, {"seq": 294, "t": 101436.262625077, "age_ms": 397.27337699150667}, {"seq": 300, "t": 101436.334007074, "age_ms": 357.2742699907394}], "fresh_video_updates_per_second": 2.0, "motion_to_decoded_marker_ms": {"p50": 398.25189400289673, "p95": 634.569867994287, "maximum": 634.569867994287}, "frame_gap_ms": {"p50": 325.38505500997417, "p95": 1833.4140350052621, "maximum": 1833.4140350052621}, "last_motion_seen": 300, "release_visible": true, "method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"}

View File

@ -0,0 +1,120 @@
{
"baseline": {
"pid": 299860,
"sent": 300,
"elapsed": 6.156590503000189,
"fresh_video_updates_per_second": 2.0,
"motion_to_decoded_marker_ms": {
"p50": 398.25189400289673,
"p95": 634.569867994287,
"maximum": 634.569867994287
},
"frame_gap_ms": {
"p50": 325.38505500997417,
"p95": 1833.4140350052621,
"maximum": 1833.4140350052621
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
},
"accelerated30": {
"pid": 310764,
"sent": 300,
"elapsed": 6.016666693991283,
"fresh_video_updates_per_second": 11.8,
"motion_to_decoded_marker_ms": {
"p50": 215.69070499390364,
"p95": 249.0676879970124,
"maximum": 312.2149850096321
},
"frame_gap_ms": {
"p50": 83.43983099621255,
"p95": 117.26217799878214,
"maximum": 179.25275200104807
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
},
"accelerated45": {
"pid": 314141,
"sent": 300,
"elapsed": 6.074999421995017,
"fresh_video_updates_per_second": 13.2,
"motion_to_decoded_marker_ms": {
"p50": 208.1869029934751,
"p95": 258.44137799867895,
"maximum": 272.018151008524
},
"frame_gap_ms": {
"p50": 81.55834300850984,
"p95": 122.88481299765408,
"maximum": 140.86681800836232
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
},
"hostcpu45": {
"pid": 319425,
"sent": 300,
"elapsed": 6.045887186002801,
"fresh_video_updates_per_second": 2.8,
"motion_to_decoded_marker_ms": {
"p50": 433.26696900476236,
"p95": 545.5845219985349,
"maximum": 545.5845219985349
},
"frame_gap_ms": {
"p50": 333.20788799755974,
"p95": 668.1846940045943,
"maximum": 668.1846940045943
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
},
"threads4-45": {
"pid": 322221,
"sent": 300,
"elapsed": 6.059825101998285,
"fresh_video_updates_per_second": 11.6,
"motion_to_decoded_marker_ms": {
"p50": 211.1673344988958,
"p95": 259.3057539925212,
"maximum": 261.4585800038185
},
"frame_gap_ms": {
"p50": 83.62990950263338,
"p95": 126.65964200277813,
"maximum": 199.5532830042066
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
},
"final": {
"pid": 325044,
"sent": 300,
"elapsed": 6.072603578999406,
"fresh_video_updates_per_second": 12.4,
"motion_to_decoded_marker_ms": {
"p50": 224.4429390048026,
"p95": 308.31432100967504,
"maximum": 327.4417700013146
},
"frame_gap_ms": {
"p50": 75.51110150234308,
"p95": 149.420955000096,
"maximum": 176.92619799345266
},
"last_motion_seen": 300,
"release_visible": true,
"method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"
},
"improvement_percent": {
"p50": 43.64297009390492,
"p95": 51.41365252904653
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -0,0 +1,93 @@
"""Run on the box with drag-source.py visibly filling the Ubuntu video."""
import ctypes as C
import json
import os
import statistics
import subprocess
import time
from pathlib import Path
os.environ.update(DISPLAY=':0', XAUTHORITY='/home/armbian/.Xauthority')
x = C.CDLL('libX11.so.6')
t = C.CDLL('libXtst.so.6')
x.XOpenDisplay.restype = C.c_void_p
x.XDefaultRootWindow.argtypes = [C.c_void_p]
x.XDefaultRootWindow.restype = C.c_ulong
x.XSync.argtypes = [C.c_void_p, C.c_int]
x.XGetImage.argtypes = [C.c_void_p,C.c_ulong,C.c_int,C.c_int,C.c_uint,C.c_uint,C.c_ulong,C.c_int]
x.XGetImage.restype = C.c_void_p
x.XGetPixel.argtypes = [C.c_void_p,C.c_int,C.c_int]
x.XGetPixel.restype = C.c_ulong
x.XDestroyImage.argtypes = [C.c_void_p]
t.XTestFakeMotionEvent.argtypes = [C.c_void_p,C.c_int,C.c_int,C.c_int,C.c_ulong]
t.XTestFakeButtonEvent.argtypes = [C.c_void_p,C.c_uint,C.c_int,C.c_ulong]
d = x.XOpenDisplay(None)
assert d
root = x.XDefaultRootWindow(d)
def read():
image = x.XGetImage(d, root, 40, 1380, 1120, 1, 0xffffffff, 2)
assert image
try:
magic = sum(1 << i for i in range(8)
if (x.XGetPixel(image, 780+i*40, 0) & 0xffffff) > 0xc0c0c0)
assert magic == 0xa5, ('probe signature absent', magic)
pixels = [x.XGetPixel(image, i*40+20, 0) & 0xffffff for i in range(16)]
if any(0x404040 < v < 0xc0c0c0 for v in pixels):
return -1, False
seq = sum(1 << i for i,v in enumerate(pixels) if v > 0xc0c0c0)
held = (x.XGetPixel(image, 700, 0) & 0xffffff) > 0xc0c0c0
return seq, held
finally:
x.XDestroyImage(image)
pid = int(subprocess.check_output(['pgrep','-x','moonlight']).strip())
focus = int(subprocess.check_output(['xdotool','getwindowfocus','getwindowpid']).strip())
assert focus == pid
assert read() == (0, False), ('test window not visible/ready',read())
t.XTestFakeMotionEvent(d, -1, 800, 700, 0)
x.XSync(d, 0)
time.sleep(.5)
sent, frames = {}, []
start = time.monotonic()
last = -1
try:
t.XTestFakeButtonEvent(d, 1, 1, 0)
x.XSync(d, 0)
time.sleep(.8)
assert read()[1], 'held-button marker did not appear'
start = time.monotonic()
for seq in range(1, 301):
target = start + (seq-1)/60
time.sleep(max(0, target-time.monotonic()))
t.XTestFakeMotionEvent(d, -1, 800+4*seq, 700+seq, 0)
x.XSync(d, 0)
sent[seq] = time.monotonic()
seen, held = read()
now = time.monotonic()
if 0 <= seen <= 300 and seen != last and held:
frames.append(dict(seq=seen,t=now,age_ms=(now-sent[seen])*1000 if seen in sent else None))
last = seen
deadline = time.monotonic()+2
while last < 300 and time.monotonic()<deadline:
seen, held = read()
now = time.monotonic()
if 0 <= seen <= 300 and seen != last and held:
frames.append(dict(seq=seen,t=now,age_ms=(now-sent[seen])*1000 if seen in sent else None))
last = seen
time.sleep(.002)
finally:
t.XTestFakeButtonEvent(d, 1, 0, 0)
x.XSync(d, 0)
time.sleep(.8)
gaps = [(b['t']-a['t'])*1000 for a,b in zip(frames,frames[1:])]
ages = [a['age_ms'] for a in frames if a['age_ms'] is not None]
def stats(items):
items=sorted(items)
return dict(p50=statistics.median(items),p95=items[int(len(items)*.95)],maximum=max(items)) if items else None
result = dict(pid=pid,sent=300,elapsed=time.monotonic()-start,frames=frames,
fresh_video_updates_per_second=sum(f['t']<start+5 for f in frames)/5,
motion_to_decoded_marker_ms=stats(ages),frame_gap_ms=stats(gaps),
last_motion_seen=last,release_visible=not read()[1],
method='60Hz XTest held drag to first observed unique decoded marker; no USB/scanout')
print(json.dumps(result))

View File

@ -0,0 +1,89 @@
"""Controlled 2K rubber-band workload, with sequence numbers in each paint."""
import json
import time
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
window = Gtk.Window(title='Ubuntu drag rendering probe')
area = Gtk.DrawingArea()
window.add(area)
area.set_events(Gdk.EventMask.POINTER_MOTION_MASK | Gdk.EventMask.BUTTON_PRESS_MASK |
Gdk.EventMask.BUTTON_RELEASE_MASK)
sequence, held, draws = 0, False, 0
target = (800, 700)
received = 0.0
def log(**kw):
print(json.dumps(dict(t=time.monotonic(), **kw)), flush=True)
def motion(widget, event):
global sequence, target, received
if held:
sequence = max(0, min(300, round((event.x_root - 800) / 4)))
target = (event.x_root, event.y_root)
received = time.monotonic()
log(event='motion', seq=sequence, x=target[0], y=target[1])
area.queue_draw()
return False
def button(widget, event):
global held, sequence, received
if event.type not in (Gdk.EventType.BUTTON_PRESS, Gdk.EventType.BUTTON_RELEASE):
return False
held = event.type == Gdk.EventType.BUTTON_PRESS
if held:
sequence = 0
received = time.monotonic()
log(event='press' if held else 'release', seq=sequence, x=event.x_root, y=event.y_root)
area.queue_draw()
return False
def draw(widget, cr):
global draws
draws += 1
cr.set_source_rgb(.94, .96, .98)
cr.paint()
cr.set_source_rgb(.1, .15, .2)
cr.select_font_face('sans')
cr.set_font_size(26)
cr.move_to(60, 70)
cr.show_text('Ubuntu 2560 x 1440: held-button selection / video response probe')
cr.set_font_size(18)
cr.move_to(60, 110)
cr.show_text('Temporary test window. The mouse pointer is separate from the rendered selection.')
if held:
cr.set_source_rgba(.1, .4, .9, .22)
cr.rectangle(500, 350, max(1, target[0]-500), max(1, target[1]-350))
cr.fill_preserve()
cr.set_source_rgb(.1, .4, .9)
cr.set_line_width(2)
cr.stroke()
for i in range(16):
v = float(bool(sequence & (1 << i)))
cr.set_source_rgb(v, v, v)
cr.rectangle(40+i*40, 1350, 40, 70)
cr.fill()
v = float(held)
cr.set_source_rgb(v, v, v)
cr.rectangle(720, 1350, 40, 70)
cr.fill()
for i in range(8):
v = float(bool(0xa5 & (1 << i)))
cr.set_source_rgb(v, v, v)
cr.rectangle(800+i*40, 1350, 40, 70)
cr.fill()
log(event='paint', seq=sequence, held=held, draw=draws,
event_to_paint_ms=(time.monotonic()-received)*1000 if received else None)
return False
area.connect('motion-notify-event', motion)
area.connect('button-press-event', button)
area.connect('button-release-event', button)
area.connect('draw', draw)
window.connect('destroy', Gtk.main_quit)
window.fullscreen()
window.show_all()
window.present()
log(event='ready')
Gtk.main()

View File

@ -0,0 +1,4 @@
5d4330f703d7f8e053bc3795ca42bdaf231c9e9dd8ebb00a612013adbcccee03 /home/armbian/vdi-build/rkmpp-experiment/build/moonlight/app/moonlight
PID
325044 /home/armbian/vdi-build/rkmpp-experiment/build/moonlight/app/moonlight stream 192.168.1.72 Desktop --resolution 2560x1440 --fps 30 --bitrate 30000 --display-mode fullscreen --video-codec H.264 --video-decoder hardware --absolute-mouse --capture-system-keys always --keep-awake --no-vsync --no-frame-pacing --audio-on-host
/tmp/vdi-render-desktop-final.png 2560x1440

View File

@ -0,0 +1,43 @@
active
active
Screen 0: minimum 320 x 200, current 2560 x 1440, maximum 8192 x 8192
Virtual-1 connected primary 2560x1440+0+0 (normal left inverted right x axis y axis) 325mm x 203mm
1280x800 74.99 +
5120x2160 50.00
4096x2160 50.00
3840x2160 60.00 50.00 59.94
1920x1440 60.00
2560x1080 50.00
1856x1392 60.00
1792x1344 60.00
2048x1152 60.00
1920x1200 59.88
1920x1080 60.00 50.00
1600x1200 60.00
1680x1050 59.95
1400x1050 59.98
1280x1024 60.02
1440x900 59.89
1280x960 60.00
1360x768 60.02
1280x768 59.87
1024x768 60.00
800x600 60.32
640x480 60.00 59.94
2560x1440_60.00 59.95*
[ 8.194] (II) modeset(0): glamor X acceleration enabled on virgl (Mesa Intel(R) HD Graphics 4600 (HSW GT2))
[ 8.258] (II) AIGLX: Loaded and initialized virtio_gpu
sunshine_name = VDI-Ubuntu
capture = x11
encoder = software
sw_preset = ultrafast
sw_tune = zerolatency
upnp = disabled
origin_web_ui_allowed = pc
hevc_mode = 1
audio_sink = vdi_audio
'Adwaita'
24
false
11月 05 13:35:26 test2-Standard-PC-Q35-ICH9-2009 sunshine[3753]: [2026-11-05 13:35:26.013]: Info: [libx264 @ 0x706ffc003700] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2

View File

@ -0,0 +1 @@
{"pid": 325044, "sent": 300, "elapsed": 6.072603578999406, "frames": [{"seq": 0, "t": 102637.231005679, "age_ms": null}, {"seq": 1, "t": 102637.375821531, "age_ms": 146.55213899095543}, {"seq": 4, "t": 102637.470369078, "age_ms": 182.81436200777534}, {"seq": 7, "t": 102637.497399496, "age_ms": 167.78540800441988}, {"seq": 11, "t": 102637.573050309, "age_ms": 177.17500499566086}, {"seq": 15, "t": 102637.637224947, "age_ms": 165.53578899765853}, {"seq": 18, "t": 102637.753354012, "age_ms": 241.16151900670957}, {"seq": 23, "t": 102637.803491943, "age_ms": 208.07116100331768}, {"seq": 28, "t": 102637.903925304, "age_ms": 215.7119280018378}, {"seq": 33, "t": 102637.986829842, "age_ms": 224.30469100072514}, {"seq": 39, "t": 102638.103472527, "age_ms": 240.95501299598254}, {"seq": 45, "t": 102638.153393749, "age_ms": 190.98508200841025}, {"seq": 48, "t": 102638.236762035, "age_ms": 224.61822899640538}, {"seq": 54, "t": 102638.336837812, "age_ms": 224.58118700888008}, {"seq": 60, "t": 102638.370273502, "age_ms": 157.78010099893436}, {"seq": 62, "t": 102638.470623736, "age_ms": 224.76639499654993}, {"seq": 68, "t": 102638.503828718, "age_ms": 158.22576600476168}, {"seq": 70, "t": 102638.53700745, "age_ms": 157.95072499895468}, {"seq": 73, "t": 102638.620147945, "age_ms": 191.04953999340069}, {"seq": 77, "t": 102638.73692188, "age_ms": 234.24903300474398}, {"seq": 82, "t": 102638.803553509, "age_ms": 214.09055299591273}, {"seq": 86, "t": 102638.853724105, "age_ms": 207.8894460137235}, {"seq": 91, "t": 102638.903663993, "age_ms": 167.7334849955514}, {"seq": 93, "t": 102638.953489547, "age_ms": 191.05974500416778}, {"seq": 96, "t": 102639.004131766, "age_ms": 191.8373250082368}, {"seq": 99, "t": 102639.086846427, "age_ms": 224.23964100016747}, {"seq": 105, "t": 102639.170783459, "age_ms": 207.79056601168122}, {"seq": 110, "t": 102639.320204414, "age_ms": 274.7010260063689}, {"seq": 116, "t": 102639.422243682, "age_ms": 276.0415219963761}, {"seq": 121, "t": 102639.453343128, "age_ms": 224.09468299883883}, {"seq": 126, "t": 102639.536739412, "age_ms": 215.7501249894267}, {"seq": 131, "t": 102639.630087624, "age_ms": 193.12386200181209}, {"seq": 136, "t": 102639.686818657, "age_ms": 208.0063989997143}, {"seq": 137, "t": 102639.770788356, "age_ms": 275.27385800203774}, {"seq": 146, "t": 102639.803607754, "age_ms": 157.53305499674752}, {"seq": 148, "t": 102639.864781731, "age_ms": 177.04986900207587}, {"seq": 149, "t": 102639.936894632, "age_ms": 241.36391900538}, {"seq": 161, "t": 102640.11382083, "age_ms": 218.28323599766009}, {"seq": 162, "t": 102640.136301843, "age_ms": 200.27841700357385}, {"seq": 166, "t": 102640.22026979, "age_ms": 241.42020600265823}, {"seq": 170, "t": 102640.375098223, "age_ms": 327.4417700013146}, {"seq": 178, "t": 102640.420292124, "age_ms": 241.39016401022673}, {"seq": 182, "t": 102640.487361832, "age_ms": 241.62845499813557}, {"seq": 186, "t": 102640.562733222, "age_ms": 249.37393100117333}, {"seq": 194, "t": 102640.652493358, "age_ms": 207.02056199661456}, {"seq": 198, "t": 102640.753895334, "age_ms": 241.7529959930107}, {"seq": 204, "t": 102640.910777676, "age_ms": 297.56761201133486}, {"seq": 210, "t": 102641.020406373, "age_ms": 308.2691169984173}, {"seq": 215, "t": 102641.105655021, "age_ms": 309.69302701123524}, {"seq": 223, "t": 102641.170360193, "age_ms": 240.16399501124397}, {"seq": 227, "t": 102641.214437012, "age_ms": 218.2913959986763}, {"seq": 231, "t": 102641.353738907, "age_ms": 290.888167990488}, {"seq": 237, "t": 102641.4274023, "age_ms": 241.2379070010502}, {"seq": 242, "t": 102641.487311028, "age_ms": 241.81948900513817}, {"seq": 246, "t": 102641.620435734, "age_ms": 308.31432100967504}, {"seq": 254, "t": 102641.688955894, "age_ms": 243.4965669963276}, {"seq": 258, "t": 102641.753825856, "age_ms": 241.21165699034464}, {"seq": 262, "t": 102641.902053013, "age_ms": 321.8129019951448}, {"seq": 266, "t": 102641.937644692, "age_ms": 291.70395400433335}, {"seq": 274, "t": 102642.037546333, "age_ms": 258.58122199133504}, {"seq": 278, "t": 102642.137321683, "age_ms": 290.67028500139713}, {"seq": 284, "t": 102642.187138774, "age_ms": 240.92173400276806}, {"seq": 287, "t": 102642.239541191, "age_ms": 243.85880799673032}, {"seq": 291, "t": 102642.283865634, "age_ms": 221.210964009515}, {"seq": 296, "t": 102642.348700595, "age_ms": 203.1839800038142}, {"seq": 299, "t": 102642.393434244, "age_ms": 197.78553801006638}, {"seq": 300, "t": 102642.496291334, "age_ms": 284.0378059918294}], "fresh_video_updates_per_second": 12.4, "motion_to_decoded_marker_ms": {"p50": 224.4429390048026, "p95": 308.31432100967504, "maximum": 327.4417700013146}, "frame_gap_ms": {"p50": 75.51110150234308, "p95": 149.420955000096, "maximum": 176.92619799345266}, "last_motion_seen": 300, "release_visible": true, "method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"}

View File

@ -0,0 +1,8 @@
PID %CPU %MEM NLWP COMMAND
42901 175 5.0 34 /home/test2/vdi-terminal/native-cursor-v1/sunshine /home/test2/.config/sunshine/sunshine.conf
42867 14.5 0.3 1 /usr/bin/python3 /home/test2/vdi-terminal/native-cursor-v1/host.py stream
6986 2.3 2.6 2 /usr/lib/xorg/Xorg vt2 -displayfd 3 -auth /run/user/1000/gdm/Xauthority -nolisten tcp -background none -noreset -keeptty -novtswitch -verbose 3
7174 1.5 9.1 21 /usr/bin/gnome-shell
42870 0.8 0.2 1 /usr/bin/python3 /home/test2/vdi-terminal/native-cursor-v1/host.py guard
CONFIG_DRM_VIRTIO_GPU=m
CONFIG_DRM_VIRTIO_GPU_KMS=y

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,54 @@
{
"/nodes/starhe/qemu/102/config": {
"bios": "seabios",
"cpu": "x86-64-v2-AES",
"machine": "q35",
"memory": "6144",
"numa": 0,
"cores": 4,
"sockets": 1
},
"/nodes/starhe/status": {
"cpuinfo": {
"cores": 4,
"model": "Intel(R) Core(TM) i7-4720HQ CPU @ 2.60GHz",
"cpus": 8,
"sockets": 1,
"mhz": "3483.812",
"user_hz": 100,
"vendor": "GenuineIntel",
"hvm": "1",
"family": "6",
"flags": "fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc cpuid aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 sdbg fma cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm abm cpuid_fault epb pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid ept_ad fsgsbase tsc_adjust bmi1 avx2 smep bmi2 erms invpcid xsaveopt dtherm ida arat pln pts vnmi md_clear flush_l1d"
},
"memory": {
"used": 21725175808,
"available": 3345096704,
"total": 25070272512,
"free": 2797477888
},
"loadavg": [
"4.14",
"4.33",
"4.17"
],
"cpu": 0,
"uptime": 170533
},
"/nodes/starhe/hardware/pci": [
{
"id": "0000:00:02.0",
"class": "0x030000",
"device_name": "4th Gen Core Processor Integrated Graphics Controller",
"vendor_name": "Intel Corporation",
"iommu_group": null
},
{
"id": "0000:01:00.0",
"class": "0x030200",
"device_name": "GM204M [GeForce GTX 965M]",
"vendor_name": "NVIDIA Corporation",
"iommu_group": null
}
]
}

View File

@ -0,0 +1,13 @@
00:02.0 VGA compatible controller [0300]: Intel Corporation 4th Gen Core Processor Integrated Graphics Controller [8086:0416] (rev 06)
Subsystem: CLEVO/KAPOK Computer Device [1558:6557]
Kernel driver in use: i915
Kernel modules: i915
total 0
drwxr-xr-x 2 root root 80 Nov 3 13:40 by-path
crw-rw---- 1 root video 226, 1 Nov 3 13:40 card1
crw-rw---- 1 root render 226, 128 Nov 3 13:40 renderD128
-cpu qemu64,+aes,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+pni,+popcnt,+sse4.1,+sse4.2,+ssse3 \
pve-manager/9.2.21/4f6e0ac86f9e8c7f (running kernel: 7.0.14-25-pve)
libvirglrenderer1:amd64 1.1.0-2
lrwxrwxrwx 1 root root 0 Nov 5 13:07 /sys/bus/pci/devices/0000:00:02.0/driver -> ../../../bus/pci/drivers/i915
dpkg-query: no packages found matching libgl1-mesa-dri

View File

@ -0,0 +1 @@
{"pid": 319425, "sent": 300, "elapsed": 6.045887186002801, "frames": [{"seq": 0, "t": 102306.790284069, "age_ms": null}, {"seq": 1, "t": 102307.077877785, "age_ms": 300.25234501226805}, {"seq": 11, "t": 102307.344724265, "age_ms": 412.03776400652714}, {"seq": 53, "t": 102308.012908959, "age_ms": 379.3470480013639}, {"seq": 68, "t": 102308.259652478, "age_ms": 376.8192309944425}, {"seq": 80, "t": 102308.478016309, "age_ms": 395.105149000301}, {"seq": 96, "t": 102308.777826205, "age_ms": 428.3570179977687}, {"seq": 123, "t": 102309.237776131, "age_ms": 438.176920011756}, {"seq": 151, "t": 102309.761594355, "age_ms": 494.9406720115803}, {"seq": 172, "t": 102310.144646653, "age_ms": 517.5548249972053}, {"seq": 192, "t": 102310.39478597, "age_ms": 445.3010080032982}, {"seq": 213, "t": 102310.844978701, "age_ms": 545.5845219985349}, {"seq": 237, "t": 102311.17827817, "age_ms": 466.9588079996174}, {"seq": 257, "t": 102311.511394477, "age_ms": 467.3510900029214}, {"seq": 300, "t": 102312.007075675, "age_ms": 244.49452900444157}], "fresh_video_updates_per_second": 2.8, "motion_to_decoded_marker_ms": {"p50": 433.26696900476236, "p95": 545.5845219985349, "maximum": 545.5845219985349}, "frame_gap_ms": {"p50": 333.20788799755974, "p95": 668.1846940045943, "maximum": 668.1846940045943}, "last_motion_seen": 300, "release_visible": true, "method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"}

View File

@ -0,0 +1 @@
{"clicks": [{"seq": 1, "seen": 1, "x": 300, "y": 800}, {"seq": 2, "seen": 2, "x": 1500, "y": 900}, {"seq": 3, "seen": 3, "x": 300, "y": 800}, {"seq": 4, "seen": 4, "x": 1500, "y": 900}, {"seq": 5, "seen": 5, "x": 300, "y": 800}, {"seq": 6, "seen": 6, "x": 1500, "y": 900}, {"seq": 7, "seen": 7, "x": 300, "y": 800}, {"seq": 8, "seen": 8, "x": 1500, "y": 900}, {"seq": 9, "seen": 9, "x": 300, "y": 800}, {"seq": 10, "seen": 10, "x": 1500, "y": 900}, {"seq": 11, "seen": 11, "x": 300, "y": 800}, {"seq": 12, "seen": 12, "x": 1500, "y": 900}, {"seq": 13, "seen": 13, "x": 300, "y": 800}, {"seq": 14, "seen": 14, "x": 1500, "y": 900}, {"seq": 15, "seen": 15, "x": 300, "y": 800}, {"seq": 16, "seen": 16, "x": 1500, "y": 900}], "double_click_start": 16, "double_click_end": 18}

View File

@ -0,0 +1 @@
{"pid": 299860, "sent": 300, "elapsed": 6.11392921199149, "frames": [{"seq": 244, "t": 101509.548426202, "age_ms": 946.6468809987418}, {"seq": 288, "t": 101509.743167794, "age_ms": 407.9408789984882}, {"seq": 300, "t": 101509.860311234, "age_ms": 312.7684690116439}], "fresh_video_updates_per_second": 0.2, "motion_to_decoded_marker_ms": {"p50": 407.9408789984882, "p95": 946.6468809987418, "maximum": 946.6468809987418}, "frame_gap_ms": {"p50": 155.94251600123243, "p95": 194.741592000355, "maximum": 194.741592000355}, "last_motion_seen": 300, "release_visible": true, "method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"}

View File

@ -0,0 +1,7 @@
{
"numbered_clicks": 16,
"presses": 18,
"releases": 18,
"double_click_increment": 2,
"max_coordinate_error_px": 1.3741799423350698
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,47 @@
"""Separate injection timing from decoded-video sampling; run in test window only."""
import ctypes as C
import json
import os
import subprocess
import time
x = C.CDLL('libX11.so.6')
t = C.CDLL('libXtst.so.6')
x.XOpenDisplay.restype = C.c_void_p
x.XSync.argtypes = [C.c_void_p, C.c_int]
t.XTestFakeMotionEvent.argtypes = [C.c_void_p,C.c_int,C.c_int,C.c_int,C.c_ulong]
t.XTestFakeButtonEvent.argtypes = [C.c_void_p,C.c_uint,C.c_int,C.c_ulong]
d=x.XOpenDisplay(None)
assert d
x.XGetInputFocus.argtypes=[C.c_void_p,C.POINTER(C.c_ulong),C.POINTER(C.c_int)]
x.XFetchName.argtypes=[C.c_void_p,C.c_ulong,C.POINTER(C.c_char_p)]
wid=C.c_ulong();revert=C.c_int();name=C.c_char_p()
x.XGetInputFocus(d,C.byref(wid),C.byref(revert))
x.XQueryTree.argtypes=[C.c_void_p,C.c_ulong,C.POINTER(C.c_ulong),C.POINTER(C.c_ulong),C.POINTER(C.c_void_p),C.POINTER(C.c_uint)]
title=''
for _ in range(8):
x.XFetchName(d,wid.value,C.byref(name))
title=name.value.decode() if name.value else ''
if title: break
root=C.c_ulong();parent=C.c_ulong();children=C.c_void_p();count=C.c_uint()
if not x.XQueryTree(d,wid.value,C.byref(root),C.byref(parent),C.byref(children),C.byref(count)): break
if not parent.value or parent.value==wid.value:break
wid.value=parent.value
assert title in ('Ubuntu drag rendering probe','VDI-Ubuntu - Moonlight'), title
t.XTestFakeMotionEvent(d,-1,800,700,0);x.XSync(d,0)
time.sleep(.5)
sent=[]
try:
t.XTestFakeButtonEvent(d,1,1,0);x.XSync(d,0)
time.sleep(.8)
start=time.monotonic()
for seq in range(1,301):
time.sleep(max(0,start+(seq-1)/60-time.monotonic()))
begin=time.monotonic()
t.XTestFakeMotionEvent(d,-1,800+4*seq,700+seq,0)
x.XSync(d,0)
sent.append(dict(seq=seq,t=time.monotonic(),sync_ms=(time.monotonic()-begin)*1000))
time.sleep(1)
finally:
t.XTestFakeButtonEvent(d,1,0,0);x.XSync(d,0)
print(json.dumps(dict(title=title,events=sent)))

View File

@ -0,0 +1,41 @@
/usr/bin/kvm \
-id 102 \
-name ubuntu-test \
-no-shutdown \
-chardev 'socket,id=qmp,path=/var/run/qemu-server/102.qmp,server=on,wait=off' \
-mon 'chardev=qmp,mode=control' \
-chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \
-mon 'chardev=qmp-event,mode=control' \
-pidfile /var/run/qemu-server/102.pid \
-daemonize \
-smbios 'type=1,uuid=5a3c4a49-7354-407c-a152-d734e5db27b5' \
-smp '4,sockets=1,cores=4,maxcpus=4' \
-nodefaults \
-boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \
-display 'egl-headless,gl=core' \
-vnc 'unix:/var/run/qemu-server/102.vnc,password=on' \
-cpu host,+kvm_pv_eoi,+kvm_pv_unhalt \
-m 6144 \
-object 'iothread,id=iothread-virtioscsi0' \
-object '{"id":"throttle-drive-scsi0","limits":{},"qom-type":"throttle-group"}' \
-global 'ICH9-LPC.disable_s3=1' \
-global 'ICH9-LPC.disable_s4=1' \
-readconfig /usr/share/qemu-server/pve-q35-4.0.cfg \
-device 'vmgenid,guid=5eba3fcd-a19d-4ba6-82a5-e125824cb9cd' \
-device 'usb-tablet,id=tablet,bus=ehci.0,port=1' \
-device 'virtio-vga-gl,id=vga,bus=pcie.0,addr=0x1' \
-chardev 'socket,path=/var/run/qemu-server/102.qga,server=on,wait=off,id=qga0' \
-device 'virtio-serial,id=qga0,bus=pci.0,addr=0x8' \
-device 'virtserialport,chardev=qga0,name=org.qemu.guest_agent.0' \
-device 'virtio-serial,id=spice,bus=pci.0,addr=0x9' \
-chardev 'spicevmc,id=vdagent,name=vdagent' \
-device 'virtserialport,chardev=vdagent,name=com.redhat.spice.0' \
-spice 'tls-port=61000,addr=127.0.0.1,tls-ciphers=HIGH,seamless-migration=on' \
-iscsi 'initiator-name=iqn.1993-08.org.debian:01:54fbd9235fe9' \
-device 'ide-cd,bus=ide.1,unit=0,id=ide2' \
-device 'virtio-scsi-pci,id=virtioscsi0,bus=pci.3,addr=0x1,iothread=iothread-virtioscsi0' \
-blockdev '{"detect-zeroes":"on","discard":"ignore","driver":"throttle","file":{"cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"qcow2","file":{"aio":"io_uring","cache":{"direct":true,"no-flush":false},"detect-zeroes":"on","discard":"ignore","driver":"file","filename":"/var/lib/vz/images/102/vm-102-disk-0.qcow2","node-name":"e66a1e00ed016b86a9a870a53cf552a","read-only":false},"node-name":"f66a1e00ed016b86a9a870a53cf552a","read-only":false},"node-name":"drive-scsi0","read-only":false,"throttle-group":"throttle-drive-scsi0"}' \
-device 'scsi-hd,bus=virtioscsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \
-netdev 'type=tap,id=net0,ifname=tap102i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \
-device 'virtio-net-pci,mac=BC:24:11:36:06:DD,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,host_mtu=1500,host_tunnel=off' \
-machine 'hpet=off,type=q35+pve0'

Binary file not shown.

After

Width:  |  Height:  |  Size: 364 KiB

View File

@ -0,0 +1,82 @@
{
"size": [
2560,
1440
],
"source_levels": [
0,
8,
16,
24,
32,
64,
128,
192,
223,
235,
247,
255
],
"decoded_rgb": [
[
0,
0,
0
],
[
8,
8,
8
],
[
16,
16,
16
],
[
24,
24,
24
],
[
31,
31,
31
],
[
64,
64,
64
],
[
128,
128,
128
],
[
192,
192,
192
],
[
223,
223,
223
],
[
235,
235,
235
],
[
247,
247,
247
],
[
254,
254,
254
]
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -0,0 +1 @@
{"pid": 322221, "sent": 300, "elapsed": 6.059825101998285, "frames": [{"seq": 0, "t": 102440.821692571, "age_ms": null}, {"seq": 1, "t": 102441.021245854, "age_ms": 200.77274600043893}, {"seq": 4, "t": 102441.054319233, "age_ms": 166.33144298975822}, {"seq": 7, "t": 102441.121074412, "age_ms": 184.1263880050974}, {"seq": 11, "t": 102441.187592172, "age_ms": 211.2048270064406}, {"seq": 17, "t": 102441.288195983, "age_ms": 211.599453992676}, {"seq": 25, "t": 102441.354245034, "age_ms": 144.08069000637624}, {"seq": 27, "t": 102441.437470401, "age_ms": 194.43801099259872}, {"seq": 32, "t": 102441.521143479, "age_ms": 194.14809400041122}, {"seq": 37, "t": 102441.621274497, "age_ms": 211.3877039955696}, {"seq": 40, "t": 102441.704291322, "age_ms": 244.57279201305937}, {"seq": 47, "t": 102441.761843214, "age_ms": 185.34351799462456}, {"seq": 50, "t": 102441.821215988, "age_ms": 194.05738500063308}, {"seq": 53, "t": 102441.904253228, "age_ms": 227.5764310033992}, {"seq": 59, "t": 102442.021125681, "age_ms": 244.2382409935817}, {"seq": 64, "t": 102442.054509394, "age_ms": 194.8098800057778}, {"seq": 68, "t": 102442.137818467, "age_ms": 211.01931799785234}, {"seq": 71, "t": 102442.187866327, "age_ms": 211.35531899926718}, {"seq": 75, "t": 102442.221035664, "age_ms": 167.4995659996057}, {"seq": 77, "t": 102442.261546279, "age_ms": 173.07829500350635}, {"seq": 81, "t": 102442.354193389, "age_ms": 211.2952359893825}, {"seq": 87, "t": 102442.454272485, "age_ms": 210.66260800580494}, {"seq": 92, "t": 102442.554537373, "age_ms": 227.72313200403005}, {"seq": 98, "t": 102442.637964863, "age_ms": 211.09194299788214}, {"seq": 103, "t": 102442.721551604, "age_ms": 201.39078100328334}, {"seq": 108, "t": 102442.804406258, "age_ms": 211.46381899598055}, {"seq": 113, "t": 102442.920716956, "age_ms": 244.21081799664535}, {"seq": 119, "t": 102442.987716838, "age_ms": 210.34760100883432}, {"seq": 124, "t": 102443.070907782, "age_ms": 210.82593301252928}, {"seq": 129, "t": 102443.171088957, "age_ms": 228.2131239917362}, {"seq": 135, "t": 102443.271234258, "age_ms": 227.42562201165128}, {"seq": 140, "t": 102443.371033932, "age_ms": 244.78102099965326}, {"seq": 149, "t": 102443.454392293, "age_ms": 177.41888800810557}, {"seq": 152, "t": 102443.555200555, "age_ms": 228.273792003165}, {"seq": 158, "t": 102443.638171873, "age_ms": 211.63676999276504}, {"seq": 169, "t": 102443.760404591, "age_ms": 150.1450340001611}, {"seq": 172, "t": 102443.85525233, "age_ms": 195.65804200829007}, {"seq": 175, "t": 102443.971184144, "age_ms": 261.4585800038185}, {"seq": 188, "t": 102444.11698828, "age_ms": 178.4758849971695}, {"seq": 192, "t": 102444.237862697, "age_ms": 233.97267900872976}, {"seq": 201, "t": 102444.337947034, "age_ms": 194.98486400698312}, {"seq": 204, "t": 102444.421131266, "age_ms": 228.22857300343458}, {"seq": 210, "t": 102444.521082895, "age_ms": 228.0856559955282}, {"seq": 216, "t": 102444.621723735, "age_ms": 228.45140800927766}, {"seq": 222, "t": 102444.695372472, "age_ms": 201.36859599733725}, {"seq": 227, "t": 102444.754574322, "age_ms": 178.3318009984214}, {"seq": 230, "t": 102444.837946388, "age_ms": 211.129841991351}, {"seq": 236, "t": 102444.877757871, "age_ms": 151.2591969949426}, {"seq": 238, "t": 102445.002232629, "age_ms": 242.34762000560295}, {"seq": 244, "t": 102445.0878587, "age_ms": 227.70881200267468}, {"seq": 250, "t": 102445.171681681, "age_ms": 211.80562699737493}, {"seq": 255, "t": 102445.271119679, "age_ms": 228.1101469998248}, {"seq": 261, "t": 102445.382047928, "age_ms": 238.3739349897951}, {"seq": 267, "t": 102445.454414491, "age_ms": 210.4543309978908}, {"seq": 270, "t": 102445.494580641, "age_ms": 201.10491999366786}, {"seq": 273, "t": 102445.621240283, "age_ms": 250.1459380000597}, {"seq": 281, "t": 102445.737939762, "age_ms": 260.4216850013472}, {"seq": 287, "t": 102445.798649531, "age_ms": 209.08144999702927}, {"seq": 291, "t": 102445.855915578, "age_ms": 201.97058899793774}, {"seq": 296, "t": 102445.972795595, "age_ms": 235.7944199902704}, {"seq": 300, "t": 102446.064952103, "age_ms": 259.3057539925212}], "fresh_video_updates_per_second": 11.6, "motion_to_decoded_marker_ms": {"p50": 211.1673344988958, "p95": 259.3057539925212, "maximum": 261.4585800038185}, "frame_gap_ms": {"p50": 83.62990950263338, "p95": 126.65964200277813, "maximum": 199.5532830042066}, "last_motion_seen": 300, "release_visible": true, "method": "60Hz XTest held drag to first observed unique decoded marker; no USB/scanout"}

View File

@ -0,0 +1,30 @@
Reading package lists...
Building dependency tree...
Reading state information...
The following additional packages will be installed:
libegl-mesa0 libglvnd0 libglx-mesa0 libglx0 libwayland-client0 libxcb-glx0
libxxf86vm1
The following NEW packages will be installed:
libegl-mesa0 libegl1 libgl1 libgl1-mesa-dri libglvnd0 libglx-mesa0 libglx0
libwayland-client0 libxcb-glx0 libxxf86vm1
0 upgraded, 10 newly installed, 0 to remove and 49 not upgraded.
Inst libwayland-client0 (1.23.1-3 Debian:13.7/stable [amd64])
Inst libegl-mesa0 (25.0.7-2+deb13u1 Debian:13.7/stable [amd64])
Inst libglvnd0 (1.7.0-1+b2 Debian:13.7/stable [amd64])
Inst libxcb-glx0 (1.17.0-2+b1 Debian:13.7/stable [amd64])
Inst libxxf86vm1 (1:1.1.4-1+b4 Debian:13.7/stable [amd64])
Inst libgl1-mesa-dri (25.0.7-2+deb13u1 Debian:13.7/stable [amd64])
Inst libglx-mesa0 (25.0.7-2+deb13u1 Debian:13.7/stable [amd64])
Inst libglx0 (1.7.0-1+b2 Debian:13.7/stable [amd64])
Inst libgl1 (1.7.0-1+b2 Debian:13.7/stable [amd64])
Inst libegl1 (1.7.0-1+b2 Debian:13.7/stable [amd64])
Conf libwayland-client0 (1.23.1-3 Debian:13.7/stable [amd64])
Conf libegl-mesa0 (25.0.7-2+deb13u1 Debian:13.7/stable [amd64])
Conf libglvnd0 (1.7.0-1+b2 Debian:13.7/stable [amd64])
Conf libxcb-glx0 (1.17.0-2+b1 Debian:13.7/stable [amd64])
Conf libxxf86vm1 (1:1.1.4-1+b4 Debian:13.7/stable [amd64])
Conf libgl1-mesa-dri (25.0.7-2+deb13u1 Debian:13.7/stable [amd64])
Conf libglx-mesa0 (25.0.7-2+deb13u1 Debian:13.7/stable [amd64])
Conf libglx0 (1.7.0-1+b2 Debian:13.7/stable [amd64])
Conf libgl1 (1.7.0-1+b2 Debian:13.7/stable [amd64])
Conf libegl1 (1.7.0-1+b2 Debian:13.7/stable [amd64])

View File

@ -0,0 +1,23 @@
{
"scsi0": "local:102/vm-102-disk-0.qcow2,iothread=1,size=50G",
"balloon": 0,
"machine": "q35",
"ide2": "none,media=cdrom",
"cpu": "x86-64-v2-AES",
"scsihw": "virtio-scsi-single",
"net0": "virtio=BC:24:11:36:06:DD,bridge=vmbr0,firewall=1",
"smbios1": "uuid=5a3c4a49-7354-407c-a152-d734e5db27b5",
"bios": "seabios",
"meta": "creation-qemu=11.0.0,ctime=1792747553",
"digest": "cca4513d17be8a42e85820cd3028ec0d9ca75bb9",
"cores": 4,
"onboot": 1,
"ostype": "l26",
"sockets": 1,
"vmgenid": "5eba3fcd-a19d-4ba6-82a5-e125824cb9cd",
"numa": 0,
"boot": "order=scsi0",
"name": "ubuntu-test",
"agent": "1",
"memory": "6144"
}

View File

@ -0,0 +1,21 @@
agent: 1
balloon: 0
bios: seabios
boot: order=scsi0
cores: 4
cpu: host
ide2: none,media=cdrom
machine: q35
memory: 6144
meta: creation-qemu=11.0.0,ctime=1792747553
name: ubuntu-test
net0: virtio=BC:24:11:36:06:DD,bridge=vmbr0,firewall=1
numa: 0
onboot: 1
ostype: l26
scsi0: local:102/vm-102-disk-0.qcow2,iothread=1,size=50G
scsihw: virtio-scsi-single
smbios1: uuid=5a3c4a49-7354-407c-a152-d734e5db27b5
sockets: 1
vga: virtio-gl
vmgenid: 5eba3fcd-a19d-4ba6-82a5-e125824cb9cd

View File

@ -0,0 +1,13 @@
{
"start": {
"ticks": 851,
"uptime": 160635.04,
"hz": 100
},
"end": {
"ticks": 6159,
"uptime": 160669.07,
"hz": 100
},
"cpu_percent": 155.98001763150694
}

View File

@ -0,0 +1 @@
{"method": "synthetic F9 injection to decoded marker; includes xdotool startup/polling; excludes physical USB and panel scanout", "samples_ms": [348.530856, 284.711552, 418.432631, 517.631971, 350.308551, 359.716136, 371.757019, 336.86728, 339.483497, 331.731979, 325.803183, 299.861117, 404.714758, 315.932907, 363.985806, 285.394734, 269.009911, 267.130731, 267.48306, 300.083667, 315.059179, 254.669442, 307.362411, 261.459355], "timeouts": [], "p50_ms": 320.868045, "p95_ms": 418.432631}

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 KiB

View File

@ -0,0 +1,13 @@
{
"start": {
"ticks": 43677,
"uptime": 160314.18,
"hz": 100
},
"end": {
"ticks": 49358,
"uptime": 160349.02,
"hz": 100
},
"cpu_percent": 163.05970149255367
}

View File

@ -0,0 +1 @@
{"method": "synthetic F9 injection to decoded marker; includes xdotool startup/polling; excludes physical USB and panel scanout", "samples_ms": [344.644424, 337.765688, 309.224611, 288.914507, 300.623824, 413.339591, 276.156092, 455.880288, 397.683984, 319.561692, 441.597948, 316.018893, 380.965697, 391.304301, 316.802011, 308.706964, 423.892107, 392.97808, 311.62779, 372.379229, 374.062989, 463.189393, 400.992325, 380.511343], "timeouts": [], "p50_ms": 373.221109, "p95_ms": 455.880288}

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 KiB

View File

@ -0,0 +1,13 @@
{
"start": {
"ticks": 54663,
"uptime": 160421.94,
"hz": 100
},
"end": {
"ticks": 60508,
"uptime": 160458.13,
"hz": 100
},
"cpu_percent": 161.50870406188517
}

View File

@ -0,0 +1 @@
{"method": "synthetic F9 injection to decoded marker; includes xdotool startup/polling; excludes physical USB and panel scanout", "samples_ms": [416.662734, 438.190541, 358.204977, 362.162827, 367.07121, 438.488762, 307.76588, 390.107248, 375.053717, 488.630023, 341.718531, 378.578458, 475.09635, 444.449367, 304.375626, 378.384812, 458.503145, 335.47612, 373.547319, 386.23024, 322.255097, 906.012442, 318.026013, 304.228075], "timeouts": [], "p50_ms": 376.7192645, "p95_ms": 488.630023}

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 KiB

View File

@ -0,0 +1,13 @@
{
"start": {
"ticks": 1159,
"uptime": 160532.79,
"hz": 100
},
"end": {
"ticks": 5792,
"uptime": 160569.31,
"hz": 100
},
"cpu_percent": 126.86199342829488
}

View File

@ -0,0 +1 @@
{"method": "synthetic F9 injection to decoded marker; includes xdotool startup/polling; excludes physical USB and panel scanout", "samples_ms": [450.981038, 407.094691, 376.074366, 355.646045, 403.058306, 400.754549, 402.787732, 448.532349, 444.135376, 507.893521, 370.823885, 440.630941, 388.25405, 403.328791, 527.302213, 462.71738, 353.718619, 431.830633, 320.072327, 366.009151, 392.344769, 373.577212, 368.107089, 404.337391], "timeouts": [], "p50_ms": 402.923019, "p95_ms": 507.893521}

Binary file not shown.

After

Width:  |  Height:  |  Size: 408 KiB

View File

@ -0,0 +1,67 @@
"""Temporary GTK desktop workload; F9 toggles a decoded-video echo marker."""
import gi, time, json
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk, GLib
started = time.monotonic()
draws = 0
white = False
win = Gtk.Window(title='VDI Ubuntu quality benchmark')
area = Gtk.DrawingArea()
win.add(area)
area.set_can_focus(True)
area.set_events(Gdk.EventMask.BUTTON_PRESS_MASK)
def event(w, e):
global white
if getattr(e, 'keyval', None) == Gdk.KEY_F9:
white = not white
area.queue_draw_area(2100, 80, 300, 100)
print(json.dumps({'event': e.type.value_nick, 'keyval': getattr(e, 'keyval', None),
'button': getattr(e, 'button', None), 'x': getattr(e, 'x', None),
'y': getattr(e, 'y', None), 't': time.monotonic()}), flush=True)
return False
def draw(w, cr):
global draws
draws += 1
width, height = w.get_allocated_width(), w.get_allocated_height()
elapsed = time.monotonic() - started
cr.set_source_rgb(.96, .97, .99); cr.paint()
cr.select_font_face('sans'); cr.set_font_size(28); cr.set_source_rgb(.08, .12, .18)
cr.move_to(60, 60); cr.show_text('Ubuntu: native resolution / text / motion / input')
cr.set_font_size(20); cr.move_to(60, 100); cr.show_text(f'Native desktop: {width} x {height}')
for row, size in enumerate([12, 14, 16, 18, 20, 24]):
cr.set_font_size(size); cr.move_to(60, 155 + row * 45)
cr.show_text(f'{size}px Cloud desktop 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz')
for i in range(600):
cr.set_source_rgb(*( (0,0,0) if i % 2 else (1,1,1) ))
cr.rectangle(60+i, 445, 1, 80); cr.fill()
for i, color in enumerate([(1,0,0),(0,.65,0),(0,.2,1),(.6,0,.6)]):
cr.set_source_rgb(*color); cr.set_font_size(18); cr.move_to(60, 565+i*28)
cr.show_text('Color text 0123456789 - desktop quality test')
for i, level in enumerate([0, 8, 16, 24, 32, 64, 128, 192, 223, 235, 247, 255]):
cr.set_source_rgb(*([level/255]*3)); cr.rectangle(900+i*70, 450, 70, 80); cr.fill()
cr.set_source_rgb(*([1 if white else 0]*3)); cr.rectangle(2100,80,300,100);cr.fill()
for i in range(5):
x=70+((elapsed*220+i*173) % max(200,width-400))
cr.set_source_rgb(.1+i*.14,.35,.8-i*.1);cr.rectangle(x,height-280+i*35,120,28);cr.fill()
return False
def tick():
area.queue_draw_area(0,max(0,area.get_allocated_height()-300),area.get_allocated_width(),300)
return True
def report():
elapsed=time.monotonic()-started
print(json.dumps({'event':'source-stats','draws':draws,'seconds':elapsed,'draw_fps':draws/elapsed}),flush=True)
return True
win.connect('destroy',Gtk.main_quit)
win.connect('key-press-event',event)
area.connect('button-press-event',event)
area.connect('draw',draw)
win.fullscreen();win.show_all();area.grab_focus()
GLib.timeout_add(16,tick);GLib.timeout_add_seconds(5,report)
print('READY',flush=True)
Gtk.main()

View File

@ -0,0 +1,40 @@
"""Synthetic X11 input to decoded video; excludes physical USB and scanout."""
import ctypes, ctypes.util, subprocess, os, time, json, statistics
os.environ.update(DISPLAY=':0',XAUTHORITY='/home/armbian/.Xauthority')
x=ctypes.CDLL(ctypes.util.find_library('X11'))
x.XOpenDisplay.argtypes=[ctypes.c_char_p];x.XOpenDisplay.restype=ctypes.c_void_p
x.XDefaultRootWindow.argtypes=[ctypes.c_void_p];x.XDefaultRootWindow.restype=ctypes.c_ulong
x.XGetImage.argtypes=[ctypes.c_void_p,ctypes.c_ulong,ctypes.c_int,ctypes.c_int,ctypes.c_uint,ctypes.c_uint,ctypes.c_ulong,ctypes.c_int];x.XGetImage.restype=ctypes.c_void_p
x.XGetPixel.argtypes=[ctypes.c_void_p,ctypes.c_int,ctypes.c_int];x.XGetPixel.restype=ctypes.c_ulong
x.XDestroyImage.argtypes=[ctypes.c_void_p];x.XCloseDisplay.argtypes=[ctypes.c_void_p]
prefix='/home/armbian/vdi-build/rkmpp-experiment/build/moonlight/app/moonlight stream 192.168.1.72 '
items=[l.split(None,1) for l in subprocess.check_output(['ps','-eo','pid,args'],text=True).splitlines()[1:] if len(l.split(None,1))==2 and l.split(None,1)[1].startswith(prefix)]
assert len(items)==1,items
pid=items[0][0]
ids=subprocess.check_output(['xdotool','search','--onlyvisible','--pid',pid,'--class','Moonlight'],text=True).split();assert ids
subprocess.run(['xdotool','windowactivate','--sync',ids[-1]],check=True)
assert subprocess.check_output(['xdotool','getwindowfocus','getwindowpid'],text=True).strip()==pid
subprocess.run(['xdotool','key','F8'],check=True)
for i in range(24):
px,py=((300,850) if i%2==0 else (1800,950))
subprocess.run(['xdotool','mousemove','--sync',str(px),str(py),'click','1'],check=True)
time.sleep(.06)
d=x.XOpenDisplay(b':0');assert d;root=x.XDefaultRootWindow(d)
def pixel():
im=x.XGetImage(d,root,2250,130,1,1,0xffffffff,2);assert im
v=x.XGetPixel(im,0,0);x.XDestroyImage(im);return v&0xffffff
samples=[];errors=[]
for i in range(24):
v=pixel();assert v<0x202020 or v>0xe0e0e0,hex(v)
assert subprocess.check_output(['xdotool','getwindowfocus','getwindowpid'],text=True).strip()==pid
start=time.monotonic_ns()
subprocess.run(['xdotool','key','--clearmodifiers','--delay','0','F9'],check=True,stdout=subprocess.DEVNULL)
while time.monotonic_ns()-start<2000000000:
cur=pixel()
if (v<0x202020 and cur>0xe0e0e0) or (v>0xe0e0e0 and cur<0x202020):
samples.append((time.monotonic_ns()-start)/1e6);break
time.sleep(.002)
else:errors.append(i)
time.sleep(.12)
x.XCloseDisplay(d);vals=sorted(samples)
print(json.dumps({'method':'synthetic F9 injection to decoded marker; includes xdotool startup/polling; excludes physical USB and panel scanout','samples_ms':samples,'timeouts':errors,'p50_ms':statistics.median(vals) if vals else None,'p95_ms':vals[min(len(vals)-1,int(len(vals)*.95))] if vals else None}))

View File

@ -0,0 +1,50 @@
[
{
"label": "2k30-limited-noanim",
"p50_ms": 320.868045,
"p95_ms": 418.432631,
"timeouts": [],
"cpu_percent": 155.98001763150694,
"render_fps": 21.4,
"decode_ms": 6.84,
"queue_ms": 0.26,
"render_ms": 2.01,
"net_ms": 3.0
},
{
"label": "2k45-full-normal",
"p50_ms": 373.221109,
"p95_ms": 455.880288,
"timeouts": [],
"cpu_percent": 163.05970149255367,
"render_fps": 21.49,
"decode_ms": 10.48,
"queue_ms": 0.53,
"render_ms": 1.92,
"net_ms": 10.0
},
{
"label": "2k45-limited-normal",
"p50_ms": 376.7192645,
"p95_ms": 488.630023,
"timeouts": [],
"cpu_percent": 161.50870406188517,
"render_fps": 22.83,
"decode_ms": 6.82,
"queue_ms": 0.19,
"render_ms": 1.89,
"net_ms": 2.0
},
{
"label": "2k45-limited-thread1-noanim",
"p50_ms": 402.923019,
"p95_ms": 507.893521,
"timeouts": [],
"cpu_percent": 126.86199342829488,
"render_fps": 17.98,
"decode_ms": 8.24,
"queue_ms": 0.14,
"render_ms": 2.11,
"net_ms": 9.0
}
]

View File

@ -0,0 +1,23 @@
{
"other_desktop_cards_unchanged": true,
"ubuntu_before": {
"app": "Desktop",
"endpoint": "192.168.1.72",
"fps": 30,
"height": 1080,
"id": "desk-ubuntu-01",
"name": "Ubuntu",
"os": "Ubuntu 桌面",
"width": 1920
},
"ubuntu_after": {
"app": "Desktop",
"endpoint": "192.168.1.72",
"fps": 30,
"height": 1440,
"id": "desk-ubuntu-01",
"name": "Ubuntu",
"os": "Ubuntu 桌面",
"width": 2560
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

View File

@ -0,0 +1,9 @@
{
"warmup_clicks": 1,
"measured_clicks": 24,
"received_clicks": 24,
"alternating_coordinates_correct": true,
"max_error_px": 0.97900390625,
"F8_received": true,
"physical_latency_measured": false
}

View File

@ -0,0 +1,24 @@
<monitors version="2">
<configuration>
<layoutmode>physical</layoutmode>
<logicalmonitor>
<x>0</x>
<y>0</y>
<scale>1</scale>
<primary>yes</primary>
<monitor>
<monitorspec>
<connector>Virtual-1</connector>
<vendor>RHT</vendor>
<product>QEMU Monitor</product>
<serial>0x00000000</serial>
</monitorspec>
<mode>
<width>2560</width>
<height>1440</height>
<rate>59.950550079345703</rate>
</mode>
</monitor>
</logicalmonitor>
</configuration>
</monitors>

View File

@ -0,0 +1,11 @@
[
{
"pid": 240476,
"ppid": 235482,
"parent": "kiosk-shell",
"args": "/home/armbian/vdi-build/rkmpp-experiment/build/moonlight/app/moonlight stream 192.168.1.72 Desktop --resolution 2560x1440 --fps 30 --bitrate 30000 --display-mode fullscreen --video-codec H.264 --video-decoder hardware --absolute-mouse --capture-system-keys always --keep-awake --no-vsync --no-frame-pacing --audio-on-host",
"range": [
"0"
]
}
]

View File

@ -0,0 +1,10 @@
sunshine_name = VDI-Ubuntu
capture = x11
encoder = software
sw_preset = ultrafast
sw_tune = zerolatency
upnp = disabled
origin_web_ui_allowed = pc
hevc_mode = 1
audio_sink = vdi_audio

View File

@ -0,0 +1,18 @@
# /home/test2/.config/systemd/user/vdi-sunshine.service
[Unit]
Description=VDI Linux desktop Sunshine host
PartOf=graphical-session.target
After=graphical-session.target
[Service]
ExecStartPre=-/usr/bin/xrandr --newmode 2560x1440_60.00 241.50 2560 2608 2640 2720 1440 1443 1448 1481 +hsync -vsync
ExecStartPre=-/usr/bin/xrandr --addmode Virtual-1 2560x1440_60.00
ExecStartPre=/usr/bin/xrandr --output Virtual-1 --mode 2560x1440_60.00
ExecStartPre=/bin/sh -c 'pactl list short sinks | grep -qw vdi_audio || pactl load-module module-null-sink sink_name=vdi_audio sink_properties=device.description=VDI-Audio'
ExecStartPre=/usr/bin/pactl set-default-sink vdi_audio
ExecStart=/usr/bin/sunshine /home/test2/.config/sunshine/sunshine.conf
Restart=on-failure
RestartSec=5
[Install]
WantedBy=graphical-session.target

View File

@ -0,0 +1,33 @@
Screen 0: minimum 320 x 200, current 2560 x 1440, maximum 8192 x 8192
Virtual-1 connected primary 2560x1440+0+0 (normal left inverted right x axis y axis) 325mm x 203mm
1280x800 74.99 +
1920x1440 60.00
2560x1080 50.00
1856x1392 60.00
1792x1344 60.00
2048x1152 60.00
1920x1200 59.88
1920x1080 60.00 50.00
1600x1200 60.00
1680x1050 59.95
1400x1050 59.98
1280x1024 60.02
1440x900 59.89
1280x960 60.00
1360x768 60.02
1280x768 59.87
1024x768 60.00
800x600 60.32
640x480 60.00 59.94
2560x1440_60.00 59.95*
Type=x11
LockedHint=no
'DMZ-White'
24
false
'flat'
active
inactive
总计 0
drwxr-xr-x 2 root root 60 11月 3 13:41 by-path
crw-rw----+ 1 root video 226, 0 11月 3 13:41 card0

View File

@ -0,0 +1,188 @@
{
"source-before": [
[
0,
0,
0
],
[
8,
8,
8
],
[
16,
16,
16
],
[
24,
24,
24
],
[
32,
32,
32
],
[
64,
64,
64
],
[
128,
128,
128
],
[
192,
192,
192
],
[
223,
223,
223
],
[
235,
235,
235
],
[
247,
247,
247
],
[
255,
255,
255
]
],
"2k45-full-normal": [
[
0,
0,
1
],
[
8,
7,
8
],
[
16,
15,
17
],
[
24,
23,
24
],
[
32,
31,
33
],
[
64,
63,
64
],
[
128,
127,
129
],
[
192,
191,
192
],
[
223,
222,
224
],
[
235,
234,
235
],
[
248,
246,
248
],
[
255,
254,
255
]
],
"2k45-limited-normal": [
[
0,
0,
0
],
[
8,
8,
8
],
[
16,
16,
16
],
[
24,
24,
24
],
[
31,
31,
31
],
[
64,
64,
64
],
[
128,
128,
128
],
[
192,
192,
192
],
[
223,
223,
223
],
[
235,
235,
235
],
[
247,
247,
247
],
[
254,
254,
254
]
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

View File

@ -0,0 +1,20 @@
# Ubuntu 交互响应深度调优(2026-11-05)
本轮只改 Ubuntu VM102。保留 2560×1440、原生 Ubuntu 光标、30Mbps H.264 和 RKMPP/EGL 客户端;Windows、麒麟和 NVIDIA 直通没有改动。
现场启用了 KMS 捕获与原生独立光标的组合:Sunshine 使用 `/dev/dri/card1` 的 virtio_gpu atomic primary scanout,客户端继续通过已验证的原生光标通道同步形状、热点和位置。KMS 守护校验唯一 primary plane、`CRTC_W/CRTC_H=2560×1440`、驱动名 `virtio_gpu`,不请求 cursor hotspot plane,因此不会把第二个光标编码进视频。virtio atomic 客户端的 legacy `crtc_id/fb_id` 保持为 0,守护不再把这两个无效字段当作活动状态;真实捕获由 Sunshine 自己完成。
对比结果(60Hz XTest 注入,读解码视频中的唯一编号;不含物理 USB、网络之外的面板扫描,也不等于本地箭头延迟):
| 场景 | KMS 45FPS | X11 45FPS |
| --- | ---: | ---: |
| 长按框选回显 P50 / P95 | 195.9 / 246.6ms | 250.1 / 311.5ms |
| 视频中可见新编号更新 | 16.0/s | 10.6/s |
| 实际按钮点击回显 P50 / P95 | 约 304 / 378ms | — |
| masked 输入字符回显 P50 / P95 | 约 165 / 182ms | — |
28 次点击的编号、位置和释放均通过;7 种原生光标形状/显隐的几何和像素最大差为 0,视频背景没有混入指针。KMS 与原生光标的正常退出、空闲后重连、守护进程被强制结束后的 X11 恢复、再次重连均通过。证据在 `docs/evidence/ubuntu-deep-latency-20261105/`,包括 `drag-kms-native45.json`、`drag-x11-native45.json`、`response-kms-async.json`、`cursor-kms-native45.json` 和 `kms-lifecycle.json`。
45FPS 请求只带来有限收益;软件编码 `min_threads=4` 的回显中位数约 197ms、尾部变差,已撤回。失败的 VirGL 硬编码和异步通知实验也没有留在运行环境。最终当前会话保持 KMS + 原生光标;Sunshine 配置仍是软件编码,未宣称已达到 Windows 的约 90ms 或“零延迟”。真实业务应用的后端认证没有写入测试数据;本轮只对实际 GTK 按钮、masked entry 和合成提交做了定量,未把合成提交冒充真实登录成功。
当前剩余瓶颈是 VM102 的 X11/virtio 读回和宿主 CPU 软件编码。要进一步接近 Windows,需要可用的 Linux 硬件编码/低开销捕获路径或更高性能 GPU;不能靠继续加快本地箭头、盲目提高 FPS 或修改鼠标主题解决。

View File

@ -0,0 +1,60 @@
# Ubuntu 框选与桌面渲染调优(2026-11-05)
本轮仅处理 Ubuntu VM102。保留系统原生光标、GNOME/Xorg、2560×1440、30Mbps、limited 色彩范围和现有受限独立光标通道。用户已明确允许正常关闭启动、对比测试及必要回退;现场共正常关闭启动三次,没有强制停止虚拟机。Windows、麒麟及其独占 GPU 配置未修改。
## 最终保留
- VM102 的 CPU 从 `x86-64-v2-AES` 改为 `host`,仍为4核/6144MB。Sunshine 实际日志确认 x264 使用 AVX/FMA3/BMI2/AVX2。
- 默认 std/bochs 虚拟显卡改为 `virtio-gl`。Xorg 从 `Refusing to try glamor on llvmpipe`、DRISWRAST,变为 `glamor X acceleration enabled on virgl (Mesa Intel(R) HD Graphics 4600 (HSW GT2))`,客体出现 renderD128。
- PVE 新增 GL/EGL/Mesa 运行依赖:0升级、10新增、0移除。宿主 i915 保持原驱动;未做核显 VFIO 直通。
- 最终请求30FPS、默认 `min_threads=2`(配置中不显式覆盖)、ultrafast/zerolatency。45FPS及4线程试验未继续降低回显延迟,已撤回。
- 盒子客户端二进制、两个 Linux 原生光标 profile、Ubuntu 主题及鼠标加速策略未改。客户端 SHA256 仍为 `5d4330f703d7f8e053bc3795ca42bdaf231c9e9dd8ebb00a612013adbcccee03`。
这是共享 GPU **桌面渲染**,不是硬件视频编码。Sunshine 仍为 X11/XCB 捕获+libx264 软件编码,不能以客体出现 renderD128 宣称已启用 Quick Sync。
## 测量和结果
原始数据见 [ubuntu-drag-20261105](evidence/ubuntu-drag-20261105/)。临时 GTK 全屏窗口在长按移动时绘制框选区域和唯一编号;盒子以60Hz注入300次运动,从实际解码视频读取编号。下表的延迟是合成运动到首次观察对应编号,**不含物理USB和面板扫描,也不是本地指针延迟**。
| 配置/证据 | 新编号视频更新/秒 | 回显 P50 / P95(ms) | 最长观察间隔(ms) |
| --- | ---: | ---: | ---: |
| 原CPU+原显卡,30FPS:baseline.json | 2.0 | 398.3 / 634.6 | 1833.4 |
| host+VirGL,30FPS:accelerated30.json | 11.8 | 215.7 / 249.1 | 179.3 |
| host+VirGL,45FPS:accelerated45.json | 13.2 | 208.2 / 258.4 | 140.9 |
| 仅host+原显卡,45FPS:hostcpu45.json | 2.8 | 433.3 / 545.6 | 668.2 |
| host+VirGL,45FPS、4线程:threads4-45.json | 11.6 | 211.2 / 259.3 | 199.6 |
| 最终host+VirGL,30FPS、默认线程:final.json | 12.4 | 224.4 / 308.3 | 176.9 |
最终这轮中位回显延迟较基线降低约44%,P95降低约51%。所有有效轮次均观察到最终编号300和按钮释放。样本较短、参数组合与运行时间不同,没有做随机重复或统计显著性检验;不能将改进百分比分解归因给某个单项,也不能直接预测真实应用中的每次框选。
“新编号视频更新”不等于 Moonlight 总帧率,视频可能含重复画面;GNOME/GDK会合并运动事件,未逐一绘制300次运动不等于丢失300次输入。有效会话全程统计中,VirGL/30FPS 收流约29.25FPS、主机处理平均52.4ms;45FPS请求约30.56FPS、62.7ms;45FPS/4线程约33.46FPS、65.5ms。不同会话工作负载和时长不同,这些数据仅用于判断升帧/线程没有达到预期,不是严格单项基准。
额外对照:去掉盒子持续截图采样,原配置5秒仍只产生16条客体motion记录;VirGL下直接在客体注入,串流时67条、退出串流后159条。说明截图探针不是唯一原因,捕获/渲染竞争仍存在。GTK事件到绘制回调通常不足数毫秒,但回调结束不代表合成、GPU提交和视频编码已结束,不能据此排除渲染瓶颈。
## 回归与现有限制
最终16次唯一编号点击全部回显,另外两次快速点击使序号从16增到18;源日志18次按下/18次释放,前16次最大坐标误差1.375px,见 input-verification.json。仅代表该稳定测试会话,不宣称任意高速操作绝不丢失。
最终画质测试实际解码尺寸2560×1440;12级灰阶解码为0、8、16、24、31、64、128、192、223、235、247、254,没有新增明显截断。文字/单像素条纹截图见 quality-final.png。仍为H.264 4:2:0,未宣称像素无损。
所有临时GTK测试服务已停止,留在正常Ubuntu桌面。最终状态见 final-guest-state.txt、final-box-state.txt、desktop-final.png。盒子桌面JSON与本轮备份结构完全一致,45FPS试验已撤回;共享客户端SHA核对未变。
另在真实GNOME桌面空白区域执行长按框选,确认橙色选择框显示、松开后消失,见 real-desktop-selection.png、desktop-after-drag.png。这是功能和最终画面检查,没有将其当作真实桌面的定量时延基准。
**尚未达到接近原生或定量等同Windows的目标。** 本轮没有对Windows执行相同仪器测试,也没有测真实GNOME桌面框选的光子延迟、物理鼠标或长期运行。当前改善集中于客体渲染;X11捕获、GPU读回和CPU编码仍限制动态响应。进一步目标是验证具有可用硬件编码能力的Linux GPU路径和更低开销的捕获方式,需单独设计与验证,不能仅提高请求FPS或改鼠标速度。
首次探针实际落在锁屏界面,黑色区域误满足“编号0”条件,未纳入有效数据;立即释放按钮并解锁。探针已加固定8bit签名及按下后的finally释放。CPU-only轮第一次因串流尚未显示测试窗口而被签名检查拒绝,待就绪后复测,拒绝轮未纳入表格。
## 备份和回退
PVE首次备份 `/root/vdi-ubuntu-render-20261105/102.conf.before`;客体首次备份 `/home/test2/vdi-terminal/backups/ubuntu-render-20261105/`;盒子首次备份 `/home/armbian/vdi-terminal/backups/ubuntu-render-20261105/desktops.json`。本地保存 vm-config-before.json、vm-config-final.txt、宿主安装日志和各轮原始记录。
回退需先保存工作、退出Ubuntu串流并正常关闭VM102,只将CPU恢复 `x86-64-v2-AES`、删除新增vga字段,再启动。不要整份覆盖VM配置,避免抹去后续磁盘/网络等修改。最终Sunshine配置与原配置一致,桌面JSON也已恢复;新增图形库无需为了回退显卡而卸载。若要卸载,应先检查是否有其他使用者,不能盲目自动清理宿主依赖。
技术依据:[QEMU VirtIO GPU](https://www.qemu.org/docs/master/system/devices/virtio/virtio-gpu.html)、[Sunshine捕获/编码与线程配置](https://docs.lizardbyte.dev/projects/sunshine/latest/md_docs_2configuration.html)、[现场固定提交X11捕获实现](https://github.com/LizardByte/Sunshine/blob/63d35f702ee9e362e43263742981836ec0710384/src/platform/linux/x11grab.cpp)。实际PVE源代码的virtio-gl依赖检查和QEMU启动参数也已现场核对。
## 后续:锁屏Sunshine通知清理
用户圈出的多组Sunshine卡片实际是 `Stream Started` / `Stream Paused` 通知。GNOME对无法关联桌面应用的通知按进程分组,历次串流服务重启使分组累积。当前检查的4条通知均为Sunshine,已通过GNOME通知面板清除,复核0条可见通知;未清理其他应用的数据。
Ubuntu配置新增 `system_tray = disabled`,正常退出/从桌面列表重连后,新Sunshine进程日志确认该配置,CLIENT CONNECTED、Sunshine和guard均正常。这同时关闭Sunshine托盘图标及其状态提示,保留串流服务,不改GNOME全局通知和锁屏策略。配置首次备份 `~/vdi-terminal/backups/sunshine-notifications-20261105/sunshine.conf`;要恢复只需删除新增system_tray行,下次正常重连生效。上文“最终Sunshine配置与原配置一致”指本附加操作之前的渲染调优验收时点。

View File

@ -0,0 +1,51 @@
# Ubuntu 画质、光标样式与响应调优(2026-11-05)
Ubuntu 已从 1920×1080 升级为真实 **2560×1440** 桌面与视频,分辨率、30Mbps 请求码率和 Windows 对齐。最新用户要求保留原生样式,因此后续已恢复 Adwaita/24px、default 鼠标加速,并部署原生独立光标,见[实施记录](linux-native-cursor-20261105.md)。关闭 GNOME 动画保留。
以下保留较早的画质实验记录:当时使用 DMZ-White/flat,未部署独立光标,2K动态视频约21–23FPS。该视频数据不代表新方案的本地指针移动延迟;物理输入到屏幕延迟仍未测量,不能称已定量达到Windows。
## 生效配置与验证
- Ubuntu `.72/test2`:原 Xorg、Sunshine 2026.914.233613、X11 捕获、libx264 ultrafast/zerolatency;编码线程恢复默认,没有保留较差的单线程实验。
- `vdi-sunshine.service` 启动前创建、添加并切换 `2560x1440_60.00`,时序 `241.50 2560 2608 2640 2720 1440 1443 1448 1481 +hsync -vsync`。已实际删除自定义模式后启动服务,验证自动重建2K成功。
- GNOME `~/.config/monitors.xml` 保存单屏2K、100%缩放。初次通过 DisplayConfig 持久应用曾等待确认后回退,随后保存明确的显示配置并重新应用;最终锁屏/解锁测试仍为2K、`LockedHint=no`。未重启虚拟机或GDM,整机重启后的恢复尚未验收。
- 盒子只修改 Ubuntu 卡片为 `2560×1440 / 30FPS`,以及逐主机文件 `~/.config/vdi-terminal/host-color-range/192.168.1.72` 为 `0`。Windows、麒麟卡片结构比较保持原值,见[隔离核验](evidence/ubuntu-quality-20261105/config-isolation.json)。
- 原 RKMPP、DRM PRIME、EGL/GLES、latest-frame、无VSync/无frame-pacing 保留。正常 kiosk 连接的父进程、参数、range 环境和真实2K硬解已核对,见[最终连接](evidence/ubuntu-quality-20261105/final-stream.json)、[客户端](evidence/ubuntu-quality-20261105/final-client.log)、[服务端](evidence/ubuntu-quality-20261105/final-server.log)。最终保留 Ubuntu 普通桌面连接,临时测试窗口已停止。
最终配置快照:[服务](evidence/ubuntu-quality-20261105/final-sunshine.service)、[Sunshine](evidence/ubuntu-quality-20261105/final-sunshine.conf)、[显示配置](evidence/ubuntu-quality-20261105/final-monitors.xml)、[系统读回](evidence/ubuntu-quality-20261105/final-ubuntu-state.txt)、[桌面截图](evidence/ubuntu-quality-20261105/final-desktop.png)。
## 同场景短测
临时 GTK 窗口显示小字号文字、单像素线、彩色文字、12级灰阶和局部运动。以下均通过正常 kiosk 入口,以真实2K视频测试。每轮24次交替点击及24次F9回显;F9测量包括 xdotool 启动、网络、客体处理、编码解码和X11像素轮询,**排除物理USB输入与显示器扫描**。
| 配置 | 渲染FPS | 解码ms | 队列ms | Sunshine CPU%¹ | F9 P50/P95 ms |
| --- | ---: | ---: | ---: | ---: | ---: |
| 45FPS请求 / full / 原动画 | 21.49 | 10.48 | 0.53 | 163.1 | 373.2 / 455.9 |
| 45FPS请求 / limited / 原动画 | 22.83 | 6.82 | 0.19 | 161.5 | 376.7 / 488.6 |
| 45FPS请求 / limited / 单线程 / 无动画(撤回单线程) | 17.98 | 8.24 | 0.14 | 126.9 | 402.9 / 507.9 |
| 30FPS请求 / limited / 默认线程 / 无动画(保留) | 21.40 | 6.84 | 0.26 | 156.0 | 320.9 / 418.4 |
¹ CPU按 `/proc/<pid>/stat` 差值测量,100%为一个逻辑核。原始客户端日志、CPU样本、输入事件及回显样本按表中配置保存在[证据目录](evidence/ubuntu-quality-20261105/),数值汇总见[comparison.json](evidence/ubuntu-quality-20261105/comparison.json)。
limited 同参数仅小幅提高视频帧率,回显没有改善;30FPS最终配置的合成回显较低,但多项设置和网络条件不同,不能归因于单一参数或称为显著降低物理延迟。单线程方案较差,已恢复默认策略。官方对 [min_threads](https://docs.lizardbyte.dev/projects/sunshine/master/md_docs_2configuration.html) 的说明也要求以实际目标和硬件测试选择线程数。
测试源本身在 GNOME 软件图形环境下未达到60次/秒绘制,累计绘制约15–20次/秒;上表是 Moonlight 视频帧率,包含可能重复的源画面,不能当作独立运动帧数。输入事件复核时发现,四轮各24次快速点击分别记录到24、24、23、21次,部分出现在输入通道启动阶段,原因未完全确认;单线程轮次还出现相邻点击落在同一处,不能称快速点击完整通过。第一轮F8在源窗口获得焦点前发出,未计为接收成功。
随后在最终已稳定运行的正常会话中,重新启动独立验证窗口,预热一次点击,以40ms按下保持和250ms间隔发送24次交替点击,**24/24接收、两处坐标交替正确、最大误差不足1px,F8接收**。见[稳定会话结果](evidence/ubuntu-quality-20261105/final-input-check.json)及[事件](evidence/ubuntu-quality-20261105/final-input-source.log)。该轮不证明高速点击或物理延迟。
四轮共96个F9翻转回显样本均完成、无超时,但其中一轮客体记录了多于注入次数的F9按键事件;探针只观察黑白翻转,没有逐键序号,不能证明严格的一键一回显。因此表格中的F9数据仅供探索,不能用于证明优化降低了输入时延。
limited 灰阶中心采样约为 `0,8,16,24,31,64,128,192,223,235,247,254`,源为 `0,8,16,24,32,64,128,192,223,235,247,255`,没有把limited数据直接当full显示而造成大范围灰雾或截断。见[采样](evidence/ubuntu-quality-20261105/gray-levels.json)、[full截图](evidence/ubuntu-quality-20261105/2k45-full-normal.png)、[limited截图](evidence/ubuntu-quality-20261105/2k45-limited-normal.png)。单像素和彩色文字仍受H.264 4:2:0压缩限制,不能宣称像素无损。
## 边界、备份和回退
Ubuntu 只有QEMU虚拟VGA、`/dev/dri/card0`,没有可用GPU渲染节点,Sunshine实际使用CPU编码;动态场景还观察到GNOME合成和Xorg开销。盒子解码队列已很短,继续提升到Windows水平需要处理客体图形/编码路径;本轮没有部署独立光标协议,也没有叠加假本地箭头。
本轮未修改PVE显卡、VM硬件、Windows配置、麒麟配置或客户端二进制。测试补装小型 `python3-gi-cairo` 包用于临时绘图,没有整体系统升级。早期独立测试会话受kiosk前景覆盖、分辨率恢复和绘图依赖缺失影响,没有纳入表格;最终有效轮次使用正常入口与实际截图核对。
备份均为首次备份:
- Ubuntu `/home/test2/vdi-terminal/backups/ubuntu-quality-20261105/`:原 Sunshine配置、用户服务、四项gsettings原值;`monitors.xml.absent` 表示此前没有显示配置文件。
- 盒子 `/home/armbian/vdi-terminal/backups/ubuntu-quality-20261105/desktops.json`;Ubuntu逐主机range文件此前不存在。
回退时先退出Ubuntu串流,恢复Ubuntu服务/配置及四项gsettings,按备份存在标记恢复或移除 monitors.xml,然后 `systemctl --user daemon-reload` 并重启 `vdi-sunshine.service`。盒子仅恢复备份中的Ubuntu对象,删除 `.72` 的range文件并在无串流时刷新kiosk;不要整文件覆盖后续其他桌面的修改。原服务会将显示设回1080p。