On Tue, 22 Jul 2025 17:00:25 GMT, Ambarish Rapte <ara...@openjdk.org> wrote:

>> ### Description
>> This is the implementation of new graphics rendering pipeline for JavaFX 
>> using Metal APIs on MacOS.
>> We released two Early Access (EA) builds and have reached a stage where it 
>> is ready to be integrated.
>> Default rendering pipeline on macOS has not been changed by this PR. OpenGL 
>> still stays as the default rendering pipeline and Metal rendering pipeline 
>> is optional to choose (by providing  `-Dprism.order=mtl`)
>> The `-Dprism.verbose=true` option can be used to verify the rendering 
>> pipeline in use.
>> 
>> ### Details about the changes
>> 
>> **Shader changes**
>> - MSLBackend class: This is the primary class that parses (Prism and Decora) 
>> jsl shaders into Metal shaders(msl)
>> - There are a few additional Metal shader files added under directory : 
>> modules/javafx.graphics/src/main/native-prism-mtl/msl
>> 
>> **Build changes** - There are new tasks added to build.gradle for
>> - Generation/ Compilation/ linking of Metal shaders
>> - Compilation of Prism Java and Objective C files
>> 
>> **Prism** - Prism is the rendering engine of JavaFX.
>> - Added Metal specific Java classes and respective native implementation 
>> which use Metal APIs
>> - Java side changes:
>>   - New Metal specific classes: Classes prefixed with MTL, are added here : 
>> modules/javafx.graphics/src/main/java/com/sun/prism/mtl 
>>   - Modification to Prism common classes: A few limited changes were 
>> required in Prism common classes to support Metal classes. 
>> - Native side changes:
>>   - New Metal specific Objective C implementation is added here: 
>> modules/javafx.graphics/src/main/native-prism-mtl
>> 
>> **Glass** - Glass is the windowing toolkit of JavaFX
>> - Existing Glass classes are refactored to support both OpenGL and Metal 
>> pipelines
>> - Added Metal specific Glass implementation.
>> 
>> ### Testing
>> - Testing performed on different hardware and macOS versions.
>>   - HW - macBooks with Intel, Intel with discrete graphics card, Apple 
>> Silicon (M1, M2 and M4)
>>   - macOS versions - macOS 13, macOS 14 and macOS 15
>> - Functional Testing:
>>   - All headful tests pass with Metal pipeline.
>>   - Verified samples applications: Ensemble and toys
>> - Performance Testing:
>>   - Tested with RenderPerfTest: Almost all tests match/exceed es2 
>> performance except a few that fall a little short on different hardwares. 
>> These will be addressed separately (there are open bugs already filed)
>> 
>> ### Note to reviewers :
>> - Providing `-Dprism.order=mtl` option is a must for testing the Metal 
>> pipeline
>> - It woul...
>
> Ambarish Rapte has updated the pull request with a new target base due to a 
> merge or a rebase. The incremental webrev excludes the unrelated changes 
> brought in by the merge/rebase. The pull request contains 12 additional 
> commits since the last revision:
> 
>  - Merge branch 'master' into impl-metal
>  - add comment for ES2SwapChain.getFboID
>  - remove MTLLog
>  - andy review comments 1
>  - changes for running apps in eclipse
>  - review-update: jni method refactoring
>  - add @Override
>  - minor cleanup changes in glass
>  - Use appropriate layer for setting opacity
>  - Glass changes after Metal PR inputs
>  - ... and 2 more: https://git.openjdk.org/jfx/compare/bc5879c6...1a9a0a41

I did a sanity review of some of the Java section as I don't have a Mac to test 
on.

build.gradle line 2705:

> 2703:                 exec {
> 2704:                     commandLine("${metalCompiler}")
> 2705:                     args += [ "-std=macos-metal2.4" ]

Should this version number be moved to the properties file with the other 
versions? Is it expected to be updated? Metal 4 was released recently, and 
Metal 3 was released a few years ago. Are we not going to end up with a version 
that's going to be "old" by the time it's released?

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 2:

> 1: /*
> 2:  * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights 
> reserved.

Is the copyright of 2021 needed if the file was introduced in 2025? Other files 
are also like that, but not all.

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 52:

> 50: import static java.util.Map.entry;
> 51: 
> 52: public class MSLBackend extends SLBackend {

Since this is a new class, can we have a bit of class docs to explain what it 
is and what it relates to? Same for the other classes where you deem it not 
trivial.

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 64:

> 62: 
> 63:     private String shaderFunctionName;
> 64:     private String textureSamplerName;

This variable is assigned but never read (unused). Is it needed for anything?

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 182:

> 180:     protected String getQualifier(Qualifier q) {
> 181:         String qual = QUAL_MAP.get(q.toString());
> 182:         return (qual != null) ? qual : q.toString();

All these "get or else" methods can use `Map::getOrDefault`:

return QUAL_MAP.getOrDefault(q.toString(), q.toString());

And if `toString` is expensive, it can be stored in a local variable first.

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 216:

> 214:                 // For every user defined function, pass reference to 4 
> samplers and
> 215:                 // reference to the uniforms struct.
> 216:                 if 
> (!CoreSymbols.getFunctions().contains(getFuncName(e.getFunction().getName())) 
> &&

Eclipse kindly warns that `CoreSymbols.getFunctions()` is a collection of 
`Function`, but it's searched of a `String`. Perhaps `.getName()` shouldn't be 
called here?

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 238:

> 236:             if (first) {
> 237:                 // Add 4 sampler variables and "device <Uniforms>& 
> uniforms" as the parameter to all user defined functions.
> 238:                 if 
> (!CoreSymbols.getFunctions().contains(getFuncName(d.getFunction().getName())) 
> &&

Same "unlikely argument".

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 256:

> 254:         Variable var = d.getVariable();
> 255:         Qualifier qual = var.getQualifier();
> 256:         if (qual == Qualifier.CONST) { // example. const int i = 10;

Using a switch expression here on the enum will be cleaner. First, the `else` 
at the end can't be reached unless `qual == null`. If it's at all possible for 
it to be `null`, it should be explicitly expressed (via `case null -> ...`). 
Second, if other enum constants are added later (is it possible even?), we 
*should* get a compiler error and not go to the `else` blindly.

I would also extract the content of each branch to its own private method, 
especially when there're a lot of comments that could go on it:

case null -> visitVarDecl(d) // if can be null
case CONST -> handleConst()
case PARAM -> handleParam()

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 317:

> 315:         String shaderType = isPrismShader ? "PRISM" : "DECORA";
> 316: 
> 317:         if (fragmentShaderHeader == null) {

Looks like `fragmentShaderHeader` is only used once and then retained in memory 
just to check later on if it was initialized  and written. Perhaps a boolean 
flag would make it clearer? In that case the builder is used and discarded with 
the appropriately-named flag conveying a meaning better than "string builder == 
null", such as `wasHeaderWritten`.

I would also extract the content of the `if` to its own method, but it's just 
my style to break up long methods.

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 359:

> 357: 
> 358:             if (objCHeader.length() == 0) {
> 359:                 objCHeader.append("#ifndef " + shaderType + 
> "_SHADER_COMMON_H\n" +

Is `objHeader` supposed to have this content initialized only once? Doesn't 
`shaderType` change in later calls?
It's also never cleared, is it supposed to retain all its content?

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 511:

> 509:         texSamplerMap = new HashMap<>();
> 510:         helperFunctions = new ArrayList<>();
> 511:         uniformNames = new ArrayList<>();

You should be able to initialize these at the declaration site and make them 
final. Here you can call `clear` to reset the content. Perhaps it's better than 
recreating the data structure?

Alternatively, you can encapsulate all the variables and methods that are used 
per-shader in a single inner class and create a new instance per shader for the 
duration of handling that shader. This approach provides better separation and 
encapsulation and tends to be less error prone.

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/backend/hw/MSLBackend.java
 line 529:

> 527:         } else {
> 528:             objCHeaderFileName = DECORA_SHADER_HEADER_FILE_NAME;
> 529:         }

If you prefer, this can be
`objCHeaderFileName = isPrismShader ? PRISM_SHADER_HEADER_FILE_NAME : 
DECORA_SHADER_HEADER_FILE_NAME;`

modules/javafx.graphics/src/jslc/java/com/sun/scenario/effect/compiler/model/CoreSymbols.java
 line 57:

> 55: 
> 56:     public static Set<Function> getFunctions() {
> 57:         return Collections.unmodifiableSet(getAllFunctions());

Could be `Set::copyOf` if you prefer.

modules/javafx.graphics/src/main/java/com/sun/prism/GraphicsPipeline.java line 
52:

> 50:          */
> 51:         GLSL,
> 52:         /**

An empty line between the constants can help with readability.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLContext.java line 50:

> 48: import java.nio.ByteBuffer;
> 49: 
> 50: public class MTLContext extends BaseShaderContext {

Looks like all the fields here can be private. I don't see them used outside of 
this class.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLContext.java line 97:

> 95:     static {
> 96:         final String shaderLibName = "msl/jfxshaders.metallib";
> 97:         final Class clazz = MTLContext.class;

Raw type -> `Class<MTLContext>`

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLContext.java line 
232:

> 230:             }
> 231:             MTLShader.setTexture(texUnit, tex, linear, wrapMode);
> 232:         }

Maybe this is cleaner, and the removal of the default branch is safer.

        if (tex == null) return;
        boolean linear = tex.getLinearFiltering();
        int wrapMode = switch (tex.getWrapMode()) {
            case CLAMP_NOT_NEEDED -> MTL_SAMPLER_ADDR_MODE_NOP;
            case CLAMP_TO_EDGE, CLAMP_TO_EDGE_SIMULATED, 
CLAMP_TO_ZERO_SIMULATED -> MTL_SAMPLER_ADDR_MODE_CLAMP_TO_EDGE;
            case CLAMP_TO_ZERO -> MTL_SAMPLER_ADDR_MODE_CLAMP_TO_ZERO;
            case REPEAT, REPEAT_SIMULATED -> MTL_SAMPLER_ADDR_MODE_REPEAT;
        };
        MTLShader.setTexture(texUnit, tex, linear, wrapMode);

Can the texture legally be `null` and this method still called with it? Looks 
odd to call `updateTexture` with a `null` texture.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLContext.java line 
247:

> 245:         } else {
> 246:             scratchTx = scratchTx.mul(xform).mul(perspectiveTransform);
> 247:         }

Looks like `mul` already does the short-circuiting identity check, so no need 
for the if-else:
`scratchTx.set(projViewTx).mul(xform).mul(getPerspectiveTransformNoClone());`

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLContext.java line 
258:

> 256:     protected void updateWorldTransform(BaseTransform xform) {
> 257:         worldTx.setIdentity();
> 258:         if ((xform != null) && (!xform.isIdentity())) {

Redundant identity check.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLContext.java line 
302:

> 300:             default:
> 301:                 throw new InternalError("Unrecognized composite mode: " 
> + mode);
> 302:         }

This can be an expression switch:

        int mtlCompMode = switch (mode) {
            case CLEAR -> MTL_COMPMODE_CLEAR;
            case SRC -> MTL_COMPMODE_SRC;
            case SRC_OVER -> MTL_COMPMODE_SRCOVER;
            case DST_OUT -> MTL_COMPMODE_DSTOUT;
            case ADD -> MTL_COMPMODE_ADD;
        };

No need for a default branch with enum. You want an error when a new constant 
is added.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLContext.java line 
315:

> 313:         // implement or change in future if necessary
> 314:         long dstNativeHandle = dstRTT == null ? 0L : 
> ((MTLTexture)dstRTT).getNativeHandle();
> 315:         long srcNativeHandle = ((MTLTexture)srcRTT).getNativeHandle();

Raw types -> `MTLTexture<?>`

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLContext.java line 
407:

> 405:         } else {
> 406:             throw new IllegalArgumentException("illegal value for 
> CullMode: " + cullMode);
> 407:         }

Can be an expression switch.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLContext.java line 
485:

> 483: 
> 484:     private void updateRawMatrix(GeneralTransform3D src) {
> 485:         rawMatrix[0]  = (float)src.get(0); // Scale X

Is there a meaningful loss of precision here?

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLGraphics.java line 
32:

> 30: import com.sun.prism.paint.Color;
> 31: 
> 32: public class MTLGraphics extends BaseShaderGraphics {

Doesn't look like the class needs to be public. Same for other classes in this 
package, like `MTLContext`. I suggest minimizing visibility to avoid leaking 
the class outside of its scope and also for better readability context.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLGraphics.java line 
45:

> 43:             return null;
> 44:         }
> 45:         return new MTLGraphics(context, target);

Can be a ternary if you prefer.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLMesh.java line 32:

> 30: 
> 31: class MTLMesh extends BaseMesh {
> 32:     static int count = 0;

Do we use a new line after a class declaration?

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLMesh.java line 83:

> 81:     }
> 82: 
> 83:     static class MTLMeshDisposerRecord implements Disposer.Record {

Can be private.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLMeshView.java line 
40:

> 38:     private final long nativeHandle;
> 39: 
> 40:     final private MTLMesh mesh;

`mesh` is unused. Is it awaiting a dereference in `dispose()`?

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLMeshView.java line 
113:

> 111:     }
> 112: 
> 113:     static class MTLMeshViewDisposerRecord implements Disposer.Record {

Can be private. Same in other places.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLPhongMaterial.java 
line 37:

> 35: import com.sun.prism.impl.Disposer;
> 36: 
> 37: class MTLPhongMaterial extends BasePhongMaterial implements PhongMaterial 
> {

The superclass already implements the interface, so it's redundant here.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLPhongMaterial.java 
line 43:

> 41:     private final MTLContext context;
> 42:     private final long nativeHandle;
> 43:     private TextureMap maps[] = new TextureMap[MAX_MAP_TYPE];

Can be final.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLPhongMaterial.java 
line 81:

> 79:         Texture texture = (image == null) ? null
> 80:                 : context.getResourceFactory().getCachedTexture(image, 
> Texture.WrapMode.REPEAT, useMipmap);
> 81:         long hTexture = (texture != null) ? ((MTLTexture) 
> texture).getNativeHandle() : 0;

Raw type

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLPipeline.java line 
65:

> 63:     @Override
> 64:     public boolean init() {
> 65:         Map devDetails = new HashMap();

Raw types (though the problem is upstream and really should be fixed).

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLPipeline.java line 
93:

> 91:             Map devDetails = MTLPipeline.getInstance().getDeviceDetails();
> 92:             devDetails.put("mtlCommandQueue",
> 93:                                 
> mtlResourceFactory.getContext().getMetalCommandQueue());

Raw type again, causing a warning because the compiler doesn't know if `put` is 
given valid types.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLPipeline.java line 
129:

> 127:             default:
> 128:                 return false;
> 129:         }

Can be a switch expression. Also no need for the comment because the constant 
has docs 💯 

        return switch (type) {
            case MSL -> true;
            default -> false;
        };

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLPipeline.java line 
139:

> 137:             default:
> 138:                 return false;
> 139:         }

Can be like above.

Also, can Metal really support SM3? Isn't it a D3D-only model?

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLRTTexture.java line 
39:

> 37: import com.sun.prism.mtl.MTLTexture;
> 38: import com.sun.prism.mtl.MTLTextureData;
> 39: import com.sun.prism.mtl.MTLTextureResource;

Unused

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLRTTexture.java line 
53:

> 51: 
> 52:     private boolean opaque;
> 53:     private boolean MSAA;

Can be final except for `opaque`.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLRTTexture.java line 
89:

> 87:                 wrapMode, msaa);
> 88:         MTLTextureData textData = new MTLRTTextureData(context, nPtr, 
> size);
> 89:         MTLTextureResource resource = new MTLTextureResource(textData, 
> true);

Raw type

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLRTTexture.java line 
101:

> 99: 
> 100:         MTLTextureData textData = new MTLFBOTextureData(context, nPtr, 
> size);
> 101:         MTLTextureResource resource = new MTLTextureResource(textData, 
> false);

Raw type

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLRTTexture.java line 
133:

> 131:         // In future, if needed, need to implement pix as ByteBuffer
> 132:         if (pix instanceof IntBuffer) {
> 133:             nReadPixelsFromRTT(nTexPtr, (IntBuffer)pix);

Can pattern match instead of cast.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLRTTextureData.java 
line 29:

> 27: 
> 28: public class MTLRTTextureData extends MTLTextureData {
> 29:     MTLRTTextureData(MTLContext context, long texPtr, long size) {

New line, also in other places?

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLRenderTarget.java 
line 1:

> 1: /*

Why is this interface needed if it's implemented only in 1 class and the return 
value from the method is always 0?

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 44:

> 42: import com.sun.prism.impl.TextureResourcePool;
> 43: import com.sun.prism.impl.ps.BaseShaderFactory;
> 44: import com.sun.prism.mtl.MTLContext;

Unused import

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 57:

> 55: 
> 56: public class MTLResourceFactory extends BaseShaderFactory {
> 57:     private final MTLContext context;

New line?

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 103:

> 101:             return createShader(pixelShaderName, samplers, params, 
> maxTexCoordIndex,
> 102:                                 isPixcoordUsed, isPerVertexColorUsed);
> 103:         } catch (Exception e) {

`e` is unused and can be `_` if this is correct (e.g., no 
`e.printStackTrace()`). Same in other places.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 114:

> 112:         Shader shader = MTLShader.createShader(getContext(), shaderName, 
> samplers,
> 113:                 params, maxTexCoordIndex, isPixcoordUsed, 
> isPerVertexColorUsed);
> 114:         return shader;

Can return the method result directly if you prefer.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 121:

> 119:         if (shaderName == null) {
> 120:             throw new IllegalArgumentException("Shader name must be 
> non-null");
> 121:         }

Can be `Objects.requireNonNull(shaderName, "Shader name must be non-null")` if 
an NPE acceptable instead of an IAE (I think it's better even).

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 126:

> 124:                 System.err.println("MTLResourceFactory: Prism - 
> createStockShader: " + shaderName);
> 125:             }
> 126:             Class klass = Class.forName("com.sun.prism.shader." + 
> shaderName + "_Loader");

Raw type

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 137:

> 135: 
> 136:     @Override
> 137:     public TextureResourcePool getTextureResourcePool() {

`TextureResourcePool` is a raw type.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 170:

> 168:             allocw = w;
> 169:             alloch = h;
> 170:         }

If you prefer:

        int allocw = PrismSettings.forcePow2 ? nextPowerOfTwo(w, 
Integer.MAX_VALUE) : w;
        int alloch = PrismSettings.forcePow2 ? nextPowerOfTwo(h, 
Integer.MAX_VALUE) : h;

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 176:

> 174:         int bpp = formatHint.getBytesPerPixelUnit();
> 175:         if (allocw >= (Integer.MAX_VALUE / alloch / bpp)) {
> 176:             throw new RuntimeException("Illegal texture dimensions (" + 
> allocw + "x" + alloch + ")");

Is a `RuntimeException` necessary here? Can we not recover?

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 194:

> 192: 
> 193:         MTLTextureData textData = new MTLTextureData(context, pResource, 
> size);
> 194:         MTLTextureResource resource = new MTLTextureResource(textData, 
> true);

Raw type

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 281:

> 279:     @Override
> 280:     public boolean isFormatSupported(PixelFormat format) {
> 281:         switch (format) {

I suggest an exhaustive no-default switch for enums.

        return switch (format) {
            case BYTE_RGB, BYTE_GRAY, BYTE_ALPHA, BYTE_BGRA_PRE, INT_ARGB_PRE, 
FLOAT_XYZW, BYTE_APPLE_422 -> true;
            case MULTI_YCbCr_420 -> false;
        };

You can keep the 1 constant per line formatting if you prefer.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 348:

> 346:         int createh = height;
> 347:         int cx = 0;
> 348:         int cy = 0;

Unused variables

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLResourceFactory.java 
line 353:

> 351:             createw = nextPowerOfTwo(createw, Integer.MAX_VALUE);
> 352:             createh = nextPowerOfTwo(createh, Integer.MAX_VALUE);
> 353:         }

Can be folded into a ternary in the initial assignment if you prefer.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLShader.java line 46:

> 44:     private final Map<Integer, WeakReference<Object>> textureIdRefMap = 
> new HashMap<>();
> 45: 
> 46:     private static Map<String, MTLShader> shaderMap = new HashMap<>();

Can be final.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLShader.java line 64:

> 62:     public static Shader createShader(MTLContext ctx, String 
> fragFuncName, Map<String, Integer> samplers,
> 63:                                       Map<String, Integer> params, int 
> maxTexCoordIndex,
> 64:                                       boolean isPixcoordUsed, boolean 
> isPerVertexColorUsed) {

All 4 are unused.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLShader.java line 67:

> 65:         if (shaderMap.containsKey(fragFuncName)) {
> 66:             return shaderMap.get(fragFuncName);
> 67:         } else {

`else` is not required because `if` returns. Up to you.

Can also use `Map::getOrDefault` if you want to extract the shader creation 
into a method.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLShader.java line 79:

> 77:         } else {
> 78:             return new MTLShader(ctx, fragFuncName);
> 79:         }

Can use `Map::getOrDefault`.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLShader.java line 85:

> 83:         for (Map.Entry<String, Integer> entry : samplers.entrySet()) {
> 84:             this.samplers.put(entry.getValue(), entry.getKey());
> 85:         }

Can be `samplers.forEach((key, val) -> this.samplers.put(val, key));` with 
better argument names.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLShader.java line 109:

> 107:         } else {
> 108:             return false;
> 109:         }

`return nMetalShaderRef != 0`?

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLShader.java line 117:

> 115: 
> 116:         currentEnabledShader.textureIdRefMap.put(texUnit, new 
> WeakReference(tex));
> 117:         MTLTexture mtlTex = (MTLTexture)tex;

Raw types

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLShader.java line 197:

> 195: 
> 196:     private static native long nCreateMetalShader(long context, String 
> fragFuncName);
> 197:     private static native Map  nGetUniformNameIdMap(long nMetalShader);

Raw type

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLSwapChain.java line 
30:

> 28: import com.sun.glass.ui.Screen;
> 29: import com.sun.javafx.geom.Rectangle;
> 30: import com.sun.prism.CompositeMode;

Unused

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLSwapChain.java line 
39:

> 37: public class MTLSwapChain implements MTLRenderTarget, Presentable, 
> GraphicsResource {
> 38: 
> 39:     private PresentableState pState;

final

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLSwapChain.java line 
59:

> 57:     @Override
> 58:     public boolean lockResources(PresentableState state) {
> 59: 

No need for empty line.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLSwapChain.java line 
87:

> 85:         MTLContext context = getContext();
> 86:         context.flushVertexBuffer();
> 87:         MTLGraphics g = (MTLGraphics) MTLGraphics.create(context, 
> stableBackbuffer);

Unnecessary cast

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLSwapChain.java line 
126:

> 124:     @Override
> 125:     public Graphics createGraphics() {
> 126: 

Empty line

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLSwapChain.java line 
148:

> 146:             long pTex = pState.getNativeFrameBuffer();
> 147: 
> 148:             stableBackbuffer = 
> (MTLRTTexture)MTLRTTexture.create(getContext(), pTex, w, h, 0);

Unnecessary cast

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLSwapChain.java line 
166:

> 164: 
> 165:     @Override
> 166:     public void setOpaque(boolean opaque) {

Should we warn somehow about this no-op? It could be confusing for the caller 
for this to "fail" silently.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLTexture.java line 41:

> 39: 
> 40:     private final MTLContext context;
> 41:     private long texPtr;

final

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLTexture.java line 79:

> 77: 
> 78:     // We don't handle mipmap in shared texture yet.
> 79:     private MTLTexture(MTLTexture sharedTex, WrapMode newMode) {

Raw type

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLTexture.java line 87:

> 85:     @Override
> 86:     protected Texture createSharedTexture(WrapMode newMode) {
> 87:         return new MTLTexture(this, newMode);

Raw type

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLTexture.java line 97:

> 95:                         int srcscan, boolean skipFlush) {
> 96: 
> 97:         switch (format.getDataType()) {

I would use an exhaustive switch and possibly extract each branch into a 
method. This is a big switch with sub-switches, it's easy to get lost.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLTextureData.java 
line 36:

> 34:     private long size;
> 35: 
> 36:     private MTLTextureData() {

Unused constructor. Prevents the fields from being final. Doesn't look like 
it's needed.

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLTextureResource.java 
line 32:

> 30: public class MTLTextureResource<T extends MTLTextureData> extends 
> DisposerManagedResource<T> {
> 31: 
> 32:     boolean canDispose;

private final

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLVramPool.java line 
36:

> 34:                implements TextureResourcePool<MTLTextureData> {
> 35: 
> 36:     private static MTLVramPool theInstance = new MTLVramPool();

final

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLVramPool.java line 
49:

> 47:     public long estimateTextureSize(int width, int height, PixelFormat 
> format) {
> 48:         return ((long) width) * ((long) height) *
> 49:                ((long) format.getBytesPerPixelUnit());

Unnecessary cast

modules/javafx.graphics/src/main/java/com/sun/prism/mtl/MTLVramPool.java line 
54:

> 52:     @Override
> 53:     public long estimateRTTextureSize(int width, int height, boolean 
> hasDepth) {
> 54:         // REMIND: need to deal with size of depth buffer, etc.

Is this comment supposed to go in?

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

PR Review: https://git.openjdk.org/jfx/pull/1824#pullrequestreview-3055919768
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231425136
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231643473
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231434571
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231476027
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231447687
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231481882
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231487233
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231509449
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231537374
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231566616
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231582333
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231544130
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231633067
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231635900
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231692608
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231711272
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231709236
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231731280
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231733285
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231702027
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231713202
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231716612
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231738770
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231749898
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231746162
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231757335
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231757753
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231761693
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231761972
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231763737
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231764851
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231766544
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231777814
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231779325
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231781861
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231790290
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231834264
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231836448
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231837112
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231837549
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231838620
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231840770
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231793697
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231795530
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231795928
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231802438
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231804350
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231807526
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231808072
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231809412
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231813640
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231816624
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231820659
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231824222
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231827607
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231829034
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231848617
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231846379
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231847525
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231855592
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231861918
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231863160
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231867919
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231844004
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231886182
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231887184
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231889067
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231891135
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231891964
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231893319
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231896842
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231899223
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231900351
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231900934
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231919533
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231904681
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231907827
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231911150
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231912646
PR Review Comment: https://git.openjdk.org/jfx/pull/1824#discussion_r2231913076

Reply via email to