jMonkeyEngine / jmonkeyengine

A complete 3-D game development suite written in Java.
http://jmonkeyengine.org
BSD 3-Clause "New" or "Revised" License
3.78k stars 1.12k forks source link

PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION set by LwjglContext gets ignored sometimes #1822

Open Ali-RS opened 2 years ago

Ali-RS commented 2 years ago

Hi

LwjglContext (in jme3-lwjgl3 module) specifies its own implementation of buffer allocator to be used by BufferAllocatorFactory by setting PROPERTY_BUFFER_ALLOCATOR_IMPLEMENTATION property in this static code block:

https://github.com/jMonkeyEngine/jmonkeyengine/blob/8af0c92991eab9c2027dfd94be09f2170beea630/jme3-lwjgl3/src/main/java/com/jme3/system/lwjgl/LwjglContext.java#L91-L102

the issue is that sometimes this property gets ignored by BufferAllocatorFactory and a ReflectionAllocator is created instead. That is because BufferAllocatorFactory.create() method sometimes is called before the LwjglContext sets the new property. Inside the BufferUtils class:

https://github.com/jMonkeyEngine/jmonkeyengine/blob/8af0c92991eab9c2027dfd94be09f2170beea630/jme3-core/src/main/java/com/jme3/util/BufferUtils.java#L65

Sometimes the order of these static executions is different, e.g the one in the BufferUtils runs before the LwjglContext, which will cause BufferAllocator allocator to get initialized with Reflectionallocator and bypass the LWJGL3 allocator.

Edit: 2 possible fixes are suggested for this issue:

https://github.com/jMonkeyEngine/jmonkeyengine/issues/1674#issuecomment-1086843067

and:

https://github.com/jMonkeyEngine/jmonkeyengine/issues/1674#issuecomment-1129832078

Edit2: Forum topic: https://hub.jmonkeyengine.org/t/buffer-allocator-implementation-set-by-lwjglcontext-gets-ignored-sometimes/45594

Ali-RS commented 2 years ago

We might have the same issue in android OGLESContext as well:

https://github.com/jMonkeyEngine/jmonkeyengine/blob/8af0c92991eab9c2027dfd94be09f2170beea630/jme3-android/src/main/java/com/jme3/system/android/OGLESContext.java#L81-L87

Ali-RS commented 1 year ago

Put simply we can also fix it at initializer: https://start.jmonkeyengine.org

So if someone picks lwjgl3 backend the initializer should define this VM option inside applicationDefaultJvmArgs of gradle build. Easy-peasy!

'-Dcom.jme3.BufferAllocatorImplementation=com.jme3.util.LWJGLBufferAllocator$ConcurrentLWJGLBufferAllocator' 

It should be similar for android as well in which case we should set the android native allocator.

Edit: Well, not that easy! I just remembered that in the case of lwjgl3 the above line will appear wrong in the generated Linux start script. Afaik there will be a \ added before $. Not sure why!

But it can be fixed by adding this in startScripts task:

startScripts {
    doLast {
        unixScript.text  = unixScript.text.replace('LWJGLBufferAllocator\\$', 'LWJGLBufferAllocator$')
    }
}