9.5 KiB
构建布局、开关与计数器(原 ARCHITECTURE §16、附 A、附 B)
设计细节。设计要点与全部章节的索引见
../ARCHITECTURE.md。章节编号沿用原ARCHITECTURE.md,代码注释里的ARCHITECTURE.md §N按编号在这里找到。
16. 构建布局
MobileGL/MG_Pipe/ 永远进构建:*.def 目录与表、MGPipe*.h payload / 句柄 / 回调、PipeApply、PipeRoute、generated/*.inc
MobileGL/MG_Impl/Pipe/ Tracker、PipeFill、SlotAllocator、CsoCache、CompositeResolver、ResourceTracker、SetHashSuppressor、*Emit.h
MobileGL/MG_Backend/MGPipe/ PipeInputs.{h,cpp}
MobileGL/MG_Remote/ 仅 MOBILEGL_BUILD_DISAGGREGATED:CONTRACT-*.md、CapsCodec、FatalFamilies.def / FatalFunnel、Handshake.h
Protocol/ protocol.fbs、generated/、SurfaceOpCodec、mg_protocol_base.h
Transport/ ITransport、SocketTransport、InProcessTransport、ILink、ShmLink、StreamLink、Ring、SessionRings、ReplySlot、EventRing、
Doorbell、ShmSegment(+Posix/Win32)、FdPassing、Framing、AuthToken、ControlInbox、LinkMetrics、WireLog
Wire/ PipeWireCodec(记录编解码、WireVerbSink)
Client/ BackendObject_Remote、ClientSession、EmitTables、WireTables、CapsMirror、PersistentMapTracker、GpuWritePending
Server/ PipeApplier、ServerLoop、ServerSession、ServerMain / ServerEntry / ServerSpawn、PreAuthGate、StagedShadow、StagedTextureStore、
SurfaceControlFrame、ServerDisplay、InProcessServer、DisplayServerJni
MOBILEGL_BUILD_DISAGGREGATED(默认 OFF)追加MG_Remote/**;OFF 时MG_Config::Transport是constexpr Monolith。MOBILEGL_BUILD_DISAGGREGATED_INPROC隐含前者并加角色隔离:两个角色靠 apply 线程与控制邮箱分开,而不是给 1494 个pGLContext->读点加 TLS。MOBILEGL_TRANSPORT = monolith | inproc | spawn是拓扑(G1 相关);控制面与数据面由 §11.9 的两个变量选。split build 不设MOBILEGL_TRANSPORT时是 monolith 对照臂。- 三个构建 flavour(P13 起):默认(单进程记录臂,不编
MG_Remote,出货形态)、verify、split;Android 两份 APK flavour(单进程 / split)。pull 构建与MOBILEGL_PIPE_PUSHCMake 选项在 P13 删除。 - 模块(P13 W7):
SOURCE_FILES按 link ratchet 的 PARTITION 拆成七个 OBJECT 库,MobileGL/MobileGL_s由它们拼成;split 构建的MobileGL_server_linkcheck只链 SERVER 与 SHARED 模块并--no-undefined,基线外的前端引用在构建时就失败(scripts/ci/server_link_check.py)。记录臂的 server 端代码在MG_Backend/Record/(RecordVerbSink、StagedShadow、StagedTextureStore),客户端 verb 发射在MG_Impl/Pipe/Verb/,不再依赖MG_Remote。 - 测试接线:ctest
ENVIRONMENT用mgl_itest_join_environment(...)构造;每条 split / spawn / tcp 条目带独立日志路径,日志按角色分文件(<base>.client.log/<base>.server.log);spawn、tcp 车道与 split 名集合一致(scripts/ci/spawn_lane_parity.py),每条目记 arm 证明。 - CI(
.github/workflows/test.yml、apk.yml):pipe-gates(G1–G8、生成器 self-test、符号报告、dirty-surface、字段归属、G5、文档引用 lint)、flatc-check、include 闭包、各 flavour 的 build / integration / retrace 车道、APK + AVD。两份 workflow 里的feat/disaggregated触发器是临时的,合入dev前移除。
附 A:开关
CMake:MOBILEGL_BUILD_DISAGGREGATED(OFF)、MOBILEGL_BUILD_DISAGGREGATED_INPROC(OFF,隐含前者)、MOBILEGL_PIPE_VERIFY(OFF,永不出货)、MOBILEGL_BUILD_SERVER_SPIKE(仅 Android spike)、MOBILEGL_FLATC_EXECUTABLE(只服务 flatc-check)。MOBILEGL_PIPE_PUSH 与 MOBILEGL_PIPE_LEGACY_MEMOS 在 P13 删除(旧缓存里的 OFF 只告警并忽略)。
运行时,MGPipe(MobileGL/Config.h、ConfigLoader.cpp):
| 变量 | 默认 | 说明 |
|---|---|---|
MOBILEGL_PIPE_PUSH |
0x3fff |
子系统位图(MG_Pipe/MGPipe.h,位永不复用);P13 起位 0–13 固定开,清任何一位都在启动时具名拒绝;只剩位 63("关 CSO 内容寻址"的行为对照)可设 |
MOBILEGL_PIPE_VERIFY / _VERIFY_FATAL / _VERIFY_CORRUPT / _POISON_OMIT |
0 / 1 / 空 / 空 | 影子比对与两个阴性对照(verify 构建才有) |
MOBILEGL_PIPE_STATS / _STATS_PERIOD / _STATS_FILE |
0 / 120 / 空 | 边界计数器(附 B);dump 按角色写 <base>.client.json / <base>.server.json |
MOBILEGL_PIPE_INDEX_MIRROR_MB |
64 | 索引镜像预算(P8);_LEGACY_MEMOS、_TEXEL_RETAIN_MB、_HANDLE_ABA_CONTROL 随各自的臂在 P13 删除 |
运行时,传输与 IPC:
| 变量 | 默认 | 说明 |
|---|---|---|
MOBILEGL_TRANSPORT |
monolith |
拓扑:monolith / inproc / spawn |
MOBILEGL_IPC_CONTROL / MOBILEGL_IPC_DATA |
fork / auto |
控制面端点与数据面(§11.9);MOBILEGL_IPC_SERVER_PATH 定位 fork 出的 server |
MOBILEGL_IPC_TOKEN / MOBILEGL_IPC_REQUIRE_SAME_BUILD |
空 / 0 | 令牌(≥16 字节;无令牌只允许 loopback);要求两端同一构建(车道纪律) |
MOBILEGL_IPC_PREAUTH_* / MOBILEGL_IPC_AUTH_BACKOFF_* |
— | server 预认证的上限与失败退避(Ph) |
MOBILEGL_IPC_CONTROL_TIMEOUT_MS / MOBILEGL_IPC_COLD_START_MS |
5000 / 20000 | 控制回复的稳态上限与冷启动预算 |
MOBILEGL_IPC_LOG_FORWARD |
远端时开 | server 日志经控制连接前送,client 写进自己的 <base>.server.log |
MOBILEGL_IPC_SURFACE |
offscreen |
server = 使用 server 自有窗口,client 无头(P12) |
MOBILEGL_IPC_RING_MB / MOBILEGL_IPC_STAGE_MB |
8 / 32 | SEG_CMD / SEG_STAGE;stage 的 1/4 是内容分块预算 |
MOBILEGL_IPC_RUN_AHEAD |
1 | P5e run-ahead;只是合取式的一半(server 须发布 kCapRunAheadApply);0 是 A/B 对照 |
MOBILEGL_IPC_VERB_BARRIER |
1 | 0 只作阴性对照,且同时关掉 run-ahead |
MOBILEGL_FRAMES_IN_FLIGHT |
3 | 1..64,两个后端共用(旧名 MOBILEGL_MAGMA_FRAMESINFLIGHT 为弃用别名):Magma 的帧上下文数;Espryt 在 present S 后等待帧 S+1-N 完成;split 的 present credit 由它导出为 max(1, N-2)(P15) |
MOBILEGL_IPC_PRESENT_CREDIT |
由 MOBILEGL_FRAMES_IN_FLIGHT 导出(默认 1) |
1..8,§14;显式设置覆盖导出值,仅供实验 |
MOBILEGL_IPC_POLL_ESCALATE |
64 | 未报告 fence 的零超时轮询本地答"未完成",同一 fence 连续第 N 次才往返(P10,CONTRACT-P10.md §1);0 = 每次轮询都往返,是 A/B 对照 |
MOBILEGL_IPC_BATCH_WAITS |
1 | lockstep 下值类记录发布即返回;verify 强制 0 |
MOBILEGL_IPC_EVENT_WAIT_MS |
2000 | 反向事件遇满环时 server 等 client 排空的整笔预算(§11.7) |
MOBILEGL_IPC_WIRE_DEFERRED_MB |
64 | Magma wire 臂延迟回收的水位线;0 是 M2 阴性对照 |
MOBILEGL_IPC_PERSISTENT_BLOCK_KB / _PERSISTENT_HASH_SUPPRESS |
64 / 1 | persistent-map 推送粒度 / 只推变化的块;0 是对照 |
MOBILEGL_IPC_ADOPT_TIER |
未设 = T0 | 未设(用户 2026-09-29 定为缺省)= 能用就 T0,不能用(stream、无 AHB、POST 失败、server 不允许)安静回退 T2:只 MGLOG_D、照样计数;0 = 点名要 T0,回退有具名行(A1 的 Refuse{AdoptTierOnStream} 等);1 = T1 已关,具名拒绝后 T2;2 = T2(P11 前的缺省)。CONTRACT-P11.md B2 |
MOBILEGL_IPC_ALLOW_ADOPT_T0 |
1 | server 自有:0 = 永不批准 T0(会话走 T2),经 ServerSpawn 保留 |
MOBILEGL_IPC_STRICT_ERRORS / MOBILEGL_IPC_AUDIT / MOBILEGL_IPC_ROLE_SPLIT_STATE |
0 / 0 / 1 | 残余输入读升级为 Fatal / 退休 staging 填 0xDD / 双块(P5f;P15 起默认开,0 关闭,阴性对照显式设 0;双块下 barriered fill 写 client 块,不再 quiesce applier) |
MOBILEGL_IPC_SPIN_US / MOBILEGL_IPC_SERVER_AFFINITY |
50 / auto |
park 前自旋预算 / apply 线程亲和(Redmi 内核忽略) |
MOBILEGL_IPC_RECOVER |
1 | session 因 device loss 结束后,应用下一次 eglCreateContext / eglCreate*Surface / eglInitialize 重新拨号得到新 session(旧 context 保持丢失,surface 在新 session 重建);0 = 丢失对整个进程永久 |
MOBILEGL_IPC_RESPAWN |
— | 具名拒绝:没有阶段实现 server 重启后的全量重推 |
显式不设立:MOBILEGL_IPC_PROGRAM(没有 relink 档)、MOBILEGL_IPC_VALIDATE_SERVER。计划中未接线:MOBILEGL_IPC_IDLE_EXIT_S(未解析)。
附 B:边界计数器(MobileGL/MG_Util/Metrics/PipeStats.h)
关闭时每站点一次全局 load + 一条永不命中的分支。字节类(stage buffer / texture / UBO / client 数组、pmap、resid、csob-blob、seg = 写进 SEG_STAGE 的字节)、调用类(draws、accessor-calls、纹理上传 emit / box / rect / jobs、csom / csob、mpr、trp、rsp、wrec、maxrec / ringwraps / ringpads / ringwaits、门铃 srv / srvpark / cli / clipark)与六个 memo 门的 hit/miss。每 MOBILEGL_PIPE_STATS_PERIOD 帧一条 MGPipe stats: 汇总行,按角色写日志。读法陷阱:accessor-calls 是静态下界,判性能只看 CPU 时间;spawn 下 client 不推进帧窗口(frames=0),窗口化字段在 spawn client 上无效,run total 仍有效(notes/p6/README.md §12.1)。站点清单(哪些路径没有接线)写在 PipeStats.cpp 头部,那份清单是契约。