RFR: 8258754: Gracefully fallback to the OpenGL rendering pipeline if Metal rendering pipeline initialization fails [v5]

Kevin Rushforth kcr at openjdk.java.net
Sat Jan 16 00:41:23 UTC 2021


On Mon, 11 Jan 2021 11:54:49 GMT, Ajit Ghaisas <aghaisas at openjdk.org> wrote:

>>> this implies that -Dsun.java2d.opengl=false on its own means the same as -Dsun.java2d.metal=true.
>>> 
>>> This is a bit grayer. It would imply that there is a designated fall back.
>>> 
>>> I take that back - it isn't grey. Because the default for metal is false, it means you've disabled both so rule 1 applies
>>> I'll add another rule up above to make it clearer.
>>> 
>>> But .. we have a sort of precedent on windows that d3d=false means fall back to gdi. So that contradicts the above :-(
>>> 
>>> So is metal a "fallback" or an "option" ? We don't fall back to optional pipelines. Meaning d3d=false would not cause opengl to be used on windows.
>> 
>> My thinking differs on this. When we will integrate Lanai JEP to the mainline, we will have 2 rendering pipelines on macOS - OpenGL and Metal - OpenGL being default.
>> If user specifically asks for -Dsun.java2d.opengl=false, then we should definitely try to use the other available pipeline - whether it is fallback or optional is immaterial. Otherwise, we would end up in a situation where no UI will be launched.
>> 
>> I suggest that we deliberate and decide on this outside of this PR.
>
>> _Mailing list message from [Alexey Ushakov](mailto:alexey.ushakov at jetbrains.com) on [lanai-dev](mailto:lanai-dev at openjdk.java.net):_
>> 
>> Hi Ajit,
>> 
>> Let?s have some refactoring here.
>> 
>> We have two places this:
>> 
>> 107 surfaceData = (CGraphicsDevice.usingMetalPipeline()) ?
>> 
>> 108 ((MTLLayer)windowLayer).replaceSurfaceData() :
>> 109 ((CGLLayer)windowLayer).replaceSurfaceData()
>> 110 ;
>> 111 return surfaceData;
>> 112 }
>> 
>> I think it would be better to have a common superclass for CGLayer and MTLLayer with common methods replaceSurfaceData(), getPointer().
>> 
>> public class CFLayer extends CFRetainedResource {
>> ?
>> public long getWindowLayerPtr() {}
>> 
>> public SurfaceData replaceSurfaceData() {}
>> ...
>> }
>> 
>> So, we can get rid of (CGraphicsDevice.usingMetalPipeline()) ? ? : ? checks
>> 
>> Best Regards,
>> Alexey
> 
> Thanks Alexey for this suggestion.
> Yes. It will simplify the code. This PR is about implementing the fallback mechanism. Once that is in place, we can handle the runtime pipeline selection pattern correction under JDK-8226384.

Conceptually, having an ordered list of the (two) pipelines makes sense (it's what we did for JavaFX with the "prism.order" property).

For Java2D, in order to fit with existing pattern and existing property names used on other platforms, we will need to stick with the separate properties as defined in this PR.

Ultimately, Phil gets to decide this, but at a high level here is what I recommend (I think it's pretty much what Ajit's latest patch intends to do, although I haven't looked at the latest changes in enough detail to be sure that's what it does).

1. If no properties are specified, try the default pipeline first and "fall back" to the optional pipeline if the default isn't available.

2. If exactly one of sun.java2d.opengl or sun.java2d.metal is set to true, then try that pipeline first and the other one as a fallback.

3. If exactly one of sun.java2d.opengl or sun.java2d.metal is set to false, then try the other one first and that one last.

4. If both are set to true or both are set to false, print a warning and ignore the properties entirely (i.e., use the default).

The following pseudo-code illustrates this:

    // default pipeline order
    pipelineOrder = { OPENGL, METAL };

    if ("sun.java2d.opengl" and "sun.java2d.metal" are both set and are equal) {
        // WARN and use the above default
    } else if ("sun.java2d.opengl" is "true" || "sun.java2d.metal" is "false") {
        pipelineOrder = { OPENGL, METAL };
    } else if ("sun.java2d.opengl" is "false" || "sun.java2d.metal" is "true") {
            pipelineOrder = { METAL, OPENGL };
        }
    }

    // Try the first pipeline in the list; if it fails, try the second

One advantage of the above is that it is trivial to change the default pipeline by just reversing the order in the initial list with no other changes needed.

-------------

PR: https://git.openjdk.java.net/lanai/pull/147


More information about the lanai-dev mailing list