Files
MobileGL/docs/Disaggregated/design/05-backend-and-server.md
T

5.0 KiB
Raw Blame History

后端改造与 server 侧(原 ARCHITECTURE §9–§10)

设计细节。设计要点与全部章节的索引见 ../ARCHITECTURE.md。章节编号沿用原 ARCHITECTURE.md,代码注释里的 ARCHITECTURE.md §N 按编号在这里找到。

9. 后端状态机改造

9.1 原样不动的东西

Espryt 的 persistent ring、buffer pool、fallback-repack、scratch FBO、驱动绑定影子、Adreno / Mali workaround、SPIRV-Cross 会话、restart 重写与 multi-draw 分档;Magma 的 VulkanRenderer memo、PipelineFactory、ProgramFactory、UniformManager、五个 Vk*Manager、SwapchainObject、D18 的节点式容器纪律。"输入变了、算法不许动"的那一类由 G5 字节一致门把关(scripts/p3a_untouched_regions.sh 十一函数、scripts/p4a_untouched_regions.sh 17 区),re-pin 必须两份同改。

9.2 strangler 脚手架:PipeInputs + 逐 verb 填充 + poison 世代(P1)

// MG_Backend/MGPipe/PipeInputs.h —— 按 memo 键组织,访问器类型与后端原来读到的完全一致
#if MOBILEGL_PIPE_PUSH
#  define MGB_CTX (&::MobileGL::MG_Pipe::gPipeInputs)
#else
#  define MGB_CTX (::MG_State::pGLContext)
#endif

三步:A 别名(P1,机械替换 + 逐 verb 类填充点,nm 不变)→ B 推送(P2,tracker 填 gPipeInputs,verify 构建逐 draw 比对快照版)→ C 句柄化(P3a–P4a、P7,SharedPtr<前端对象> → 句柄 + 描述符,写回变回调)。poison 是逐 verb 世代:读一个当前 verb 未填的字段是 Fatal{UnmigratedPipeInput, "<Getter>@<Verb>"}。

P13 收尾:pull 分支与宏一起删掉(W3b,MGB_CTX 不再存在,后端只经 gPipeInputs 与 applier 记录取状态);单进程也走记录臂(W4–W5),后端的前端对象臂与前端键 twin 入口删除(W6)——Espryt 的 twin 表只收 client 铸好的句柄,对象死亡通知带句柄、按句柄释放(与 server 的 object_death 同一释放)。

9.3 Track V / Track H

Track V(值类型:render state、pixel store、capability 位、标量)是机械迁移;Track H(167 个 SharedPtr<MG_State…> 读点)是真活。74% 的读点是翻译输入,所以"bump 一个版本让 server 自己拉"行不通,值本身必须过去。

9.4 残余值块

迁移期临时调用 SetResidualValueState(ResidualValueBlock):尺寸只降不升(1248 → 8,只剩 CapabilityBits),P13 W3c 删除——op 46 退役为拒绝行,capability 交叉核对交给 verify 比较器;set_context_values 携带剩下的值类字段(单进程也发,W4d / W8)。

9.5 身份 memo 的重键

{slot, gen} + 显式 destroy 让 21 条身份 memo 中 11 条直接删除、2 条的去抖搬到 client(§5.4)、7 条重键成更便宜的比较、1 条(D18)不动。统一事实:进 memo 键的版本计数器要么会回绕,要么根本不被它害怕的 mutation bump,身份比较是堵洞的补丁。

9.6 A/B 与口径收窄

MOBILEGL_PIPE_PUSH 子系统位图在阶段 B 是真 A/B;阶段 C 之后位清零时后端仍跑重键后的代码,所以编译期 MOBILEGL_PIPE_LEGACY_MEMOS 曾保留 pre-handle 臂。P13 结束了这段:LEGACY_MEMOS 与 pre-handle 臂删除,位 0–13 固定开、清位即启动期具名拒绝(原 Off 车道改为这条拒绝的阴性对照),只剩位 63 可设。位依赖两侧都拒(客户端族门里根本不发射,否则会"客户端已清 dirty、服务端却走旧臂"而丢上传);没有消费者的后端一条不发。

10. server 侧

10.1 对象表与 applier

MG_Remote/Server/PipeApplier:解码 → 更新对象表与 PipeInputs → 调后端。单进程(P13 起)是同一记录臂少了编解码与环:状态记录经 PipeRoute 的单进程表直进 applier,verb 记录由 MG_Impl/Pipe/Verb 的发射器交给本进程的 MG_Backend/Record/RecordVerbSink。server 不持有 buffer 的完整副本(只有 staged shadow)、不持有前端对象图;任何传输下都不得有 SharedPtr 或裸前端指针跨过 applier 边界(P5c 角色守卫、P5e 规则 F)。InProcessTransport 与 spawn 走完全相同的编解码路径。

10.2 monolith 侧的净收益

即使 IPC 永不上线:复用地址 ABA 一整类不可表达;FBO → program 排序 hazard 消失;SwapchainObject 写 MG_Impl 的分层倒置消失;inproc = 渲染线程。monolith 净代码量是增加的,论据只看逐线程 CPU。

10.3 索引宿主镜像(Server/IndexHostMirror,P8,待重裁)

设计:kCapNeedsHostIndexBytes 下,server 从本来就要收的 ResourceCreate/Respecify/SubData 流增量维护 element-array buffer 的宿主镜像,零额外流量;预算 MOBILEGL_PIPE_INDEX_MIRROR_MB(默认 64),超预算退化为逐 draw 经 MGHostSpan 传送。P6 的 a6 审计实测宿主索引 span 无 producer、client 索引已是 owned buffer,所以 P8 要按真实消费者重新裁定,不照抄本节(notes/p8/README.md)。