LWJGL / lwjgl3

LWJGL is a Java library that enables cross-platform access to popular native APIs useful in the development of graphics (OpenGL, Vulkan, bgfx), audio (OpenAL, Opus), parallel computing (OpenCL, CUDA) and XR (OpenVR, LibOVR, OpenXR) applications.
https://www.lwjgl.org
BSD 3-Clause "New" or "Revised" License
4.78k stars 636 forks source link

Add support for Java array parameters #175

Closed Spasi closed 8 years ago

Spasi commented 8 years ago

The Hotspot JVM has an undocumented feature called Critical Natives, details here. It makes Java primitive arrays a viable alternative to NIO buffers and is a good match for LWJGL (virtually all JNI methods qualify, by design).

Pros:

Cons:

Questions:

ShadowLordAlpha commented 8 years ago

I would love to have this as it would make the java and c look basically identical though it is undocumented and for internal use from what I see so it could change at any time especially with jigsaw coming in 9.

Another con you forgot is that its a JDK 7 feature.

I think it would also be good to see if they actually do speed anything up so a benchmark with a few functions first or something.

octylFractal commented 8 years ago

Maybe it could be a secondary artifact, for those who know users will run on Hotspot JDK 7+ (e.g. they provide it) and want to get more speed. I could see that being very interesting for video games that bundle the JRE.

kappaOne commented 8 years ago

This looks like an awesome feature to have and would really allow clean looking LWJGL code (without the horrid NIO buffers).

Maybe LWJGL could have methods (or a utility class) that accept primitive arrays and where not supported (pretty rare situation IMO), automatically copying it to a buffer and using the buffer version of that API. Would allow users to use standard java arrays everywhere without worrying too much about compatibility.

Spasi commented 8 years ago

I think it would also be good to see if they actually do speed anything up so a benchmark with a few functions first or something.

I've actually been testing it for the last couple of days. Got incredibly excited at first, because it sounded like it would improve all JNI methods, even methods that don't use arrays. Results:

Another con you forgot is that its a JDK 7 feature.

Maybe it could be a secondary artifact, for those who know users will run on Hotspot JDK 7+

Honestly, I still hate it that LWJGL needs to be Java 6 compatible. If it were up to me, it would support Java 8 and up. Even Android supports Java 8 now. Maybe open this discussion again before the 3.0.0 release?

Maybe LWJGL could have methods (or a utility class) that accept primitive arrays and where not supported (pretty rare situation IMO), automatically copying it to a buffer and using the buffer version of that API. Would allow users to use standard java arrays everywhere without worrying too much about compatibility.

Technically possible, but would be too much code for very few (if any) users.

httpdigest commented 8 years ago

I am quite interested in this, too. Just to make sure that I would not invest time needlessly into JOML redesigning/extending it to make use of Java arrays, I would like to gather some benchmark results from users interested in using JOML with LWJGL 3. I created a small JMH benchmark project here: https://github.com/JOML-CI/joml-bench I would request for anyone interested to just download and run the prebuilt jar file and post their results into this GitHub issue. You don't have to mention your hardware stats, and also not the exact numbers if you don't want to. Just which test performed better. Higher numbers (ops/s) are better.

erodozer commented 8 years ago

I don't think it's worth pushing for something like it, since Project Panama is coming in JDK 10

If you're worried about JNI wrappers and performance, have you looked into depending on JNA. It looks like what Panama is going to be based around, and it would provide a compatible solution for older JVMs even after 10 comes out.

httpdigest commented 8 years ago

JNA is slower than using handwritten/generated JNI. JNA just allows bridging Java and native without writing native code ourselves. And that comes at a price, because the lowest denominator is just JNI. Everything wanting to bridge between Java and native has to use JNI. JNA simply has its own "hub" JNI dispatcher function and we pay the price for having JNA store the call arguments in its own data structure. Yes, it uses FFI, but that also adds to runtime.

erodozer commented 8 years ago

Ah, so does Panama's goal more or less provide what JNA's interface does, but skips the JNI step? If that's the case that'd be amazing.

Bundling a JRE with your app on desktop isn't uncommon, and is more than not recommended, especially if your app is distributed on Steam. I wonder how these changes would effect people who are trying to release apps on PS4/Xbox. I don't know what the distribution requirements are and if they have a specific requirement of what JVM to use or package. I'm afraid something like this could prevent developers from pushing their apps to those platforms if this is a change that can't be optional.

Spasi commented 8 years ago

but skips the JNI step? If that's the case that'd be amazing.

Yes and a lot more. The current prototype can even generate inline assembly using pure Java.

I'm afraid something like this could prevent developers from pushing their apps to those platforms if this is a change that can't be optional.

Using array parameters will work on any JVM. If a JVM doesn't support Critical Natives, the only difference will be a performance penalty when using such methods.

Spasi commented 8 years ago

An initial implementation is available in the array-params branch.

Spasi commented 8 years ago

Support for Hotspot Critical Natives is now available in LWJGL 3.0.0 build 77.

The current implementation does not include byte[] array overloads. They would have low usefulness and would result in a massive number of new overloads. If you have an interesting use-case for byte arrays, please post here. It would be possible to generate byte[] overloads for specific functions only.