On Wed, 4 Nov 2020 16:14:06 GMT, Johan Vos <[email protected]> wrote:
>> Allow the EGL functionality in monocle to leverage EGL-based systems. The
>> low-level specific details about how the EGL calls should be constructed are
>> left out, and a native interface (egl_ext.h) is created that can be mapped
>> to any low-level system.
>
> Johan Vos has updated the pull request incrementally with one additional
> commit since the last revision:
>
> add one more @override to process reviewer comments
I wanted to put the EGL bridge into a library called `libglass_monocle_egl.so`
built by JavaFX, as we do for X11 and EPD, and then simply drop the custom
library that implements `egl_ext.h` into the same directory. Yet I was unable
to get `glass_monocle_egl` to resolve the symbols in my custom library at
runtime, even when both were loaded successfully.
I ended up having to build the bridge and custom implementation into one shared
library. So instead of just the `egl_ext.h` header file and my `test01.c`
source file, I required all of the following:
com_sun_glass_ui_monocle_EGLAcceleratedScreen.h
Monocle.h
egl_ext.h
eglBridge.c
test01.c
I thought it would be nice to build and load them separately, but I haven't
been able to figure it out. The code change would be something like the
following:
**EGLPlatform.java**
import com.sun.glass.utils.NativeLibLoader;
public EGLPlatform() {
String lib = System.getProperty("monocle.egl.lib");
if (lib != null) {
NativeLibLoader.loadLibrary(lib);
}
NativeLibLoader.loadLibrary("glass_monocle_egl");
}
modules/javafx.graphics/src/main/native-prism-es2/monocle/MonocleGLFactory.c
line 112:
> 110: void *handle = asPtr(libraryHandle);
> 111: if (libraryHandle == 0) {
> 112: handle = RTLD_DEFAULT;
I had to add the following two lines for the constant `RTLD_DEFAULT` when
building for ARM (`PCOMPILE_TARGETS=armv6hf`).
#define __USE_GNU
#include <dlfcn.h>
Otherwise, I got the compilation error:
MonocleGLFactory.c:112:19:
error: ‘RTLD_DEFAULT’ undeclared (first use in this function)
modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EGLPlatform.java
line 42:
> 40: }
> 41: }
> 42: }
I changed the constructor to the following:
import com.sun.glass.utils.NativeLibLoader;
public EGLPlatform() {
String lib = System.getProperty("monocle.egl.lib");
if (lib != null) {
NativeLibLoader.loadLibrary(lib);
}
}
Using the `NativeLibLoader` allowed me to define my native library with
`monocle.egl.lib=test01` (instead of `libtest01.so`) and drop it in the JavaFX
SDK with all the other JavaFX libraries. You also get good error messages when
it fails.
The current code did load the library after adding its path to the environment
variable `LD_LIBRARY_PATH`, but it failed with the following message on first
use:
java.lang.UnsatisfiedLinkError:
'long com.sun.glass.ui.monocle.EGLAcceleratedScreen
.nPlatformGetNativeWindow(java.lang.String)'
The call to `NativeLibLoader` solved these problems, with no `LD_LIBRARY_PATH`
required.
modules/javafx.graphics/src/main/java/com/sun/glass/ui/monocle/EGLAcceleratedScreen.java
line 46:
> 44: */
> 45: EGLAcceleratedScreen(int[] attributes) throws GLException {
> 46: eglWindowHandle = platformGetNativeWindow();
My IDE flags this line with "Overridable method call in constructor" (Item 19
in Bloch's *Effective Java Third Edition*): "the overriding method in the
subclass will get invoked before the subclass constructor has run."
modules/javafx.graphics/src/main/native-glass/monocle/egl/egl_ext.h line 29:
> 27: #include <jni.h>
> 28: extern long getNativeWindowHandle(const char *v);
> 29: extern long getEGLDisplayHandle();
Rename to `getEglDisplayHandle` like all the others?
modules/javafx.graphics/src/main/native-glass/monocle/egl/egl_ext.h line 32:
> 30: extern jboolean doEglInitialize(void* handle);
> 31: extern jboolean doEglBindApi(int api);
> 32: extern jlong doEglChooseConfig (long eglDisplay, int* attribs);
This function definition and the three that follow have a space before the left
parenthesis.
modules/javafx.graphics/src/main/native-glass/monocle/egl/egl_ext.h line 42:
> 40: jlong readSurface, jlong eglContext);
> 41:
> 42: extern jboolean doEglSwapBuffers(jlong eglDisplay, jlong eglSurface);
Is there a reason for using different types for the same variables in the
method definitions?
* The *window handle* is `long` and `jlong`.
* The *display handle* is `long`, `void*`, and `jlong`.
* The others (*config*, *surface*, and *context*) are all `jlong`.
-------------
PR: https://git.openjdk.java.net/jfx/pull/343