JEP 382:新的 macOS 渲染管道
概括
使用 Apple Metal API 为 macOS 实现 Java 2D 内部渲染管道,作为现有管道的替代方案,现有管道使用已弃用的 Apple OpenGL API。
目标
-
为使用 macOS Metal 框架的 Java 2D API 提供功能齐全的渲染管道。
-
做好准备,以防 Apple 从未来版本的 macOS 中删除已弃用的 OpenGL API。
-
确保新管道对 Java 应用程序的透明度。
-
确保实现与现有 OpenGL 管道的功能对等。
-
在选定的实际应用程序和基准测试中提供与 OpenGL 管道一样好或更好的性能。
-
创建适合现有 Java 2D 管道模型的干净架构。
-
与 OpenGL 管道共存,直至其过时。
非目标
-
删除或禁用现有 OpenGL 管道并不是目标。
-
添加任何新的 Java 或 JDK API 并不是我们的目标。这都是内部实现。
动机
有两个主要因素促使在 macOS 上引入新的基于 Metal 的渲染管道:
-
Apple于 2018 年 9 月在 macOS 10.14 中弃用了 OpenGL 渲染库。macOS 上的 Java 2D 的内部渲染管道完全依赖于 OpenGL,因此需要新的管道实现。
-
Apple 声称Metal 框架(OpenGL 的替代品)具有卓越的性能。对于 Java 2D API,通常是这种情况,但也有一些例外。
描述
大多数图形 Java 应用程序都是使用 Swing UI 工具包编写的,该工具包通过 Java 2D API 进行呈现。在内部,Java 2D 可以使用软件渲染加上屏幕传输,也可以使用特定于平台的 API,例如 Linux 上的 X11/Xrender、Windows 上的 Direct3D 或 macOS 上的 OpenGL。这些特定于平台的 API 通常提供比软件渲染更好的性能,并且通常可以减轻 CPU 的负载。 Metal 是用于此类渲染的新 macOS 平台 API,取代了已弃用的 OpenGL API。 (这个名字与 Swing“金属”外观和感觉无关;这只是一个巧合。)
我们创建了大量新的内部实现代码来使用 Metal 框架,就像我们已经为其他特定于平台的 API 所做的那样。虽然很容易融入现有框架,但新代码在图形硬件的使用方面更加现代,使用着色器而不是固定的功能管道。这些更改仅限于 macOS 特定的代码,即使 Metal 和 OpenGL 之间共享的代码也只有极少量的更新。我们没有引入任何新的 Java API,也没有更改任何现有的 API。
Metal 管道可以与 OpenGL 管道共存。当图形应用程序启动时,将选择其中之一。目前,OpenGL 仍然是默认设置。仅当在启动时指定或 OpenGL 初始化失败时才使用 Metal,就像在不支持 OpenGL 的 macOS 的未来版本中会发生的情况一样。
在集成此 JEP 时,Apple 尚未删除 OpenGL。在此之前,应用程序可以通过在命令行-Dsun.java2d.metal=true
上指定来选择加入 Metal java
。我们将在未来版本中将 Metal 渲染管道设置为默认管道。
在集成到 JDK 之前,我们在Project Lanai中对此 JEP 进行了工作。
测试
测试新管道的功能不需要新的功能测试开发,因为没有更改 Java 2D API。现有的测试和实际应用就足够了。其中包括:
- JDK jtreg回归测试,
- JCK 测试,
- Java 2D 和 Swing 演示,以及
- Intellij IDEA 和 Netbeans 等 IDE 是大规模现实应用程序的示例。
为了测试性能,我们使用了:
- J2DBench,JDK 中包含的 Java 2D 基准测试应用程序,
- RenderPerfTest,一种自定义压力测试,可渲染相同基元类型的多个对象并测量在 Project Lanai 中开发的每秒帧数 (FPS),以及
- IntelliJ IDEA IDE 性能。
最终计划的抢先体验版本的性能结果如下。
为了进一步验证新管道,我们使用 macOS Xcode 检测工具来检查是否存在泄漏以及 Metal API 的使用是否正确。
风险和假设
-
我们在各种被认为具有代表性的硬件和 macOS 版本上进行了测试,但并非所有组合都可用。由于我们无法考虑所有场景,因此性能限制可能仍然存在。
-
我们对 Apple Silicon 上当前的 x64 二进制文件进行了非常有限的(健全的)测试。目前还没有 JDK 到 Apple Silicon 的端口可用于支持本机测试。
-
Metal 不支持 XOR 运算,因此我们不得不接受在这种特殊情况下较低的性能。在 Metal 为 XOR 提供直接支持之前,这种情况可能会持续下去。