Term 的终端渲染改用 EGL/GLES3 实例化渲染器 —— 在真机上实测的方法、数据与画面。
同一台真机(华为 Pura 70)、同一份语料,通过内置的 Log frame stats 开发者开关,将 GPU 路径与 CPU 基线做 A/B 对比。
| 工作负载 | CPU 路径 | GPU 路径 | 提速 |
|---|---|---|---|
| 全屏滚动(firehose) | 14.6 ms · 68 fps | 5.3 ms · 188 fps | 2.7× |
| 慢速滚动(~5 行/帧) | 12.8 ms · 76 fps | 6.0 ms · 167 fps | 2.1× |
GPU 路径的帧时间几乎与滚动量无关 —— 每一帧都是一次完整重绘,而这对 GPU 来说很便宜。CPU 路径对滚动行数敏感的问题就此消失。
每帧约 1000 个实例化四边形。字形只光栅化一次进入纹理图集,之后每帧仅重新发射网格实例。
| 阶段 | 平均 | 说明 |
|---|---|---|
| build | 2.15 ms | CPU 侧:遍历网格 → 实例四边形 + 光栅化新字形入图集 + 上传 |
| draw | 0.22 ms | GL 实例化绘制 |
| swap | 2.95 ms | eglSwapBuffers(呈现) |
| 帧总计 | 5.32 ms | ≈ 188 fps |
消除两次搬运 14 MB 的内存操作:不再有影子位图的滚动位移(~6 ms),也不再有到 dmabuf 的拷贝(~5.6 ms)—— 这 ~11 ms 就是全部的节省。GPU 直接在 EGL 表面上原地光栅化。
语料是彩色 ANSI-SGR 混合中文、韩文与 ASCII,由基准脚本写入会话 TTY,无需触碰手机。
脚本自动化三个阶段(firehose 滚动 / 空闲闪烁 / 单行更新),通过向远程主机上会话的 TTY 写入实现 —— 手机端零交互。
# 语料:彩色 ANSI-SGR + 中文/韩文/ASCII,400 行 corpus() { i=0 while [ $i -lt 400 ]; do printf "\033[3%dm%04d 端末描画性能測定 中文渲染基准 가나다라마 \033[1mBOLD\033[0m ascii-abcdefghijklmnop %05d\n" \ $((i % 8)) $i $((i * 37)) i=$((i + 1)) done } C="$(corpus)" # P1 firehose 滚动 30s(满帧全损) end=$((SECONDS + 30)) while [ $SECONDS -lt $end ]; do printf "%s\n" "$C" > "$T"; done # P2 空闲 60s(仅闪烁 → 局部呈现帧) sleep 60 # P3 单行更新 20s(~8 Hz,打字形状的局部帧) end=$((SECONDS + 20)) while [ $SECONDS -lt $end ]; do printf "\rtyping simulation %06d" $n > "$T"; n=$((n + 1)); sleep 0.12 done
gpubench.sh 拷到该主机,用 who -u 找到会话对应的 TTY。./gpubench.sh /dev/ttysNNN(会话的 tty)。hdc -t <target> shell hilog | grep "connrender: gpu" —— 每 60 帧输出一条统计窗口。注意:P2/P3 的统计窗口跑在低 DVFS 频率下(每秒仅 2–9 次绘制,时钟处于最低档),与 firehose 数字不可直接比较 —— 只做同节奏对比。P1 的第一个窗口包含一次性的 CJK 字形光栅化爆发(属正常)。