diff --git a/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md b/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md index d8a39bf9..093cef4d 100644 --- a/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md +++ b/docs/Disaggregated/CURRENT_STAGE_PROGRESS.md @@ -1,6 +1,6 @@ # 当前阶段进度 -分支 `feat/disaggregated`;代码头 `3cc4e1ec`(2026-09-18,P5e wave 2 + fix1 + ID-110;P5d 收官头 `1f8de61b`,P5c 收官头 `b88e8487`)。本文随每次落地更新。ID-1..75 的逐条裁定长文在 git 历史(`ef35ea0c` 之前版本的本文件)。 +分支 `feat/disaggregated`;代码头 `25fba0d5`(2026-09-18,P5e wave 3:strict 硬绿 + run-ahead 武装;P5d 收官头 `1f8de61b`,P5c 收官头 `b88e8487`)。本文随每次落地更新。ID-1..75 的逐条裁定长文在 git 历史(`ef35ea0c` 之前版本的本文件)。 ## 1. 阶段状态 @@ -69,6 +69,94 @@ 两臂截图为同一视角同一世界,画面正确。monolith 这一次未被 120 Hz vsync 封顶(与 P5d 的 205.8 那次同类),故**不与 inproc 直接比大小**——本轮问的是"改完还能不能正常跑",不是配对性能。inproc 的 136-140 与 ID-107 记的 140.0 / 144.9 同档,说明 fix1 触到的那行(臂选择本身,两臂都读)没有拖慢 split 臂。库版本以符号探针确认(`texture-handle-arm` 等四个字符串在 APK 的 `lib/arm64-v8a/libMobileGL.so` 内),不看游戏内的 `GIT@` 戳记——增量构建下它是旧的。 +## 2.6 P5e wave 3:strict 硬绿、run-ahead 武装(头 `25fba0d5`) + +四个包:**pa**(program 家族,逐 draw 的那次拉取)、**mv**(multi-draw 的 VAO 读点 + 五个档位的门禁条目)、 +**gl**(门禁机制本身 + 两处潜伏崩溃)、**ra2**(翻开开关后暴露的竞态)。裁定 ID-111..136。 + +### 2.6.1 strict 车道成为可被脚本判定的硬绿 + +`GetProgramForDraw@DrawArrays` 从 62 条归零(**无线上改动**:记录早就带着每次 link 的 `ProgramArchive`, +缺的是仍去问前端对象的读者),`GetProgramForDispatch@DispatchCompute` 7 → 0, +`GetBoundVertexArray@DrawArrays` 9 → 0。采纳规则最终是**三个析取项**: + +1. 该 verb 的线上 op 静态设障(ID-116); +2. 该字段的退役相不指向本阶段(ID-125); +3. 记录是**按升级**而非按静态类设障的(ID-128,XFB 活跃与客户端数组两种 draw)。 + +三条都不是预想出来的,都是被真实条目逼出来的。白名单由 `gen_pipe_field_ownership.py` **生成**而非手抄 +(ra 原本手抄的 13 行在两个方向上都错),棘轮**两侧**都会失败——新出现的对要认领,不再出现的对要删除, +否则车道会"烂绿"。合并当天棘轮就自己点名了两处:pa 退役的行不再出现,mv 的间接档位逼出了一行新的。 + +### 2.6.2 覆盖面 + +| | wave 3 前 | 现在 | +|---|---|---| +| `unit` | 2250 | **2256** | +| `integration-split` | 116 | **179**(+ 2 条 clientarrays 预期红、2 条 magma 预期红) | +| `integration-gpu` | 1294 | **1357** | +| 构建 flavour | 只有 split 编得过 | **pull / push / split 全绿**(ID-124) | + +新增的 65 条条目全部覆盖此前**一条门禁条目都没有**的臂或档位。 + +### 2.6.3 翻开开关之后:strict 硬绿是必要而**不充分**的 + +翻开两个常量后 `unit`/`gens`/`flavours` 仍全绿,而 `isplit` 掉到 112/181、`gpu` 掉到 1290/1359,**且 flaky**。 +70 条红只涉及四个字段、横跨十一个 verb——一个字段一个 verb 稳定失败是漏迁移,**四个字段散在十一个 verb 上且 +flaky 是竞态**。根因(ra2 实测,推翻了我 ID-132 的机制猜测):`gPipeInputs` 的**字段值**已由 `SuppliedFieldMask` +分区、不竞态;竞态的是**元数据标量**。而让它长期不可见的是守卫本身—— +`RefusePipeInputsTouchWhileApplierOwnsIt` 的 run-ahead 臂对任何 `isBarrieredFill` 一律豁免,依据是一句 +**关于未来**的断言("客户端马上就要 park"),而真实顺序是 fill → emit → park。修法是把那句断言**变成事实**。 +同源的第二个缺陷:`MGP_VERB_OP_LIST` 把整个 draw 家族并到一行,十九个索引 draw verb 都答"设障"、都填充、都不 park。 + +**教训(ID-132)**:strict 跑在 lockstep 下,`ApplyOne` 把每条记录都盖成 barriered,所以"只在客户端不再等待时 +才发生"的事它按构造看不见。阶段出口必须有一条**独立的、翻开开关后的**车道。 + +### 2.6.4 头 `25fba0d5` 的门(run-ahead 已武装) + +| 门 | 结果 | +|---|---| +| build | rc=0 | +| unit | **2256/2256** | +| `integration-split` | **179/179** | +| `integration-gpu` | **1357/1357** | +| `flavours` | rc=0(pull 915 TU push=absent,push 929 TU push=1) | +| 生成器 / 卫生门 | 全 rc=0 | +| 逐条普查(strict) | **179/179 绿,`Fatal{` 为零**,`Admitted{` 恰为 ID-128 的八行 | +| 预期红车道 | `integration-clientarrays-split` 2 条(`(Multi)DrawArrays+CLIENT_ARRAYS`)、`integration-magma-split` 2 条(`GetFramebufferBindingSlot@Clear`),均具名断言 | + +### 2.6.5 设备(Redmi `2f7cbe2e`,MC 26.3-rc-3,~850 draws/帧,**CPU 定频**,风扇开,30 s 窗口,交错) + +**先记一条测量纠错**:第一轮矩阵**没有定频**,monolith 自己那一臂的逐帧 CPU 在两次之间从 4.43 跳到 7.07 ms, +而那次慢的**温度更低**——是 walt governor 把 policy0 从 2745 拉到 748 MHz,不是热降频。 +`tools/device_bench/pin_device.sh` 不认识本机 serial 且**拒绝猜**(正确),故按本机节点另写了 `pin_redmi.sh`, +写序 min→底、max→目标、min→目标,并**回读 `scaling_cur_freq` 验证定频生效**。 + +定频 little 1555200 / big 1958400(每臂两次,离散度 < 2%): + +| 臂 | fps p50 | fps max | client ms/帧 | apply ms/帧 | +|---|---|---|---|---| +| monolith | 115.1 | 117.0 | 6.19 | — | +| inproc **run-ahead** | **117.6 / 117.9** | 118.3 / 118.6 | 6.71 / 6.63 | 4.30 / 4.32 | +| inproc lockstep(`RUN_AHEAD=0`,配对对照) | 111.1 / 110.7 | 114.9 / 115.1 | 8.27 / 8.09 | 6.44 / 6.41 | + +定频 little 1996800 / big 1958400(本机允许的最高,再高被厂商限幅器夹住): + +| 臂 | fps p50 | fps max | client ms/帧 | apply ms/帧 | +|---|---|---|---|---| +| monolith | 115.6 / 115.4 | 117.2 / 117.5 | 6.45 / 6.25 | — | +| inproc **run-ahead** | **117.6 / 118.0** | 118.5 / 118.6 | 6.92 / 6.87 | 4.43 / 4.35 | +| inproc lockstep | 111.6 | 113.7 | 8.16 | 6.53 | + +**配对 A/B(同一构建、同一定频,唯一差别是客户端等不等)**:client −18%、apply −33%、fps p50 +6%。 + +**结论**:两个定频档下,**monolith 与 run-ahead 都撞到 120 Hz 面板上限(max 117-118.6),只有 lockstep 撞不到** +(max 113.7-115.1)。也就是说在这台设备的真实负载里,**inproc 现在与 monolith 齐平**,而阶段开始时是 0.62-0.74 倍。 +逐帧 client CPU 上 run-ahead 比 monolith 多约 8%(6.9 vs 6.3),两者都在上限之下留有余量。 + +**尚未回答的**:面板上限之上谁更快。本机定不住更高的频率,而未定频的一次高频窗口里 monolith p50 201 / run-ahead +p50 181(约 1.10 倍)——那一次不可配对,只能作为方向性提示。要回答它需要关掉 vsync 或换一台上限更高的设备。 + ## 3. P5c 落地内容 | 包 | 内容 | 效果 | diff --git a/docs/Disaggregated/MEASUREMENTS.md b/docs/Disaggregated/MEASUREMENTS.md index 04d087a5..fdfbeac9 100644 --- a/docs/Disaggregated/MEASUREMENTS.md +++ b/docs/Disaggregated/MEASUREMENTS.md @@ -508,3 +508,56 @@ monolith 这一次未被 120 Hz vsync 封顶(与 §9 的 205.8 那次同类) - 派给外部 CLI 的任务,其进程会活过 harness 的完成通知;**派出后不得自己再跑同一件事**,否则两套实验同时对一台手机 force-stop / 清 logcat,得出假失败。 - 不得在脚本正被 bash 执行时修改它(边读边执行);要改先冻结副本。 - 游戏内 F3 的 `GIT@` 戳记在增量构建下是旧的,**判断库版本要看 APK 里 `.so` 的符号 / 字符串**,不看戳记。 + +## 11. P5e wave 3 — run-ahead 武装后的设备矩阵(头 `25fba0d5`) + +Redmi `2f7cbe2e`,FCL fordebug + Minecraft 26.3-rc-3 世界 `test`,VD12,DirectGLES,~850 draws/帧。 +**CPU 定频**(见下),GPU 钉 pwrlevel 0 且每臂重新断言,风扇开,进世界后 20 s 稳定再取 30 s 窗口,臂交错。 + +### 定频,以及为什么这一节必须先讲它 + +第一轮矩阵没有定频,于是 **monolith 自己那一臂**的逐帧 CPU 在两次运行之间从 4.43 ms 跳到 7.07 ms, +而慢的那次**温度更低**(53.5 °C vs 58.9 °C)——不是热降频,是 walt governor 把 policy0 从 2745 MHz +拉到 748 MHz。未定频的逐线程 CPU ms/帧**不能跨臂比较**,那一轮矩阵作废。 + +`tools/device_bench/pin_device.sh` 不认识本机 serial,并**明确拒绝猜**("pin path 因 SoC 而异,猜错会静默失败")—— +这是对的,也正是它没有静默半应用的原因。按本机实测节点另写 `pin_redmi.sh`:写序 min→硬件底、max→目标、 +min→目标(顺序要紧,否则按 stock 相对目标的位置会半应用),并**回读 `scaling_cur_freq` 确认**,跑完再 check 一次。 + +### 结果(每臂两次,离散度 < 2%) + +定频 little 1555200 / big 1958400: + +| 臂 | fps p50 | fps max | client ms/帧 | apply ms/帧 | +|---|---|---|---|---| +| monolith | 115.1 | 117.0 | 6.19 | — | +| inproc run-ahead | 117.6 / 117.9 | 118.3 / 118.6 | 6.71 / 6.63 | 4.30 / 4.32 | +| inproc lockstep (`MOBILEGL_IPC_RUN_AHEAD=0`) | 111.1 / 110.7 | 114.9 / 115.1 | 8.27 / 8.09 | 6.44 / 6.41 | + +定频 little 1996800 / big 1958400(更高会被厂商限幅器夹住): + +| 臂 | fps p50 | fps max | client ms/帧 | apply ms/帧 | +|---|---|---|---|---| +| monolith | 115.6 / 115.4 | 117.2 / 117.5 | 6.45 / 6.25 | — | +| inproc run-ahead | 117.6 / 118.0 | 118.5 / 118.6 | 6.92 / 6.87 | 4.43 / 4.35 | +| inproc lockstep | 111.6 | 113.7 | 8.16 | 6.53 | + +### 读法 + +- **配对 A/B**:`MOBILEGL_IPC_RUN_AHEAD=0` 与默认是同一构建、同一份记录、同一定频,唯一差别是客户端等不等 + (ID-114:**不得**用 `VERB_BARRIER=0`,它是 `RunAheadArmed()` 的第一个合取项,会顺手关掉 run-ahead, + 而且实测几秒内即 `Fatal{UnmigratedPipeInput, "IsCapabilityEnabled@ClientWaitSync"}`)。 + 差值:client **−18%**、apply **−33%**、fps p50 **+6%**。 +- **两个定频档下 monolith 与 run-ahead 都撞到 120 Hz 面板上限**(max 117-118.6),**只有 lockstep 撞不到** + (max 113.7-115.1)。所以"inproc 是否追平 monolith"在本机真实负载上的答案是**追平了**;阶段开始时是 + **0.62-0.74 倍**(见 §10)。 +- 逐帧 client CPU:run-ahead 6.9 / monolith 6.3,多约 **8%**,两者都在上限之下有余量。 +- **未回答**:面板上限之上谁更快。本机定不住更高频率;一次未定频的高频窗口给出 monolith p50 201 / + run-ahead p50 181(约 1.10 倍),但那次不可配对,只作方向性提示。需要关 vsync 或换上限更高的设备。 + +### 侧写(`25fba0d5` 之前,`7c6f6886`,说明 run-ahead 为什么值得做) + +symbolized `simpleperf cpu-cycles`,客户端 GL 线程:`SessionProducer::WaitForAppliedOrEventBacklog` +**31.58% 自身时间**,其后第二名只有 3.72%。设备计数器同期显示客户端每帧进入 doorbell 等待约 **916 次** +(对 ~849 次 draw),其中 99.8% 靠自旋解决——`MOBILEGL_IPC_SPIN_US=0` 让每次等待都 park,帧率塌到 20.9。 +所以代价是**会合本身**,不是自旋参数,这也是为什么修法是"不再每次 draw 会合"而不是"把每次会合做便宜"。 diff --git a/docs/Disaggregated/ROADMAP.md b/docs/Disaggregated/ROADMAP.md index 3a7affca..e3447a04 100644 --- a/docs/Disaggregated/ROADMAP.md +++ b/docs/Disaggregated/ROADMAP.md @@ -1,6 +1,6 @@ # MGPipe 路线图 -> 状态:**P0、P0.5、P1、P2、P3a、P4a、P5、P5b、P5c、P5d 已收官**(P5c:2026-09-17,代码头 `b88e8487`;P5d:三轮,2026-09-18,代码头 `1f8de61b`)。当前头、逐门数字、开放项与下一步见 **[`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md)**;设计见 `ARCHITECTURE.md`;逐阶段实测见 `MEASUREMENTS.md`;P5d 报告见 [`P5D-INPROC-PERFORMANCE.md`](P5D-INPROC-PERFORMANCE.md)。**当前在 P5e**(退役 Espryt draw path 的 lockstep,契约 `MobileGL/MG_Remote/CONTRACT-P5E.md`;八包已全部落地合并,头 `3cc4e1ec`,逐门数字与设备验证见 `CURRENT_STAGE_PROGRESS.md` §2.5);之后才是 P6 spawn transport(此时只是传输替换)。 +> 状态:**P0、P0.5、P1、P2、P3a、P4a、P5、P5b、P5c、P5d 已收官**(P5c:2026-09-17,代码头 `b88e8487`;P5d:三轮,2026-09-18,代码头 `1f8de61b`)。当前头、逐门数字、开放项与下一步见 **[`CURRENT_STAGE_PROGRESS.md`](CURRENT_STAGE_PROGRESS.md)**;设计见 `ARCHITECTURE.md`;逐阶段实测见 `MEASUREMENTS.md`;P5d 报告见 [`P5D-INPROC-PERFORMANCE.md`](P5D-INPROC-PERFORMANCE.md)。**当前在 P5e**(退役 Espryt draw path 的 lockstep,契约 `MobileGL/MG_Remote/CONTRACT-P5E.md`;十二包已全部落地合并,**run-ahead 已武装**,头 `25fba0d5`;strict 车道硬绿 179/179、`integration-gpu` 1357/1357、三个构建 flavour 全绿;设备上 inproc 已与 monolith 齐平,见 `CURRENT_STAGE_PROGRESS.md` §2.6 与 `MEASUREMENTS.md` §11);之后才是 P6 spawn transport(此时只是传输替换)。 ## 通用纪律(每个 commit) @@ -28,7 +28,7 @@ | **P5b** `inproc` verb migration | ✅ `37fc4fdb..82683d4a` | class-C 普查决定顺序;d1 19 / i1 7 / t2 6 / f1 11 槽迁移;sync 五槽;具名 blit;GLES mip descriptor;r1 / r2;收官审查三项修复。发射表 A=2 / B=54 / C=15 | 主机全门 `348d22a4` complete;`integration-split` 107/107;合并普查零回退、79 trace 72/6/1;**Redmi 正确性 8/8 + 四臂 A/B、barrier tax 首测**。§7 | | **P5c** `inproc` 共享内存读点归零 | ✅ `11ac3de6..b88e8487` | server 端纹理 staged shadow(`StagedTextureStore`,句柄为键、整段覆盖、defined-ness 追踪);`SEG_EVENT` 三个 producer + `kEventGlError`(反向通道零裸指针);sink / twin 按记录句柄解析(blit 具名臂经 verb 句柄工作区,Magma 走 G6 消费臂);`applier_reset` / `object_death` 控制记录(opcode 77/78,framebuffer 首个 wire delete);`set_context_values`(79)退役全部值类 BARRIER-PULLED 行,三 shutter 自答;双层 `Fatal{RoleViolation}` 守卫 + `InBarrierWait` 接线;两个具名豁免 scope(通告家族 P4b/P7、G6 registry 家族 P3b/P4b)承接未到期的债 | 角色守卫开启下 unit 2187/2187(strict 下同绿)、`integration-split` 111/111、每层守卫 red-once 按名变红;纹理 `0xDD` audit 在 bsl / complementary 两条 in-world trace 零 Fatal;rsp 按帧实测(bsl 948.5/帧,残留全为钉住的对象类 15 行);G1 三个认定 resize(SwapchainObject::Create / CopyTexSubImage2D / ScopedRestartIndexSubstitution,均已具名)+ `.text` −16 B、pull 构建零 MG_Remote 符号;G5 保护区字节一致;双生成器 --check/--self-test 绿 | P5b | | **P5d** `inproc` 性能专项 | ✅ `cb06538c`、`56a77348`、`1f8de61b` | 一二轮:persistent-map 推送三级臂(mprotect 脏页追踪 + 哈希抑制 + 绑定过滤 `PushDrawConsumers`)、barrier 批处理 `MOBILEGL_IPC_BATCH_WAITS` + 延期销毁队列、自旋时钟 64 合 1、零页注册 + shadow 页对齐分配。三轮(按符号化 profile 逐项切,四包 + 一份 lockstep 可行性研究):apply 空转轮询零锁(控制邮箱原子影子位)、`Doorbell::Wait` 校准自旋稳态不读时钟、wait/park 计数进 stats;`OnApplyThread()` 内联为线程指针比较、三个 scope 深度计数器退掉 `thread_local`;shadow 分配尺寸补页、追踪范围向外对齐、边块哈希消失、脏页排空修复;image unit 高水位、残余填充 memo、server stamp 常量表;`generate_mipmap` 不再免等(apply 读残余输入)、death 测试围栏 | 三轮设备(Redmi,CPU 定频):inproc **64.3 → 103-106 fps**(p50),client 线程 CPU 15.0 → 9.2 ms/帧、apply 12.4 → 7.0-7.4;monolith 同场景 115(120 Hz vsync 封顶的运行)/ 206(一次未封顶,渲染线程 5.0 ms/帧 大核);配对比较以逐线程 CPU/帧为主,见报告"数字"节;unit 2203/2203、`integration-split` 111/111(两条曾 flaky 的用例复跑 6/6);双生成器、include 闭包、dirty-surface、doc 引用绿。未完成:R-1 序列化(研究结论:留给 P3b/P4b 后的 P11 `gPipeInputs` 版本化)、线程放置(内核忽略亲和)、`SetHashSuppressor` 哈希等小项。报告:[`P5D-INPROC-PERFORMANCE.md`](P5D-INPROC-PERFORMANCE.md) | P5b | -| **P5e** 退役 Espryt draw path 的 lockstep | 🚧 进行中(八包全落地,头 `3cc4e1ec`) | 契约 `MG_Remote/CONTRACT-P5E.md`(规则 F:未设障记录的 apply 不得读任何 client 内存;19 条裁定见 §9)。八包:**c0e** 契约 + 线上行(`PipeCalls.def` 第五列 `WaitClass` + `MGPipeWaitClassFor`、`set_program_bindings` opcode 80 空路由、`kCapRunAheadApply` 位 10、`kDrawClientArrays`、子系统位 13、`MGPipeImageAccess` 一张表、两个旋钮、跨包 seam 声明)→ **id** 身份(registry 按 `{slot, gen}` 重键、by-handle resolver、分配器守卫)→ **vi / sb / pg / tx2 / fb** 五个 per-draw 家族并行(VAO / 缓冲绑定点 / program 归档 + 绑定 / 纹理 + sampler 窗口 / FBO + image)∥ **ra** 传输机制(等待规则 `EmitAndWaitTails`、present credit、`gPipeInputs` 变 server 角色内存、事件环流控)。集成 commit 翻 `kMGPipeP5eRunAheadReady` | 集成门(§3):unit 两臂绿;`integration-split` 111+ 绿 + inproc 普查零回退 + 79 trace 无新首阻塞;`integration-split-strict` 转**硬绿车道**(只允许 §7 白名单的 `[BARRIER-PULLED]` 标记,未设障记录 `rsp` = 0);三条阴性对照(`MOBILEGL_IPC_RUN_AHEAD=0` SSIM 一致、`VERB_BARRIER=0` 在设障行变红、Magma 上 `RUN_AHEAD=1` 记一条日志后跑 lockstep);每包 red-once 在集成树复跑;G1 0/0/0/0、G2、G14、G5;monolith push 四条 A/B trace SSIM 不变。设备出口(§4,Redmi 30 s 在世界窗口,四臂):fps ≥ lockstep、client 线程 CPU ms/帧 < lockstep、SSIM 不变,且逐 op 等待清单里**没有 `kWaitApplied` 行、没有逐 draw 的 reply 行** | P5d | +| **P5e** 退役 Espryt draw path 的 lockstep | 🚧 进行中(十二包全落地,**run-ahead 已武装**,头 `25fba0d5`) | 契约 `MG_Remote/CONTRACT-P5E.md`(规则 F:未设障记录的 apply 不得读任何 client 内存;19 条裁定见 §9)。八包:**c0e** 契约 + 线上行(`PipeCalls.def` 第五列 `WaitClass` + `MGPipeWaitClassFor`、`set_program_bindings` opcode 80 空路由、`kCapRunAheadApply` 位 10、`kDrawClientArrays`、子系统位 13、`MGPipeImageAccess` 一张表、两个旋钮、跨包 seam 声明)→ **id** 身份(registry 按 `{slot, gen}` 重键、by-handle resolver、分配器守卫)→ **vi / sb / pg / tx2 / fb** 五个 per-draw 家族并行(VAO / 缓冲绑定点 / program 归档 + 绑定 / 纹理 + sampler 窗口 / FBO + image)∥ **ra** 传输机制(等待规则 `EmitAndWaitTails`、present credit、`gPipeInputs` 变 server 角色内存、事件环流控)。集成 commit 翻 `kMGPipeP5eRunAheadReady` | 集成门(§3):unit 两臂绿;`integration-split` 111+ 绿 + inproc 普查零回退 + 79 trace 无新首阻塞;`integration-split-strict` 转**硬绿车道**(只允许 §7 白名单的 `[BARRIER-PULLED]` 标记,未设障记录 `rsp` = 0);三条阴性对照(`MOBILEGL_IPC_RUN_AHEAD=0` SSIM 一致、`VERB_BARRIER=0` 在设障行变红、Magma 上 `RUN_AHEAD=1` 记一条日志后跑 lockstep);每包 red-once 在集成树复跑;G1 0/0/0/0、G2、G14、G5;monolith push 四条 A/B trace SSIM 不变。设备出口(§4,Redmi 30 s 在世界窗口,四臂):fps ≥ lockstep、client 线程 CPU ms/帧 < lockstep、SSIM 不变,且逐 op 等待清单里**没有 `kWaitApplied` 行、没有逐 draw 的 reply 行** | P5d | | **P6** spawn transport | P5e 之后 | `SocketTransport`(socketpair + fork/execve,envp 剔除 + 强制 monolith 双保险);`ServerMain`;`MOBILEGL_IPC_SERVER_PATH` + `dladdr` 兜底;有界重试握手;EOF 即时退出;device-lost latch;EGL forwarder 的控制面帧;P5c 留下的 `s_synced` / `g_syncedRenderStateParameters` 按 context 世代重置 | P5b 的完整渲染路径在 `spawn` 下绿;进程树只多一个子进程;`HeadlessGL` fork 预检无孤儿;OpenRA 在 Adreno 830 上 split SSIM ≥ 0.99 | | **P3b / P4b** 深化(Espryt) | 待排 | 按存储属主键控的发射游标与 view 索引重映射;`g_fboTextureSyncList`;`ResolvedTextureBindingMemo` / `SamplerPassMemo` / image sweep / program registry 重键;XFB scatter 搬到 client;删 fragColor 重推导 workaround 与 `g_broadcastMemo*`;raw-depth-fetch sampler 原生化;回读 / pack state;P4a 记下的 R-3 / R-4 / R-5 / R-7 / R-10 / R-11;`ProgramArtifacts.h` 的 NDK 尺寸钉 | 纹理 / program 场景;CTS `texture_*` / `shader_image_*` / `packed_pixels` 在 0.5 pp 内;每一个 Iris trace;`TextureUploadShapeScenario` 升级成门 | | **P7** DirectVulkan(Magma)全量迁移 | 待排 | 其余 10 个子系统:`SetupDrawSnapshot` 探测字段塌成 dirty mask;占位纹理原生化;具名 UBO host payload(D-B8);内部 shader 烘焙;`VertexInputStateFactory` 内容寻址 CSO;D18 容器纪律保留 | 集成 + trace 在 Magma 的 push 与 split 下全绿;verify 零分歧;`nm -D libMobileGLServer.so \| grep glslang` 为空;CTS 0.5 pp 内。**再基线检查点:中点完成子系统 < 40% 立即重定基线** |