Vulkan AWT view impossible on Mac Osx

Started by Graou, August 23, 2019, 07:11:08

Previous topic - Next topic

Graou

Hello,
I'm developing a java 3D application on Mac Osx.
I use the JDK 11 OpenJDK, JavaFx 11 for GUIs and OpenGl (Embedded JOGL Swing in JavaFx component) for 3D views.
I know that soon Mac OSx will no longer support OpenGl so I want to migrate to Vulkan.
I thought of doing this migration using lwjgl3-awt (and JAWT) but the AWTVKCanvas class does not implement Mac Osx.
Is there a solution to this problem?

KaiHH

If you mean https://github.com/LWJGLX/lwjgl3-awt then the solution is that we need someone with a Mac implementing support for Mac OS.

Graou

Yes I mean https://github.com/LWJGLX/lwjgl3-awt and I saw this need on another forum.
I have a mac and I would gladly answer this need but I'm afraid of not having the necessary knowledge.

KaiHH

If you want the implementation, you likely have to acquire the knowledge and contribute an implementation. :)

Graou

How strange, I saw this answer as clearly as a big truck. :-\
I have already started to inspect the code of lwjgl3-awt and JAWT and I agree to try this implementation.
However I am only a humble Java developer so if someone could give me clues to orient myself in my research documentation it would be a great relief.

Graou

I am since Friday on the implementation of the Mac OSX part of lwjgl3-awt. As I use the latest version of the Vulkan SDK (1.1.114.0) the VK_MVK_macos_surface extension, although supported is deprecated. MoltenVK therefore recommends the use of VK_EXT_metal_surface.
But the LWJGL3 classes corresponding to the extension VK_EXT_metal_surface do not exist. I'll have to create them, but for the new MKVMetalSurface class (the equivalent of KHRWin32Surface for Windows) I have to set the value of the VK_STRUCTURE_TYPE_* constant (the equivalent of the VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR constant for the KHRWin32Surface class).
I do not know where or how to find the value of this constant.
Does anyone know?

Graou


spasi

VK_EXT_metal_surface will be available in the next snapshot (3.2.3 build 11). Thanks!

Graou

I have a technical problem that I can not find the solution despite much research.

I want to access the bounds property of the CAMetalLayer class via org.lwjgl.system.macosx.ObjCRuntime and org.lwjgl.system.JNI but as it is a structure type return value I do not see how.

When the return value is a class, a primitive type or void, I use objc_msgSend and everything is ok. Example:
long objc_msgSend = ObjCRuntime.getLibrary().getFunctionAddress("objc_msgSend");
	long cAMetalLayerClassPtr = ObjCRuntime.objc_getClass(createCS("CAMetalLayer"));
	long cAMetalLayerInstance = ObjCRuntime.class_createInstance(cAMetalLayerClassPtr, 0L);
	long mlayermsgSend = JNI.invokePPP(cAMetalLayerInstance, sel_getUid("init"), objc_msgSend);


On the other hand, when the return value is a structure, the program crashes at the invocation of objc_msgSend_stret. And that's understandable since in XCode the use of objc_msgSend_stret is a casting of the return value.
Example Objective-c calls (that work) of objc_msgSend and then objc_msgSend_stret:
        //Create CAMetalLayer instance.
        CAMetalLayer* metalLayer = [CAMetalLayer alloc];
        //Prepare init() call.
        SEL initMethod = sel_getUid("init");
        //Define objc_msgSend pointer with id return type.
        id (*initMsg)(id inst, SEL sel) = (void*) objc_msgSend;
        //Call init() like [metalLayer init]
        metalLayer = (*initMsg)(metalLayer, initMethod);

        //Define objc_msgSend_stret pointer with CGRect return type.
        CGRect (*ptrBoundMsg)(id inst, SEL sel) = (void*) objc_msgSend_stret;
        //Prepare bounds getter call.
        SEL boundsGetter = sel_getUid("bounds");
        //Call bounds like [metalLayer bounds] : what i need in Java.
        CGRect structBounds = (*ptrBoundMsg)(metalLayer, boundsGetter);


I do not see how in Java call objc_msgSend_stret with the correct typecasting. Does someone have an idea?

I also went to the track DynCall and after a day of research I can not make a code, even very simple, that works.

spasi

I'm afraid dynamically calling functions that return or accept structs by-value is not currently possible with LWJGL. There is an API for structs in dyncall, but there's no support in the implementation. It is one reason I'm considering restoring the libffi bindings in LWJGL 3.3.

LWJGL 3.3 will also feature a new system for bindings. The org.lwjgl.system.JNI class will be removed and a new API will be available that will allow users to create custom bindings dynamically (in the same way that LWJGL will do it internally). It is very likely that structs by-value will be supported out of the box in that new API (i.e. will be simple and easy to call any function, regardless of signature). There will also be tinycc bindings available for advanced use-cases.

Graou

Okay, thank you again for your responsiveness.

I think that while waiting LWJGL 3.3 I will try to make a small temporary library to answer this need.

My short-term goal is to verify that Vulkan rendering is possible and satisfying in a JavaFx panel via AWT on Mac Osx.
Although it is a great pleasure for me to make my modest contribution to lwjgl3-awt, the issue is still something that could thwart the future of my project on Mac Osx.

spasi

A simpler approach would be adding the necessary bindings to lwjgl3 directly. Like we did recently for the CoreGraphics robot functionality. You may also be able to use Objective-C directly (let me know if the build process is giving you trouble), instead of going through the ObjC Runtime. Simply submit a PR when you have everything you need.

Instructions for building/testing locally:

export JAVA_HOME=<path to JDK 8+>
export LWJGL_BUILD_OFFLINE=true
ant compile-templates compile-native
// either use the compiled classes/dylibs directly, or
ant release -Djavadoc.skip=true // to produce the LWJGL jar files

Graou

If I understood correctly you propose to me to recover some of the sources lwjgl3 locally to integrate directly the functionalities that I need?

As a result, it can directly implement the methods in objective-c. Is it to test or to be potentially definitive because in this case is there not a problem of license with Apple?

If we are talking about the same thing, this proposal interests me.

spasi

Yes, clone and build lwjgl3 locally. Apply the changes you need, test the resulting build locally, then open a pull request so that the official build incorporates the new bindings.

There's no licensing issue. Using ObjC for ObjC APIs is simply easier/safer than doing the same thing in C with the ObjC Runtime.

Graou

I agree to try this track.

However, I think I will probably need some help. My development environments are now limited to Java, PHP, Javascript all under Eclipse. As for Objective-c, I'm just starting.

At first I will try to build lwjgl3 locally hoping to get there alone.
But I think I'll need to be guided on how to proceed. For example I see how to do the JNI with a proprietary library (even in Objective-c). But what I could explore in the inter-system exchange tools lwjgl3 seems a little too advanced for the moment.