1. 课程导入

移动图形开发与桌面图形开发最大的差异,不在于 API 语法,而在于资源约束。手机和平板受限于功耗、散热、内存带宽与电池容量,GPU 的峰值算力往往无法长时间维持。因此,OpenGL ES 性能优化工程并不是“把代码写得更快”这么简单,它是一门围绕帧预算、带宽、功耗与渲染正确性进行系统权衡的工程学科。本课程的目标,是让你从“能画出画面”进阶到“能稳定、低耗、可预测地画出画面”。

学习目标可以概括为四句话:看得懂 GPU 在做什么,算得清每一帧的时间与带宽花在哪里,改得动渲染管线中的关键瓶颈,验得了优化前后的真实收益。

一、核心概念:帧预算、带宽与管线

移动图形性能的第一性原理是帧预算。以 60 FPS 为例,每帧只有约 16.6 ms;若目标为 120 FPS,则压缩到约 8.3 ms。这 16.6 ms 需要同时容纳 CPU 逻辑、驱动提交、GPU 顶点处理、光栅化、片元着色、合成与显示。任何一环超支,都会表现为掉帧、卡顿或发热降频。

第二个核心概念是带宽。移动 GPU 通常采用 Tile-Based Rendering(TBR)架构,把屏幕划分为小块,在片上高速缓存中完成片元处理,从而减少对系统内存的访问。但一旦出现频繁的 Render Target 切换、全屏后处理、大纹理采样或每帧重新上传顶点数据,带宽就会迅速成为瓶颈。很多“GPU 占用不高却依然卡”的现象,本质是带宽或同步等待造成的。

第三个核心概念是渲染管线。OpenGL ES 的管线从顶点着色器、图元装配、光栅化、片元着色器到逐片元操作,每一阶段都有对应的优化手段:顶点阶段关注属性数量与矩阵计算,片元阶段关注纹理采样次数与分支,逐片元阶段关注混合、深度测试与 Early-Z 的失效条件。

移动图形性能优化全景:从应用到像素 应用层 场景管理 / 剔除 Draw Call 组织 驱动与提交 状态校验 / 命令缓冲 同步与 Fence GPU 几何阶段 顶点着色 / 图元装配 裁剪 / 投影 GPU 像素阶段 光栅化 / 片元着色 混合 / 深度 / 写入 关键约束(移动端) 帧预算 16.6ms / 8.3ms 内存带宽 纹理 / RT / 上传 功耗与散热 降频 / 温控策略 同步开销 阻塞 / 等待 优化手段与观测工具 CPU 侧 批处理 / 实例化 / 状态排序 避免每帧重建缓冲 GPU 侧 减少 Overdraw / 简化 Shader 压缩纹理 / 合理 Mipmap 观测与验证 GPU 时间戳 / 计数器 / 抓帧 A/B 对比与回归基线

二、整体框架:从测量到验证的闭环

性能优化最忌讳“凭感觉改代码”。工程化的做法是建立闭环:测量 → 定位 → 假设 → 修改 → 验证 → 固化基线。测量阶段要区分 CPU 时间与 GPU 时间,区分渲染线程与逻辑线程;定位阶段要借助抓帧工具查看每个 Draw Call 的状态、纹理绑定与着色器指令;验证阶段必须用同一场景、同一设备、同一分辨率做 A/B 对比,否则优化结论不可信。

下面给出一个典型的优化工作流清单,可作为项目中的检查表:

阶段 关键动作 常用指标 常见产出
基线测量 固定场景与设备,采集帧时间 FPS、帧时间分布、GPU 时间 性能基线报告
瓶颈定位 抓帧分析 Draw Call 与状态 Draw Call 数、Overdraw、带宽 热点列表
方案实施 批处理、纹理压缩、Shader 简化 CPU/GPU 时间变化 优化补丁
回归验证 多机型对比,检查画质与功耗 帧率稳定性、温度、耗电 验收结论

三、案例场景:一个典型的“卡顿”排查

假设某 3D 场景在中端机上只有 35 FPS,且机身明显发热。初步抓帧发现:Draw Call 约 420 次,每帧有 3 次 Render Target 切换,片元着色器中有动态分支与多次纹理采样。此时不要急于重写着色器,而应先判断瓶颈类型。若 GPU 时间远高于 CPU 时间,优先处理 Overdraw 与纹理采样;若 CPU 提交时间占比高,则优先做批处理与状态排序。

// 伪代码:用时间戳粗略区分 CPU 与 GPU 耗时
startCpu = now();
issueDrawCalls();
endCpu = now();

gpuBegin = queryGpuTimestampBegin();
renderFrame();
gpuEnd = queryGpuTimestampEnd();

cpuMs = endCpu - startCpu;
gpuMs = gpuEnd - gpuBegin;
// 若 cpuMs 接近帧预算,优先优化提交与状态;
// 若 gpuMs 接近帧预算,优先优化着色与带宽。
优化前先建立可复现的测试场景,并记录设备型号、系统版本、分辨率与画质档位。没有基线的优化,等于没有优化。

四、误区与复盘

  • 误区一:只看平均 FPS。平均帧率会掩盖卡顿,应关注帧时间的高百分位(如 95th、99th)。
  • 误区二:把 GPU 占用低等同于没有 GPU 瓶颈。带宽、同步与驱动提交同样会造成等待。
  • 误区三:一次性改太多变量。无法归因的优化不可复用,应单变量验证。
  • 误区四:忽略功耗与温控。短时间跑分高,长时间降频后体验反而更差。
性能优化不是“把某个数字压到最低”,而是在画质、帧率、功耗与开发成本之间找到可交付的平衡点。任何脱离设备与场景的绝对结论都不可靠。

本课程后续将围绕这条主线展开:先建立测量与定位能力,再分别深入 CPU 提交、GPU 几何、片元与带宽、纹理与内存、Shader 与工具链,最终形成一套可落地的移动图形性能优化工程方法。掌握这套方法后,你面对的不再是“玄学卡顿”,而是一组可测量、可解释、可验证的工程问题。