Skip to content

从硬件到开发者:客户端渲染的系统栈 ​

这不是一张“软件分层图”。它描述一次输入如何穿过真实机器,最后成为一帧画面;也描述开发者写的一行状态更新,最后怎样反向变成 CPU 工作、驱动命令、GPU 任务与显示扫描。

text
用户动作
  -> 输入设备与控制器
  -> 内核输入子系统 / 中断 / 调度
  -> 应用进程与运行时
  -> UI 库、状态与渲染引擎
  -> 窗口系统 / 浏览器合成器 / 图形 API
  -> 驱动、命令缓冲、同步对象
  -> GPU、显存、显示控制器
  -> 屏幕扫描出一帧
  -> 用户看见结果,开始下一次动作

反向看同一条链:开发者不是“直接画像素”,而是在约定范围内描述状态、结构、样式和动画;库与引擎把它们编译成图形工作;内核和驱动负责安全地调度 CPU、内存和 GPU;显示硬件按刷新节奏把结果呈现出去。

节点清单 ​

节点输入它维护的状态输出给谁典型故障表现
输入设备触摸、鼠标、键盘、笔设备报告、坐标、按键状态控制器与内核丢事件、坐标漂移、输入延迟
CPU 与内存指令、数据、缺页、中断寄存器、缓存、页表、线程上下文内核、应用、驱动长任务、抖动、换页、响应慢
GPU 与显示硬件命令缓冲、纹理、fence队列、显存、管线状态、扫描时序显示控制器掉帧、白块、纹理压力、撕裂
内核与驱动IRQ、系统调用、DMA、图形命令进程、虚拟内存、设备队列、同步对象窗口系统、应用、GPU任务排队、阻塞、设备重置、权限失败
平台图形栈窗口表面、buffer、输入事件surface、buffer ownership、合成顺序浏览器/Flutter/原生应用不可见窗口、合成延迟、缩放错误
引擎与库DOM/Widget、样式、状态变更渲染树、布局、显示列表、图层图形 API 与平台 surface布局错、重绘大、动画掉帧
开发者代码业务事件、异步结果状态机、identity、缓存、命令关联UI 库与网络/存储假成功、竞态、整页重建、不可访问

一次点击的真实路径 ​

以“点击保存,按钮变为提交中,服务端确认后显示已保存”为例:

  1. 输入设备报告按下与抬起;控制器通过中断或轮询把报告交给内核。
  2. 内核记录输入事件,调度目标窗口所属线程;窗口系统或浏览器进程完成坐标与目标路由。
  3. 应用线程运行事件处理器,状态从 editing 变为 submitting(requestId);UI 库计算最小更新。
  4. 引擎重新布局或更新图层,生成绘制命令;图形库把命令编码进 command buffer。
  5. 驱动验证与提交命令,GPU 栅格化或合成;fence 表示哪一批工作已经完成。
  6. 显示控制器在合适的刷新周期取到新 buffer,扫描到屏幕。此时用户看到“提交中”。
  7. 网络结果回到应用,重复第 3 到第 6 步。只有服务端确认与本地状态一致时,画面才能显示“已保存”。

前六步解决“如何尽快把本地状态变成可见画面”;第七步才涉及共享事实。画面先变不等于保存已经完成。

分页阅读 ​

  1. 硬件与显示链:CPU、缓存、内存、PCIe、GPU、显存、显示控制器和刷新。
  2. 内核与驱动:中断、调度、虚拟内存、系统调用、DMA、图形驱动、命令队列和 fence。
  3. 平台图形栈、引擎与应用:窗口系统、surface、浏览器/Flutter 引擎、图形库、UI 框架与开发者边界。
  4. 跨层故障链:把“点了没反应、卡、花屏、假成功”还原成可验证节点。

学习准则 ​

不要按名词背诵。每遇到一个组件,先问:它是否拥有状态?它能否并行?它如何同步?它和谁交换 buffer 或消息?它失败后用户看到了什么?能回答这些,才算真正把它放进图里。

学习规划与研究资料库