JDK-8238361 : JEP 382: New macOS Rendering Pipeline
  • Type: JEP
  • Component: client-libs
  • Sub-Component: 2d
  • Priority: P3
  • Status: Closed
  • Resolution: Delivered
  • Fix Versions: 17
  • Submitted: 2020-01-31
  • Updated: 2021-10-22
  • Resolved: 2021-09-02
Related Reports
Blocks :  
Blocks :  
Duplicate :  
Sub Tasks
JDK-8268631 :  
Description
Summary
-------

Implement a Java 2D internal rendering pipeline for macOS using the Apple Metal API as alternative to the existing pipeline, which uses the deprecated Apple OpenGL API.

Goals
------ 

- Provide a fully functional rendering pipeline for the Java 2D API that uses the macOS Metal framework.

- Be ready in the event Apple removes the deprecated OpenGL API from a future version of macOS.

- Ensure transparency of the new pipeline to Java applications.

- Ensure functional parity of the implementation with the existing OpenGL pipeline.

- Provide performance as good or better than the OpenGL pipeline in select real applications and benchmarks.

- Create a clean architecture that fits into the existing Java 2D pipeline model.

- Co-exist with the OpenGL pipeline until it is obsolete.

Non-Goals
---------

- It is not a goal to remove or disable the existing OpenGL pipeline.

- It is not a goal to add any new Java or JDK APIs. This is all internal implementation.

Motivation
----------

Two major factors motivate the introduction of a new Metal-based rendering pipeline on macOS:

- Apple [deprecated the OpenGL rendering library in macOS 10.14][opengl-depr], in September 2018. Java 2D on macOS is completely reliant on OpenGL for its internal rendering pipeline, so a new pipeline implementation is needed.

- Apple claims that the [Metal framework](https://developer.apple.com/metal/), their replacement for OpenGL, has superior performance. For the Java 2D API, this is generally the case with some exceptions.

[opengl-depr]: https://developer.apple.com/documentation/macos_release_notes/macos_mojave_10_14_release_notes?language=objc#3035786

Description
-----------

Most graphical Java applications are written using the Swing UI toolkit, which renders via the Java 2D API.  Internally, Java 2D can use software rendering plus a blit to the screen or it can use a platform-specific API, such as X11/Xrender on Linux, Direct3D on Windows, or OpenGL on macOS.  These platform-specific APIs typically offer much better performance than software rendering, and generally off-load the CPU.  Metal is the new macOS platform API for such rendering, replacing the deprecated OpenGL API.  (The name has nothing to do with the Swing “Metal” Look and Feel; that is just a coincidence.)

We created a substantial amount of new internal implementation code to use the Metal framework, just as we already had for the other platform-specific APIs. Whilst easily fitting into the existing framework the new code is much more modern in its use of graphics hardware, making use of shaders rather than a fixed function pipeline.
The changes are confined to macOS-specific code and even there only a minimal amount of code shared between Metal and OpenGL is updated. We did not introduce any new Java APIs, nor did we change any existing API.

The Metal pipeline can co-exist with the OpenGL pipeline.  When a graphical application starts up, one or the other is chosen.  For now, OpenGL remains the default.  Metal is used only if it is specified on startup or if the initialization of OpenGL fails, as would happen in a future version of macOS with no OpenGL support.

At the time of integration of this JEP, Apple have yet to remove OpenGL.
Until that happens an application can opt-in to Metal by specifying `-Dsun.java2d.metal=true` on the `java` command line.  We will make the Metal rendering pipeline the default in a future release.

Prior to integration in the JDK, we conducted work on this JEP in [Project Lanai](http://openjdk.java.net/projects/lanai/).

Testing
-------

Testing the functionality of the new pipeline did not require new functional test development, since no Java 2D APIs were changed.  Existing tests and real-world applications sufficed.  These included:

- JDK jtreg regression tests,
- JCK Tests,
- Java 2D and Swing Demos, and
- IDEs such as Intellij IDEA and Netbeans, as examples of large-scale real world applications.

To test performance, we used:

- J2DBench, a Java 2D benchmarking application included in JDK,
- RenderPerfTest, a custom stress test that renders multiple objects of the same primitive type and measures frames per second (FPS) developed in Project Lanai, and
- IntelliJ IDEA IDE performance.

Performance results for the final planned early-access release are [here](https://bugs.openjdk.java.net/browse/JDK-8261408).

To further verify the new pipeline, we used macOS Xcode instrumentation tools to check for leaks and for correct Metal API usage.

Risks and Assumptions
---------------------

- We tested on a variety of hardware and macOS versions which are presumed to be representative, but not all combinations were available.  Since we could not account for all scenarios, it is possible that performance limitations remain.

- We did very limited (sanity) testing of the current x64 binaries on Apple Silicon. No port of the JDK to Apple Silicon is yet available to support native testing.

- Metal does not support the XOR operation, so we had to accept lower performance in that niche case. That is likely to remain so until such time as Metal provides direct support for XOR.

Comments
Thanks, Phil & Ajit. Nice numbers! :-)
22-02-2021

> Have you benchmarked this in any way? I.e., do we have any hard numbers regarding the performance relative to the OpenGL pipeline on current Apple hardware? See https://bugs.openjdk.java.net/browse/JDK-8261408
21-02-2021

Now that this JEP is ready for targeting, could you please update it to describe what you’ve done rather than what you will or might do? Did you, for example, find new opportunities to leverage new capabilities of the Metal framework? Did the lists of tests change? Have you exceeded your goals and metrics, as suggested in the final paragraph? Did you find a way to implement the XOR operation efficiently?
18-02-2021

[~hschreiber], The measured performance results are available at - JDK-8261408. [~gziemski], There is no way for the user to specify which GPU to use. This is true for OpenGL rendering pipeline as well as the Metal rendering pipeline. It is a system setting and we honor the chosen GPU and GPU switch events.
09-02-2021

Is there a way for the developer/user to specify which GPU to use with Metal based pipeline? The available choices are: - built-in low power integrated GPU - built-in discrete GPU - external GPU connected via Thunderbolt
08-02-2021

I love that this JEP is becoming reality. Thanks for your awesome work! Out of curiosity: Have you benchmarked this in any way? I.e., do we have any hard numbers regarding the performance relative to the OpenGL pipeline on current Apple hardware?
04-02-2021

The goals defined above have been met, the test plan has been implemented and we are in good shape with just a small number of non-critical issues outstanding, and so we are ready to propose targeting this JEP to JDK 17. And a PR for code review of the implementation to be integrated into JDK has been posted :https://git.openjdk.java.net/jdk/pull/2403
04-02-2021

Yes -- the Success Metrics didn't add anything that wasn't already mentioned in the Goals, so I removed it.
14-04-2020

Yes I am fine with this version. I've made the title shorter. I suppose the summary tells you everything that the title now does not. I suppose Success metrics was considered redundant ? That's fine. I will reassign
14-04-2020

I’ve edited the text to tighten the wording. If this looks okay to you then please assign the issue to me and I’ll move it to Candidate. Can we find a shorter title for this JEP? Most readers of JEP titles won't know what “Metal” is. How about just “New macOS Rendering Pipeline”?
14-04-2020

Responding to the above #1 pixel for pixel mandated only to the extent that the 2D specification requires it, but we still care about it. #2 performance is mentioned as one of the motivations. Efficiency usually affects that. But functionality is #1. #3. Yes, we can of course ask about XOR or anything else that seems to be missing. FWIW there is an open rdr on this https://openradar.appspot.com/34763016 Definitely not thinking of new user-level APIs. The basic idea is that in the OpenGL code (and D3D) we have a single Java thread that makes all the calls to the platform OpenGL APIs, but Metal supposedly supports being used concurrently from multiple threads. This might improvement performance for some applications. Some early attempts to try this produced crashes, so it is on the back burner until we get functionality finished.
08-04-2020

Did anyone try https://moltengl.com/moltengl/ to see how our OpenGL pipeline works on top of their OpenGL implementation, which they implemented on top of Metal? Our Metal pipeline should, hopefully, be faster than our GL pipeline on top of molten.
08-04-2020

A few questions: #1 Is "pixel for pixel" match for the new pipeline with the existing pipelines a goal or non-goal? #2 Are we concerned about the efficiency of our Metal based pipeline implementation, i.e. comparing the GPU usage of the new Metal based pipeline with the existing OpenGL based one? (also, comparing any other resources, such as RAM/VRAM/CPU usage) #3 Can we ask Apple to help with the XOR as a possibly new feature in their Metal APIs? Feedback: I love seeing the sentence about taking advantage of concurrent rendering in the description, but could it be expanded a bit? Are we thinking of new user level APIs (I ask even though the description says no new user level API in non-goals, but I take it to mean: no direct access to the Metal APIs) or only internal implementation, and if so, do we have an idea of what scenarios we would like to handle and what kind of apps would benefit?
08-04-2020