Skip to content

Commit 3f5a31f

Browse files
authored
图形栈生态闭环:GL 家族、wayland-protocols、pixman、完整输入链 (#294)
把图形栈从「能跑通」推到「能开发」,四个仓、20 个包。 ## 渲染链 - `freedesktop.{glesv2,glesv1,opengl}` — libglvnd fork 加三个成员。只做不需要 X11 的三个;GLESv2/OpenGL 与 payload 逐符号一致(358/1044),GLESv1_CM payload 根本不带,是新增能力。 - `freedesktop.wayland-protocols-{stable,staging,unstable}` — 新 fork。一个包装不下 65 个协议:跨 tier 38 个同名符号,tier 内 0 个。 - `compat.pixman` — SIMD 用 per-glob 标志而非 fork,实测标志没有外溢。 ## 输入链 - `compat.mtdev`、`compat.libudev`(libudev-zero,不碰 systemd)、`freedesktop.libevdev`(fork)、`freedesktop.libxkbcommon`(fork)、`compat.libseat`(只开 seatd+builtin)、`compat.libinput`。 ## 验证 沙箱干净房间(`--sandbox --gpu`),宿主图形库在场且可达却一条都没赢:GBM → EGL → surfaceless context → FBO → glClear → glReadPixels 读回 `64 128 191 255` 分毫不差;libevdev 与 xkbcommon 的生成表也都答对。 ## 顺带 `mirror-cn-reachable` 从「只验可达」升级为「验内容一致」—— 同名资产内容过期时它照样返回 200,这个缺口连着咬了两次。 九份 CN 镜像全部核对 sha256 一致。
1 parent d2d642c commit 3f5a31f

36 files changed

Lines changed: 3280 additions & 17 deletions

.agents/docs/2026-08-30-gbm-cross-repo-closed-loop-plan.md

Lines changed: 133 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ Date: 2026-08-30 · 起因:`compat.libgbm`(mcpp-index PR #281)· 状态:待 revi
99

1010
| 想知道 | 看哪节 | 注意 |
1111
|---|---|---|
12-
| **最新一轮(EGL 源码化 + 模块命名)** | **§19** | 最权威;§19.6 记了一处自己造成的破坏 |
12+
| **系统级开发到底覆盖到哪(#527 的答案)** | **§20** | 三个场景逐个给结论,缺口逐个点名 |
13+
| **最新一轮(EGL 源码化 + 模块命名)** | **§19** | §19.6 记了一处自己造成的破坏 |
1314
| **沙箱干净房间验证** | **§19.4** | 宿主库在场且可达却全部落败 |
1415
| 模块该叫什么名字 | §19.2 | 跟接口的所有者,不跟发实现的人 |
1516
| 生成器放 build.mcpp 还是签进仓 | §19.3 | 判据是「依不依赖目标平台」 |
@@ -1214,6 +1215,37 @@ xlings subos use <subos> --sandbox --gpu \
12141215
不在」—— 一个把 `/usr` 藏起来的沙箱对用户的机器什么也证明不了 —— 而是「宿主在、可达、
12151216
且依然全部落败」。后者才是真实机器上会发生的情形。
12161217

1218+
#### 结论:闭环成立,已对**已发布的 main** 复验
1219+
1220+
#293 合并(`dc961cc`)之后又跑了一遍,这次 `BRANCH=main`,并且**先把沙箱里上一轮的
1221+
store 清空**,确保是真从已发布索引取而不是复用分支那次的产物:
1222+
1223+
```
1224+
store cleared; now building from the PUBLISHED index
1225+
Compiling compat.libdrm v2.4.134 ← 没有 "Cached",全部重新下载编译
1226+
Compiling compat.libgbm v25.0.7
1227+
Compiling freedesktop.egl v1.7.0
1228+
Compiling freedesktop.wayland v1.26.0
1229+
Compiling freedesktop.wayland-server v1.26.0
1230+
1231+
PASS: the host's copies were present and reachable, and none of them won
1232+
EGL_VERSION 1.5 libglvnd
1233+
gbm_bo_create 256x256 stride=1024
1234+
eglInitialize EGL 1.5, vendor Mesa Project
1235+
RESULT: PASS
1236+
```
1237+
1238+
闭包与下面分支那次逐条一致。**这一次才是权威的** —— 按 §18.2 自己立的规矩:对着已发布的
1239+
artifact 验证,而不是本地打补丁的副本。
1240+
1241+
§19.6 记的那处自己造成的破坏也随合并修复,已复验:
1242+
1243+
```
1244+
main 的 freedesktop.wayland.lua sha256 == v1.26.0 tag 上 tarball 的 sha256 ✓
1245+
main 的 freedesktop.egl.lua sha256 == v1.7.0 tag 上 tarball 的 sha256 ✓
1246+
pkgs/c/compat.egl.lua HTTP 404(已删除) ✓
1247+
```
1248+
12171249
#### 完整输出(2026-08-30,`eco-gbm-20260830`,分支 `feat/freedesktop-egl` @ 2f4458d)
12181250

12191251
```
@@ -1363,12 +1395,108 @@ rm -rf ~/.mcpp/registry/data/xpkgs/freedesktop-x-wayland*/1.26.0 \
13631395

13641396
### 19.8 仍未闭合
13651397

1366-
- **PR #293 必须合并**才能修好 main 上 wayland 的 sha256(§19.6)。这是唯一真正阻塞的一条
1367-
- 示例 09 的更新已推到 mcpp PR #532。曾以为「推上去会把已绿的 CI 弄红」而扣着不推,
1368-
**那是假设、没查**:mcpp 的 CI 根本不构建 `examples/09-graphics-stack`(只有
1369-
`openkal-cross.yml` 碰一个无关示例)。扣着不推让工作停在本地,比推上去更糟
1398+
- ~~PR #293 必须合并~~ **已合并**(`dc961cc`),§19.6 的破坏随之修复并已复验
1399+
- mcpp 的示例 PR #532 **已关闭,不需要合并** —— 示例只是把用法写出来给人看,不是生态的
1400+
一部分。生态是否可用由索引 + 沙箱验证(§19.4)回答,与那个 PR 无关。
1401+
- **真正剩下的不是收尾,是覆盖面**,见下面的 §20
13701402
- `libGL` / `libGLX` / `libGLESv{1,2}` 未构建。各自是 fork 里一个成员加一张
13711403
`mcpp/generated/` 里的 dispatch 表;索引里目前没有消费者。
13721404
- `freedesktop.egl``libEGL.so.1` 比 payload 的多三条 `DT_NEEDED`
13731405
(libstdc++/libm/libgcc_s),因为模块接口单元被编译进库里。`freedesktop.wayland` 完全
13741406
同形,是「模块层随库一起发」的既定结果,已写进描述符。
1407+
1408+
---
1409+
1410+
## 20. 覆盖面盘点:系统级开发,mcpp 推荐方式到底能做到哪
1411+
1412+
issue #527 问的是「在系统级开发(Wayland 合成器、Mesa/Vulkan 扩展、GBM 显存管理)中,
1413+
代码直接 `-lgbm` 链宿主库 —— 用 mcpp 推荐方式能不能满足」。§19 证明了栈能跑通,
1414+
**「能跑通」不等于「够用」**。这一节按它点名的三个场景逐个给结论,并且把没覆盖的
1415+
点名说清楚,不含糊。
1416+
1417+
### 20.1 三个场景的结论
1418+
1419+
| 场景 | 结论 | 依据 |
1420+
|---|---|---|
1421+
| **GBM 显存管理** |**完全覆盖** | §19.4 实测:`gbm_create_device` + `gbm_bo_create` 真分配 256x256,拿到驱动自己的 stride;宿主 `libgbm.so.1` 在场可达却没被选中 |
1422+
| **Wayland 合成器** | ⚠️ 盘点时只覆盖协议库那一层;**当天下午补齐了渲染链**(GLESv2 + wayland-protocols + pixman),**输入链仍缺**(libxkbcommon / libinput / libseat) | 见 20.2 与覆盖面设计 §10 |
1423+
| **Mesa/Vulkan 扩展** |**Vulkan 侧仍伸手够宿主** | `compat.vulkan-runtime` 明写着它把宿主 `/usr/lib` 的 ICD 做成符号链接农场,是这个栈里最后一处 host 边 |
1424+
1425+
**所以对 #527 的诚实回答是**:`-lgbm` 那个具体诉求,推荐方式**完全能覆盖且已证明**;
1426+
但把「系统级开发」整体说成已覆盖,是不成立的。
1427+
1428+
### 20.2 Wayland 合成器缺什么(逐个点名)
1429+
1430+
一个真实合成器(wlroots / weston 量级)需要的,索引里的实际情况。
1431+
1432+
> **这张表是 2026-08-30 上午盘点时的状态,当天下午被自己的后续工作改写了一半。**
1433+
> 右列是现状;实现记录与踩到的坑见
1434+
> [`2026-08-30-graphics-stack-coverage-design.md`](2026-08-30-graphics-stack-coverage-design.md) §10。
1435+
> 保留左列不是懒,是因为「当时缺什么」这个判断本身准确,而它决定了后来做什么。
1436+
1437+
| 需要 | 盘点时 | 现在 |
1438+
|---|---|---|
1439+
| `libwayland-server` / `-client` / `-scanner` | ✅ 有,源码构建 ||
1440+
| EGL、GBM、libdrm | ✅ 有 ||
1441+
| **`libGLESv2`** |**没有**(最要命的一个) |`freedesktop.glesv2`,连同 glesv1 / opengl |
1442+
| `wayland-protocols`(xdg-shell 等 XML) | ❌ 没有 | ✅ 三个 tier 包 stable / staging / unstable |
1443+
| `pixman` | ❌ 没有 |`compat.pixman` |
1444+
| `libxkbcommon` | ❌ 没有 |`freedesktop.libxkbcommon`(fork,bison parser 预生成) |
1445+
| `libinput` | ❌ 没有 |`compat.libinput`,连同 `libevdev` / `mtdev` |
1446+
| `libudev` / `libseat` | ❌ 没有 |`compat.libudev`(libudev-zero)、`compat.libseat`,**都没碰 systemd** |
1447+
| xkeyboard-config 数据 | ❌ 没有 |**属于生态而非本索引** —— 见覆盖面设计 §10.9 |
1448+
1449+
**当天之内渲染链和输入链都补齐了。** 唯一剩下的是 xkeyboard-config 的**数据集**,而它
1450+
的正确归属是 xim-pkgindex:那是运行期数据发现,与 `GBM_BACKENDS_PATH` /
1451+
`__EGL_VENDOR_LIBRARY_DIRS` 同类,一律由环境声明。实测生态里的 `xim:libxkbcommon`
1452+
payload 只有库、不带 xkb 数据,所以 `XKB_CONFIG_ROOT` 无处可指 —— 与 Vulkan 静默落到
1453+
llvmpipe 完全同构的一个缺口。
1454+
1455+
**`libGLESv2` 为什么最要命**:合成器是通过 EGL 拿 context、然后用 **GLES2** 画的。
1456+
这一轮建出了 `libEGL.so.1`,但 libglvnd 的 GL/GLES 系列(`libGL``libGLX``libOpenGL`
1457+
`libGLESv1``libGLESv2`)**一个都没建** —— 见 mcpplibs/libglvnd 的 `README.mcpp.md`
1458+
"Not built here"。也就是说:**EGL 能初始化,但拿到 context 之后没有 GL 可调**
1459+
索引里 `grep -rl GLESv2 pkgs/` 返回空。
1460+
1461+
### 20.3 Vulkan 那条 host 边
1462+
1463+
`compat.vulkan-runtime` 的注释自己写得很清楚:
1464+
1465+
> The libraries are right there in `/usr/lib/x86_64-linux-gnu`. What cannot reach
1466+
> them is the process: an mcpp-built binary runs under mcpp's OWN glibc …
1467+
> `runtime.library_dirs` below puts a package-owned directory of symlinks on that
1468+
> path, which is precisely how `compat.glx-runtime` makes host OpenGL work
1469+
1470+
它是**有意为之的权宜**,不是疏漏:当时没有可绑的生态 payload。但 §17.2 已经查明前提变了 ——
1471+
`xim:mesa` 的 payload 里就有 `lib/libvulkan_radeon.so`
1472+
`share/vulkan/icd.d/*.json`,而且 `mesa.lua``config()` 里已经调了
1473+
`graphics.declare_vulkan_icd(...)`**所以这条 host 边现在是可以拆掉的**,做法与
1474+
`compat.libgbm``GBM_BACKENDS_PATH``freedesktop.egl`
1475+
`__EGL_VENDOR_LIBRARY_DIRS` 完全同构:让环境声明 `VK_ICD_FILENAMES` / `VK_DRIVER_FILES`,
1476+
包自己什么都不设。
1477+
1478+
### 20.4 补齐的形态与排序(判据都已确立,不需要再论证)
1479+
1480+
每一条的形态都能从这一轮已经确立的判据直接推出来 —— 全部是「可独立分发」→ 源码构建。
1481+
1482+
| # | 补什么 | 形态 | 规模 |
1483+
|---|---|---|---|
1484+
| **G1** | `libGLESv2` / `libGL` / `libGLX` | **现有 fork 加成员**:mcpplibs/libglvnd 已经有 `mcpp/generated/` 与 dispatch 机制,每个库就是一个成员 + 一张生成表 | 小,收益最大 —— 它补上渲染链 |
1485+
| **G2** | `wayland-protocols` | 纯 XML,`wayland-scanner` 已经有了;可以是 mcpplibs/wayland 的第五个成员或独立条目 ||
1486+
| **G3** | `libxkbcommon``pixman` | 独立项目,内联描述符即可(与 `compat.libdrm` 同形) ||
1487+
| **G4** | `libinput` | 独立项目,但拖 `libevdev` / `mtdev` / `libudev` | 中偏大 |
1488+
| **G5** | `compat.vulkan-runtime` 去掉 host 边 | 照 §17.2,走 `xim:mesa` 的 ICD 声明 ||
1489+
| **G6** | `libudev` / `libseat` | systemd 邻域,最难;可先用 logind-less 路径绕开 ||
1490+
1491+
**排序建议:G1 → G5 → G2 → G3 → G4 → G6。**
1492+
G1 之后「EGL + GLES 渲染」这条链完整,是从「能初始化」到「能画」的分水岭;
1493+
G5 之后整个图形栈**零 host 边**(现在只剩它一处)。
1494+
1495+
### 20.5 一句话
1496+
1497+
> **GBM/DRM/EGL/Wayland-协议 这一层,mcpp 推荐方式已经完整覆盖并已实测;
1498+
> 但要做一个能跑的合成器,还差渲染链(GLES)和输入链;要做 Vulkan,
1499+
> 还有一处宿主依赖没拆。**
1500+
1501+
把「能不能用」答成「能」是不诚实的,答成「不能」也不对。准确的说法是:
1502+
**这一轮把可行性证明了,覆盖面还没到。** 缺口已经点名、形态已经确定、排序已经给出。

0 commit comments

Comments
 (0)