mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-11-07 01:53:24 +09:00
[docs] (P7): CONTRACT-P7 §10.7 and §12 and the ROADMAP Ph row record the int3 follow-ups: the narrowed latch window, null-or-unit-private image units and five new debts
This commit is contained in:
@@ -145,7 +145,7 @@ verify **在 wave 3 之前**只在 monolith 臂注册(`MG_IntegrationTest/CMak
|
||||
4. `CONTRACT-P6.md` §5.2「`Session::Fail` 在 P6 保持 `[[noreturn]]`」——Ph 的翻转按 ID-P7-1 重定界,不做 98 站点的字面翻转;`Server/StagedShadow.h:115`、`Server/StagedTextureStore.h:344` 两处旁路由 wave 0 包 C 收进漏斗。
|
||||
5. `ARCHITECTURE.md` §8.5「XFB scatter 在 client」——树上取的是 server staged shadow + `OnBufferWriteback`(P5c/P5f);`OnXfbScatterReady` 是死声明,删除。
|
||||
6. **PH-4 mutable texture-level bounds (2026-09-23, F2 commits `2c6a6e25` / `51480f8c`).** A named `ResourceRespecify` carries exact per-level W/H/D alongside `(uploadTarget, level)`; on split the dimension words reuse `MGPResourceDesc.BufOffset/BufSize` only for non-buffer named image levels, and `WireFingerprint` mixes the extent-carrier revision. The applier stores the exact accepted extent, clears the transient range carrier from its descriptor copy, and passes the extent/target/fallback internal format into `StagedTextureStore.NoteLevelDefined`. The store derives its byte bound under server device limits before uploads; every `ResourceSubData` slab must match that saved extent and stay within the derived byte bound. TexBuffer and multisample targets have no legal subimage producer and staged byte records for them are named `ProtocolCorruption`. **PH-5** charges `sizeof(value_type)` for a vector count against `ReadCursor::Remaining()` before resize, using division to avoid count multiplication overflow. **PH-2** sends out-of-range and backwards-generation handle refusals through `MGPipeSessionFail` at reachable DirectGLES adoption guards; the slot table keeps the same named refusal as a backstop. Luna integration review = land; 49 targeted cases pass, including raw-peer extent, MS, slot and stale-generation controls; strict pull G1 against `adf2cbe0` is byte-identical (`.text=0xa52203`, no symbol changes). |
|
||||
7. **PH-1 (3)(4) 每会话闩(F2 latch 包,2026-09-23,ID-P7-1)——对 `CONTRACT-P5.md` R-2 与 `CONTRACT-P6.md` §5.2 的更正。** 在 **spawn / TCP 会话子进程**里(`ServerMain::RunSession` 调 `ArmSessionLatch()`,全树唯一的武装点),输入字节来自对端、且已在 `Bool` / `MobileGLResult` 函数里的站点(R-2 的诚实臂与解码边界、`PipeApplier.cpp` 七处、`ServerLoop.cpp` 四处、`SurfaceOpCodec.cpp` 三处,逐站表见 `scripts/ci/ph_latch_sites.py --table`)不再 abort:`SessionLatch` 记同一行 `Fatal{Family, "word"}`、发同一个 SessionFault 帧(只发第一个),记下**第一个**故障后返回 false;`DrainRing` 在入口与每条记录之后查闩,apply 线程离开循环,控制泵与 `ServerApplyWireSurfaceOp` 对闩后的控制帧回 `PROTOCOL_MISMATCH` 不派发,`RunSession` 的控制等待按 100 ms 切片、见闩即关会话,以 **`kSessionLatchedExitCode = 75`** 退出;supervisor 的 reap 行记 `exit=75 (latched fault)` 并计入 `sessionsFaulted`,照常服务下一连接。所以 R-2 的「Fatal{ProtocolCorruption}」在会话子进程里读作「闩 + exit 75」。**inproc 保持 Fatal**:client 与 server 同进程,闩住而存活的 server 会让同进程 client 的 GL 线程停在屏障上、没有 EOF 可醒,也没有 supervisor 去服务「下一连接」——进程就是会话;client 从不武装。未武装时 `SessionLatch` 逐字节等于 `SessionFail`,死亡测试全部保持。负控:`MG_Test/Wire/PeerLatchTest.cpp`(每站一行 raw-peer,外加批内闩与静默对端两例)与 `ServerLoopTest.cpp` 的 `ServerLoopLatchTest.*`;`ph_latch_sites.py` 的 MECHANICS 表把每一道「拒绝其余工作 / 关会话」的检查对到它的负控。
|
||||
7. **PH-1 (3)(4) 每会话闩(F2 latch 包,2026-09-23,ID-P7-1)——对 `CONTRACT-P5.md` R-2 与 `CONTRACT-P6.md` §5.2 的更正。** 在 **spawn / TCP 会话子进程**里(`ServerMain::RunSession` 调 `ArmSessionLatch()`,全树唯一的武装点),输入字节来自对端、且已在 `Bool` / `MobileGLResult` 函数里的站点(R-2 的诚实臂与解码边界、`PipeApplier.cpp` 七处、`ServerLoop.cpp` 四处、`SurfaceOpCodec.cpp` 三处,逐站表见 `scripts/ci/ph_latch_sites.py --table`)不再 abort:`SessionLatch` 记同一行 `Fatal{Family, "word"}`、发同一个 SessionFault 帧(只发第一个),记下**第一个**故障后返回 false;`DrainRing` 在每次 pop 之前查一次闩(codex closeout finding 6 把控制线程闩的窗口缩窄到「查闩到 pop」,没有关闭:落在其间的闩再放过已放行的那一条,会话在下一次检查结束),apply 线程离开循环,控制泵与 `ServerApplyWireSurfaceOp` 对闩后的控制帧回 `PROTOCOL_MISMATCH` 不派发,`RunSession` 的控制等待按 100 ms 切片、见闩即关会话,以 **`kSessionLatchedExitCode = 75`** 退出;supervisor 的 reap 行记 `exit=75 (latched fault)` 并计入 `sessionsFaulted`,照常服务下一连接。所以 R-2 的「Fatal{ProtocolCorruption}」在会话子进程里读作「闩 + exit 75」。**inproc 保持 Fatal**:client 与 server 同进程,闩住而存活的 server 会让同进程 client 的 GL 线程停在屏障上、没有 EOF 可醒,也没有 supervisor 去服务「下一连接」——进程就是会话;client 从不武装。未武装时 `SessionLatch` 逐字节等于 `SessionFail`,死亡测试全部保持。负控:`MG_Test/Wire/PeerLatchTest.cpp`(每站一行 raw-peer,外加批内闩与静默对端两例)与 `ServerLoopTest.cpp` 的 `ServerLoopLatchTest.*`;`ph_latch_sites.py` 的 MECHANICS 表把每一道「拒绝其余工作 / 关会话」的检查对到它的负控。
|
||||
|
||||
---
|
||||
|
||||
@@ -189,4 +189,9 @@ verify **在 wave 3 之前**只在 monolith 臂注册(`MG_IntegrationTest/CMak
|
||||
- `MGB_CTX` 访问 4:`PipeInputs::{GetTextureObject,HasOpenTransformFeedbackSpan,InvalidateCompileEnv}`、`GLImpl::CopyTextureImageToClientOrPBO_State`。
|
||||
- **PH-6 / fuzz 臂 3 的记录债(包 f2-event,ID-P7-2;细节 `~/w7/logs/f2-event/NOTE.md` §5)**:(1) **被丢事件所属的那条记录照常完成**:它仍贴 `kStatusOk` 回复并推进 `appliedSeq`(`ServerLoop.cpp` `DrainRing` 在该记录之后才停),而 `Client/` 里没有任何代码读 `eventDropped`(`EventRingConsumer::DroppedEvents()` 只有测试在读)——一个先发不等的 readback、事后才等其回复的 client,可能在看到 EOF 之前读到缺那次 writeback 的影子。只有不等待的 client 走得到(等待中的 client 在等待里就排空了)。修法候选是让触发 forfeit 的记录回复失败,或 client 在 `eventDropped != 0` 时闩 device-lost;两者都动 client 的等待 / 回复契约,未做。(2) **inproc 不被告知**:forfeit 停掉 apply 线程,同进程的 client 收不到任何信号。这不是「只有测试能到达」(初版 NOTE 的说法不对):(3) 的场景在 inproc 上同样可达,之后 client 的下一次等待在 120 s 后以 `Fatal{BarrierTimeout}` 死——诊断名字是错的,真因是 forfeit(审查指出,本包未测)。(3) **默认 2000 ms 未在设备上测过**:合法 client 停调 GL 超过旋钮(如 Android 退后台)且队里有一环以上未等待的事件(XFB writeback)会丢会话;此前是 30 s 后 Fatal。(4) **lockstep 臂不变**:无 `kCapRunAheadApply` 的 server(Magma)满环仍是 P5C 的 `Fatal{EventRingOverflow}`,不排空的对端让会话 SIGABRT(计入 `sessionsFaulted`,下一连接照常服务);fuzz 臂 3 没有 Magma 臂。(5) **对端不被告知原因**:没有 forfeit 的 wire 词,client 只见 EOF → device-lost;加 `Refuse` / `Fatal` 码会改 `wireFingerprint`。(6) **shm 的 `eventRingFull` 在对端可写的页上**:持续写 0 的对端让保留循环不 park 地自旋,直到旋钮耗尽后以 `TooSlow` forfeit 或会话被 Stop(有界,只记)。(7) **stream 面的阻塞 `sendmsg`**(`StreamLink.cpp:158`,apply 线程经 `StreamLink::Flush` 同步 `SendEvents`)**不是无界的**:数据套接字带 `TCP_USER_TIMEOUT=5000`(`SocketTransport.cpp:99-112`)。实测(临时探针,未入库):对端 SIGSTOP、旋钮 8000,stream 面 5327 ms 时链路被内核判死 → `ReverseChannelForfeit{PeerGone}`、exit 0;shm 面等满 8006 ms → `NotDraining`、exit 0。即 stream 面上一个冻住(活着但不 ACK)的对端约 5 s 被叫作 PeerGone,与旋钮无关;apply 线程恰好卡在 send 里时控制流又结束,`Stop()` 的 5000 ms join 与这 5 s 赛跑——未构造出,记录。(8) forfeit 后队列里剩下的记录不再应用(有意);`RunSession` 每会话每 100 ms 轮询一次控制套接字(包内原为 250 ms;与 PH-1 (3) 闩的控制切片在 p7/f2-all 合并为一个 100 ms 切片,每轮先问闩、再问 apply 线程),且每一轮都查 apply 线程(记录,不是门)。(9) 排在 PH-6 等待后面的 surface op:server 的控制线程阻塞在 apply 线程的邮箱里(P5e 的等待谓词不含控制请求,本包未改),对端活着但只是不排空时,这个 op 要等旋钮耗尽才被回答;对端死亡则由数据 bell 报告(shm 面靠 server bell 挂在控制套接字上的死亡见证,镜像 CONTRACT-P6 D5c)。(10) **server bell 的死亡见证改变了 shm 会话的正常收尾顺序**:client 的 `ShutdownSend`(`ClientSession::Stop` 第 2 步)现在可能先让 apply 线程从 park 里以 dead bell 退出、再由控制循环读到 EOF;两条路走同一个退出块,每次 shm 会话正常收尾 server 日志多一行 INFO `the peer hung up (witness fd …, revents=0x2000)`(其措辞是为 client 侧写的)。
|
||||
- **PH-7 (5) + fuzz 臂 1 + ID-P7-44(包 f2-auth,分支 `p7/f2-auth`,含 fix round)关掉的与留下的**。关掉:TCP `--serve` supervisor 在 fork 前读首帧、先验令牌(未认证对端只得 `Refuse{Authentication}`,无指纹 / stamp,无 fork);首帧期限 `MOBILEGL_IPC_PREAUTH_MS`(默认 2000);待认证连接上限 `MOBILEGL_IPC_PREAUTH_MAX`(默认 8,钳到 256),满时按地址公平让位(新连接顶掉占位最多地址的最老一条,`Refuse{Busy}` "displaced ...");失败退避 `MOBILEGL_IPC_AUTH_BACKOFF_AFTER`(默认 5,0 关)/ `MOBILEGL_IPC_AUTH_BACKOFF_MS`(默认 1000,逐次翻倍,上限 60 s,认证成功清零,10 分钟遗忘,最多跟踪 256 个地址),失败 = 错令牌、畸形首帧、超时、静默占位超过 250 ms 后关闭或被顶掉;accept 遇 EMFILE/ENFILE/ENOBUFS/ENOMEM 暂停 100 ms 而非退出 73;`RunSession` 自读首帧(单会话 TCP、unix 端点)每条出路具名,令牌先于 `ValidatePeerHandshake`;ID-P7-44 见上。无 schema 变化,`MOBILEGL_PROTOCOL_CONTROL_REVISION` 与 pin 不动;**对端可见的行为变化要设备 server 随下一个 APK 重部署**:未认证的错指纹 Hello 得 Authentication 而非 WireFingerprint;静默连接 2 s 后得 Authentication(原来是 fork + 10 s 后 exit 67 且计入 faulted);会话忙时静默的第二条连接得期限拒绝而非 Busy;满队时的让位拒绝。**留下的记录债**:(1) unix 端点仍对每个 `AcceptPair` 先 fork 再读 Hello(本地对端债,不在远端威胁模型内;只补了具名拒绝);(2) 退避按对端地址计,NAT / `adb forward` 回环后的对端共用一个键,同址合法 client 会被连坐;轮换地址(如 IPv6)只受上限、期限与按地址让位约束;(3) nonce 不符的 DataBind(child 内比较)与找不到活会话的 DataBind 不计入退避(后者可能是合法的陈旧连接),两者都不花 fork;(4) 会话建立后的畸形控制帧只以日志行结束会话(child exit 0),握手之后没有给对端的帧;(5) 四个旋钮只读环境变量,不在任何配置表或 Android service extra 里;(6) ID-P7-44 的控制依赖 Linux af_unix dgram 语义(接收端 `SHUT_RD` 后 `sendmsg` 得 EPIPE),child 崩溃时已排队的 DataBind 仍被内核丢弃;(7) 测试专用杠杆 `MOBILEGL_TEST_DELAY_SESSION_HANDSHAKE_MS`(与 `MOBILEGL_TEST_DELAY_FIRST_CAPS_MS` 同类,未设不生效)。
|
||||
- **门 5 修复(ID-P7-58)的记录债**:(1) 探针判坏的设备上 shader resolve 臂 decline(无 `VK_EXT_shader_stencil_export` 的模板面、格式不带 `SAMPLED_IMAGE | DEPTH_STENCIL_ATTACHMENT`、pipeline 失败)时回落到已知不写目标的 render-pass 臂,读回 0、无 GL 错误(POST 上是 UNFIXABLE 行,只有 `MGLOG_W_ONCE`);(2) 探针只测 4×、4×4、整幅 render area,别的采样数 / 尺寸 / 子矩形上坏的驱动看不到;(3) 非 1:1 单采样深度 blit(缩放 / 翻转 / default FB)在无 `BLIT_DST` 的深度格式上仍调 `vkCmdBlitImage`(monolith 同样);(4) 跨格式 wire 深度 blit 不走 monolith 的 `BlitDepthAcrossFormats`;(5) tcp 带不了 `MsResolveBug.` / `MsFlipBug.` / `MsResolveElide.`(server 环境旋钮,`MAGMA_SERVER_ENV_KNOB_NO_TCP` 具名);(6) 图像单元:在存储里但落在 [BASE, MAX] 之外或 mip 不完整的 level 仍按原样绑定(与 monolith 一致,门 5 以它为参照),占位按 (格式, target) 共享、每次 resolve 清零一次;(7) 切带回读在 Magma 上每带一次完整 `ReadWirePixels`(flush + 转换 + 等待),2400×1080 截图 5 带——只记性能。
|
||||
- **门 5 修复(ID-P7-58)的记录债**:(1) 探针判坏的设备上 shader resolve 臂 decline(无 `VK_EXT_shader_stencil_export` 的模板面、格式不带 `SAMPLED_IMAGE | DEPTH_STENCIL_ATTACHMENT`、pipeline 失败)时回落到已知不写目标的 render-pass 臂,读回 0、无 GL 错误(POST 上是 UNFIXABLE 行,只有 `MGLOG_W_ONCE`);(2) 探针只测 4×、4×4、整幅 render area,别的采样数 / 尺寸 / 子矩形上坏的驱动看不到;(3) 非 1:1 单采样深度 blit(缩放 / 翻转 / default FB)在无 `BLIT_DST` 的深度格式上仍调 `vkCmdBlitImage`(monolith 同样);(4) 跨格式 wire 深度 blit 不走 monolith 的 `BlitDepthAcrossFormats`;(5) tcp 带不了 `MsResolveBug.` / `MsFlipBug.` / `MsResolveElide.`(server 环境旋钮,`MAGMA_SERVER_ENV_KNOB_NO_TCP` 具名);(6) 图像单元:无效 / 空的存储单元在有 VK_EXT_robustness2 `nullDescriptor` 处绑 null 描述符(即 GL 8.26 的确切语义),否则绑该单元私有的占位(残余:同一 draw 内同一单元先存后读读到所存值;私有占位满 `kWirePrivateStoragePlaceholderCap` = 384 个后新的 (形状, 单元) 回落到按形状共享);在存储里但落在 [BASE, MAX] 之外或 mip 不完整的 level 仍按原样绑定(与 monolith 一致,门 5 以它为参照);(7) 切带回读在 Magma 上每带一次完整 `ReadWirePixels`(flush + 转换 + 等待),2400×1080 截图 5 带——只记性能。
|
||||
- **`ArmPrimGenReroute` 仍是每进程首设备裁决**:`VulkanRenderer.cpp` 的 `static const PrimitivesGeneratedNoXfbMeasurement s_measurement` 让同进程后来的设备沿用第一个设备的测量;这段编进 pull 构建,改它动 G1,只记(深度 resolve 的同形问题已按设备身份记忆,codex closeout finding 7)。
|
||||
- **回调里闩住的记录仍推进 `appliedSeq`**:`SessionRings.h` 的 `SessionConsumer::ApplyOne` 在回调返回后照常 `++m_appliedSeq` 并发布,等这条记录的 client 在 SessionFault / 会话关闭前短暂看到它已应用;只影响本会话,与上文 PH-6 债 (1) 同形。
|
||||
- **PH-5 的最小编码界只管 vector**:`ProgramArtifactsCodec.cpp` 对 vector 计数按元素最小编码字节数(`MinEncodedBytes`)对剩余字节设界,伪造计数的瞬时内存约为归档的 4×(最坏 `String` 32 / 8);map / set 解码仍按每项 1 字节计、逐项增长,4× 不是整个解码的上界。
|
||||
- **窗口 2 reducer 的已知偏差(记录,不判)**:`$BASE` 为 Fail、AFTER 变 NotSupported 的用例离开分母、抬高 rate,可抵消真正的 Pass→Fail(dsa 2 例 Pass→Fail 同时 2 例 `$BASE` Fail→NS 读 −0.003 pp 通过,没有后者是 −0.541 pp 失败);只有 `WARN <block>: NotSupported …` 行可见。
|
||||
- **Adreno 上的 robustness2 启用待下一设备窗口确认**:wire 臂现对每个非 monolith 设备启用 VK_EXT_robustness2 `nullDescriptor`,设备窗口 2 跑的 `6afa077f` 不含它;下一窗口核对 Redmi server 日志的 `Magma wire: an invalid or unbound image unit binds …` 行是哪一臂、`KHR-GL46.shader_image_load_store.incomplete_textures` 仍 Pass、门 3 不受影响。
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user