Files
Unlucky-Launcher/docs/backend-cjk-evidence-matrix.md
T
AskaEth 414f6ff886 feat(m187): 启动失败弹窗 + 诊断包导出,并接通 DialogQueue
用户实测「MC 启动失败找不到崩溃日志」的直接修法:失败时弹一个框,把退出码、
一句人话原因、证据形态、四条真实路径与三个按钮摆在同一个地方。

- app-iced:最小一层模态(遮罩 + 卡片 + 主/次按钮 + Esc/点遮罩关闭),
  消费 presenter 的 DialogQueue(此前全仓零引用,所有弹窗都画不出来);
  队列管弹窗,CrashCard 管这次失败的事实,按 DialogId 绑定。
- 弹窗区分两种失败:游戏自己写了 crash-reports(贴 Description + 栈片段)/
  游戏没来得及写(明说「这次没有生成崩溃报告」并贴出捕获的最后 30 行)/
  什么都没抓到(给最可能原因分类)。绝不对第二种说「找不到日志」。
- 导出诊断包:core 侧新 crash_bundle 写 zip(清单 + 启动器日志 + 会话 JSONL +
  crash-reports/* + hs_err + latest.log + 版本 JSON),落盘即脱敏(家目录 / token /
  会话 id),单文件 4 MiB、总量 48 MiB 上限并在清单记截断。
- 启动器自身日志落盘(core::launch::launcher_log → <.ULL>/logs/launcher.log,
  登记目录前先缓冲),补上「双击启动时诊断行直接蒸发」的缺口。
- i18n:25 条中英文案进 catalog/logs.rs + 金表。
- 取证:ULL_DIALOG_FIXTURE=crash-report|no-logs|export 在临时目录造真文件出图,
  wgpu 与 tiny-skia 各一套,见 DevDocs/artifacts/m187/。

未复现 M190 的「owned 文字在 wgpu 下丢字」:同一串中文两条文字路径、两种后端逐字相同
(ab-wgpu.png / ab-tinyskia.png),因此本轮未改任何渲染路径。
2026-11-08 22:42:00 +08:00

5.0 KiB
Raw Blame History

后端 × 中文:什么断言只在软渲染下成立,什么必须在 GPU 下看(M187)

本文件登记一条通道级缺口,不是一条 bug:自动化证据全部走软件渲染,所以「只有 GPU 后端 才出现」的缺陷在 CI 里永远是盲区。下次有人要验「文字/像素在 GPU 上是否正常」时,先读这一页。

1. 现状:所有自动出图都是 --software-renderer

通道 位置 后端
CI 冒烟截屏 .github/workflows/ci.yml:101 --software-renderer(强制 CPU)
CI 交互冒烟 .github/workflows/ci.yml:246、:283 --software-renderer
Linux 容器冒烟 packaging/linux-smoke-docker.sh:90 --software-renderer
D30 视觉验收(人工,按协议出图) DevDocs/PlanDoc/(视觉验收协议) 同上(CI 同款命令)

--renderer=auto(默认)会挑 wgpu;--software-renderer 强制 tiny-skia。CI 走后者是有意的: 容器/无 GPU 机器上没有 Vulkan/DX12 设备,硬要 wgpu 会红在一句「adapter 创建失败」上,与皮肤无关。

代价:tiny-skia 与 wgpu 是两套完全不同的文字光栅化路径(前者 cosmic-text + CPU 位图上传, 后者经 cryoglyph 上传到 GPU 字形图集)。所以「GPU 侧字形图集出错」这类缺陷,任何自动证据都抓不到。

2. 这轮实测:M190 的「owned 文字在 wgpu 下丢字」在本 branch 上没有复现

同一份构建、同一串中文、同一字号,一次 wgpu 一次 tiny-skia:

图 后端 内容
DevDocs/artifacts/m187/ab-wgpu.png wgpu(Vulkan,AMD RX 6600 XT) 四行:text_role_owned / text_role × 大字号 / 正文字号,逐字相同
DevDocs/artifacts/m187/ab-tinyskia.png tiny-skia(--software-renderer) 同上,与 wgpu 那张逐字一致
DevDocs/artifacts/m187/probe-acc-wgpu.png wgpu 账户页设备码面板(M190 钉的那一行「剩 14:59」在 wgpu 下正常画出)

结论(只对这份构建、这台机器成立,不推广):frame::text_role_owned 与 frame::text_role 产出的控件在小规模中文下行为一致,两种后端都能画;把缺陷归因到「owned 路径」在本 branch 上没有证据支撑。要复现 M190 的现象,需要它当时的构建/环境。

3. 分工:哪些结论只信软渲染,哪些必须在 GPU 上看

断言类型 软渲染(tiny-skia)够吗 必须在 GPU 下复核 理由
版面几何(位置、宽高、折行、间距) ✅ 够 建议一次 几何由布局树决定,两后端共用
文字在不在(整行缺失 / 空块) ⚠️ 只能证明 CPU 路径 必须 GPU 字形图集是独立实现(cryoglyph)
字形形状 / 连字 / 每字形字体落点(「个别字换了字体」) ⚠️ 同上 必须 两种后备字体选择可能不同
颜色 / 对比度 / 主题令牌 ✅ 够(纯色由令牌给) 建议一次 面板混合色只有 GPU 路径可验
材质层 / 高程阴影 ⚠️ 必须 阴影在 wgpu 与 tiny-skia 是两套画法
整窗 α / 无边框圆角(Win32) ❌ 不看 必须(且只在 Windows) 与渲染后端无关,靠 DWM 下发
背景图 / 壁纸取色 / 图片缩放 ⚠️ 必须 GPU 侧走纹理采样
SVG 图标(含描边宽度) ✅ 够 建议一次 光栅化后端不同

读法:「有没有画出来」与「字形对不对」这两类,只认 GPU 图;几何与令牌只认一份即可。

4. 怎么在 GPU 下出图(本机命令)

# GPU(wgpu;会自动挑适配器,日志里 [gpu] Selected: AdapterInfo{…} 是「真用上 GPU」的实证)
unlucky-launcher-iced --screenshot out-gpu.png --screenshot-theme=light

# CPU(tiny-skia)
unlucky-launcher-iced --screenshot out-cpu.png --screenshot-theme=light --software-renderer

# 两图逐像素比对(本程序自带,不需要 Python/PIL)
unlucky-launcher-iced --diff out-gpu.png out-cpu.png

--diff 的退出码:0 一致 / 1 有差异 / 2 参数错。几何应当一致(D30 的硬项), 颜色与字形抗锯齿允许不同——所以「有差异」不等于坏,要看着图判。

启动失败弹窗的两态各两张(wgpu / tiny-skia)就是这么出的:

ULL_DIALOG_FIXTURE=crash-report unlucky-launcher-iced --screenshot dialog-crash-wgpu.png
ULL_DIALOG_FIXTURE=no-logs      unlucky-launcher-iced --screenshot dialog-no-logs-wgpu.png

5. 机器条件(写下来,免得下次怀疑「没 GPU」)

本机 --renderer=auto 的实测选择:AMD Radeon RX 6600 XT / Vulkan / device_type: DiscreteGpu。 无独显的机器上 wgpu 会落到 Microsoft Basic Render Driver(CPU 实现,device_type: Cpu)—— 那种图不能算 GPU 证据(它仍是 CPU 光栅化,只是走了 DX12 接口)。 判据:看 [gpu] Selected: 那行的 device_type,Cpu 一律不算。