From 2e596cd07f1ec9d3f774f1239949db8b7e13e3e8 Mon Sep 17 00:00:00 2001 From: Maksim Belov <45949002+artdeell@users.noreply.github.com> Date: Sat, 4 Jan 2025 02:41:02 +0300 Subject: [PATCH] Fix[renderer]: move GL4ES initialization code (#6447) --- .../src/main/jni/ctxbridges/gl_bridge.c | 40 ++++++++----------- .../java/org/lwjgl/opengl/GLCapabilities.java | 2 + .../org/lwjgl/opengl/PojavRendererInit.java | 39 ++++++++++++++++++ 3 files changed, 58 insertions(+), 23 deletions(-) create mode 100644 jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PojavRendererInit.java diff --git a/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.c b/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.c index 89cc44bc7..8f6613973 100644 --- a/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.c +++ b/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.c @@ -55,25 +55,6 @@ static void gl4esi_get_display_dimensions(int* width, int* height) { *height = 0; } -static bool already_initialized = false; -static void gl_init_gl4es_internals() { - if(already_initialized) return; - already_initialized = true; - void* gl4es = dlopen("libgl4es_114.so", RTLD_NOLOAD); - if(gl4es == NULL) return; - void (*set_getmainfbsize)(void (*new_getMainFBSize)(int* width, int* height)); - set_getmainfbsize = dlsym(gl4es, "set_getmainfbsize"); - if(set_getmainfbsize == NULL) goto warn; - set_getmainfbsize(gl4esi_get_display_dimensions); - goto cleanup; - - warn: - printf("gl4esinternals warning: gl4es was found but internals not initialized. expect rendering issues.\n"); - cleanup: - // dlclose just decreases a ref counter, so this is fine - dlclose(gl4es); -} - gl_render_window_t* gl_init_context(gl_render_window_t *share) { gl_render_window_t* bundle = malloc(sizeof(gl_render_window_t)); memset(bundle, 0, sizeof(gl_render_window_t)); @@ -145,10 +126,6 @@ void gl_swap_surface(gl_render_window_t* bundle) { } void gl_make_current(gl_render_window_t* bundle) { - // Perform initialization here as the renderer may not be loaded when gl_init or gl_init_context is called. - // Yes, even though it is dlopened on MC startup by Pojav, due to linker namespacing weirdness - // on API 29/MIUI it may not be loaded at the point of the gl_init call in the current namespace. - gl_init_gl4es_internals(); if(bundle == NULL) { if(eglMakeCurrent_p(g_EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { @@ -211,3 +188,20 @@ void gl_swap_interval(int swapInterval) { eglSwapInterval_p(g_EglDisplay, swapInterval); } + +JNIEXPORT void JNICALL +Java_org_lwjgl_opengl_PojavRendererInit_nativeInitGl4esInternals(JNIEnv *env, jclass clazz, + jobject function_provider) { + __android_log_print(ANDROID_LOG_INFO, g_LogTag, "GL4ES internals initializing..."); + jclass funcProviderClass = (*env)->GetObjectClass(env, function_provider); + jmethodID method_getFunctionAddress = (*env)->GetMethodID(env, funcProviderClass, "getFunctionAddress", "(Ljava/lang/CharSequence;)J"); +#define GETSYM(N) ((*env)->CallLongMethod(env, function_provider, method_getFunctionAddress, (*env)->NewStringUTF(env, N))); + + void (*set_getmainfbsize)(void (*new_getMainFBSize)(int* width, int* height)) = (void*)GETSYM("set_getmainfbsize"); + if(set_getmainfbsize != NULL) { + __android_log_print(ANDROID_LOG_INFO, g_LogTag, "GL4ES internals initialized dimension callback"); + set_getmainfbsize(gl4esi_get_display_dimensions); + } + +#undef GETSYM +} diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLCapabilities.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLCapabilities.java index 861187a51..034e4e6bd 100644 --- a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLCapabilities.java +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/GLCapabilities.java @@ -4792,6 +4792,8 @@ public final class GLCapabilities { GLCapabilities(FunctionProvider provider, Set ext, boolean fc, IntFunction bufferFactory) { forwardCompatible = fc; + PojavRendererInit.onCreateCapabilities(provider); + PointerBuffer caps = bufferFactory.apply(ADDRESS_BUFFER_SIZE); OpenGL11 = check_GL11(provider, caps, ext, fc); diff --git a/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PojavRendererInit.java b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PojavRendererInit.java new file mode 100644 index 000000000..8a74020a7 --- /dev/null +++ b/jre_lwjgl3glfw/src/main/java/org/lwjgl/opengl/PojavRendererInit.java @@ -0,0 +1,39 @@ +package org.lwjgl.opengl; + +import org.lwjgl.system.FunctionProvider; +import org.lwjgl.system.SharedLibrary; + +import javax.annotation.Nullable; + +/** + * Class for initializing renderer-specific callbacks. Allows to reliably initialize + * any callbacks needed for renderers by using the same FunctionProvider as used for loading + * GL symbols. + * */ +public class PojavRendererInit { + + public static void onCreateCapabilities(FunctionProvider functionProvider) { + String rendererName = null; + if(functionProvider instanceof SharedLibrary) { + SharedLibrary rendererLibrary = (SharedLibrary) functionProvider; + rendererName = rendererLibrary.getName(); + } + if(!isValidString(rendererName)) { + rendererName = System.getProperty("org.lwjgl.opengl.libname"); + } + if(!isValidString(rendererName)) { + System.out.println("PojavRendererInit: Failed to find Pojav renderer name! " + + "Renderer-specific initialization may not work properly"); + } + // NOTE: hardcoded gl4es libname + if(rendererName.endsWith("libgl4es_114.so")) { + nativeInitGl4esInternals(functionProvider); + } + } + + private static boolean isValidString(@Nullable String s) { + return s != null && !s.isEmpty(); + } + + public static native void nativeInitGl4esInternals(FunctionProvider functionProvider); +}