mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-13 06:39:54 -04:00
Feat[lwjgl]: add vulkan to lwjgl dlopen hook, move hook to new file
This commit is contained in:
parent
aadb91dc98
commit
ebe5314f28
@ -46,6 +46,7 @@ LOCAL_SRC_FILES := \
|
|||||||
utils.c \
|
utils.c \
|
||||||
stdio_is.c \
|
stdio_is.c \
|
||||||
java_exec_hooks.c \
|
java_exec_hooks.c \
|
||||||
|
lwjgl_dlopen_hook.c \
|
||||||
driver_helper/nsbypass.c
|
driver_helper/nsbypass.c
|
||||||
|
|
||||||
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
|
||||||
|
@ -258,14 +258,18 @@ EXTERNAL_API void* pojavCreateContext(void* contextSrc) {
|
|||||||
return br_init_context((basic_render_window_t*)contextSrc);
|
return br_init_context((basic_render_window_t*)contextSrc);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERNAL_API JNIEXPORT jlong JNICALL
|
void* maybe_load_vulkan() {
|
||||||
Java_org_lwjgl_vulkan_VK_getVulkanDriverHandle(ABI_COMPAT JNIEnv *env, ABI_COMPAT jclass thiz) {
|
// We use the env var because
|
||||||
printf("EGLBridge: LWJGL-side Vulkan loader requested the Vulkan handle\n");
|
|
||||||
// The code below still uses the env var because
|
|
||||||
// 1. it's easier to do that
|
// 1. it's easier to do that
|
||||||
// 2. it won't break if something will try to load vulkan and osmesa simultaneously
|
// 2. it won't break if something will try to load vulkan and osmesa simultaneously
|
||||||
if(getenv("VULKAN_PTR") == NULL) load_vulkan();
|
if(getenv("VULKAN_PTR") == NULL) load_vulkan();
|
||||||
return strtoul(getenv("VULKAN_PTR"), NULL, 0x10);
|
return (void*) strtoul(getenv("VULKAN_PTR"), NULL, 0x10);
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERNAL_API JNIEXPORT jlong JNICALL
|
||||||
|
Java_org_lwjgl_vulkan_VK_getVulkanDriverHandle(ABI_COMPAT JNIEnv *env, ABI_COMPAT jclass thiz) {
|
||||||
|
printf("EGLBridge: LWJGL-side Vulkan loader requested the Vulkan handle\n");
|
||||||
|
return (jlong) maybe_load_vulkan();
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERNAL_API void pojavSwapInterval(int interval) {
|
EXTERNAL_API void pojavSwapInterval(int interval) {
|
||||||
|
@ -228,47 +228,6 @@ void sendData(int type, int i1, int i2, int i3, int i4) {
|
|||||||
atomic_fetch_add_explicit(&pojav_environ->eventCounter, 1, memory_order_acquire);
|
atomic_fetch_add_explicit(&pojav_environ->eventCounter, 1, memory_order_acquire);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Basically a verbatim implementation of ndlopen(), found at
|
|
||||||
* https://github.com/PojavLauncherTeam/lwjgl3/blob/3.3.1/modules/lwjgl/core/src/generated/c/linux/org_lwjgl_system_linux_DynamicLinkLoader.c#L11
|
|
||||||
* The idea is that since, on Android 10 and earlier, the linker doesn't really do namespace nesting.
|
|
||||||
* It is not a problem as most of the libraries are in the launcher path, but when you try to run
|
|
||||||
* VulkanMod which loads shaderc outside of the default jni libs directory through this method,
|
|
||||||
* it can't load it because the path is not in the allowed paths for the anonymous namesapce.
|
|
||||||
* This method fixes the issue by being in libpojavexec, and thus being in the classloader namespace
|
|
||||||
*/
|
|
||||||
jlong ndlopen_bugfix(__attribute__((unused)) JNIEnv *env,
|
|
||||||
__attribute__((unused)) jclass class,
|
|
||||||
jlong filename_ptr,
|
|
||||||
jint jmode) {
|
|
||||||
const char* filename = (const char*) filename_ptr;
|
|
||||||
int mode = (int)jmode;
|
|
||||||
return (jlong) dlopen(filename, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Install the linker bug mitigation for Android 10 and lower. Fixes VulkanMod crashing on these
|
|
||||||
* Android versions due to missing namespace nesting.
|
|
||||||
*/
|
|
||||||
void installLinkerBugMitigation() {
|
|
||||||
if(android_get_device_api_level() >= 30) return;
|
|
||||||
__android_log_print(ANDROID_LOG_INFO, "Api29LinkerFix", "API < 30 detected, installing linker bug mitigation");
|
|
||||||
JNIEnv* env = pojav_environ->runtimeJNIEnvPtr_JRE;
|
|
||||||
jclass dynamicLinkLoader = (*env)->FindClass(env, "org/lwjgl/system/linux/DynamicLinkLoader");
|
|
||||||
if(dynamicLinkLoader == NULL) {
|
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "Api29LinkerFix", "Failed to find the target class");
|
|
||||||
(*env)->ExceptionClear(env);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
JNINativeMethod ndlopenMethod[] = {
|
|
||||||
{"ndlopen", "(JI)J", &ndlopen_bugfix}
|
|
||||||
};
|
|
||||||
if((*env)->RegisterNatives(env, dynamicLinkLoader, ndlopenMethod, 1) != 0) {
|
|
||||||
__android_log_print(ANDROID_LOG_ERROR, "Api29LinkerFix", "Failed to register the bugfix method");
|
|
||||||
(*env)->ExceptionClear(env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is meant as a substitute for SharedLibraryUtil.getLibraryPath() that just returns 0
|
* This function is meant as a substitute for SharedLibraryUtil.getLibraryPath() that just returns 0
|
||||||
* (thus making the parent Java function return null). This is done to avoid using the LWJGL's default function,
|
* (thus making the parent Java function return null). This is done to avoid using the LWJGL's default function,
|
||||||
|
64
app_pojavlauncher/src/main/jni/lwjgl_dlopen_hook.c
Normal file
64
app_pojavlauncher/src/main/jni/lwjgl_dlopen_hook.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//
|
||||||
|
// Created by maks on 06.01.2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <android/api-level.h>
|
||||||
|
#include <android/log.h>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
#include <environ/environ.h>
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
extern void* maybe_load_vulkan();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basically a verbatim implementation of ndlopen(), found at
|
||||||
|
* https://github.com/PojavLauncherTeam/lwjgl3/blob/3.3.1/modules/lwjgl/core/src/generated/c/linux/org_lwjgl_system_linux_DynamicLinkLoader.c#L11
|
||||||
|
* but with our own additions for stuff like vulkanmod.
|
||||||
|
*/
|
||||||
|
static jlong ndlopen_bugfix(__attribute__((unused)) JNIEnv *env,
|
||||||
|
__attribute__((unused)) jclass class,
|
||||||
|
jlong filename_ptr,
|
||||||
|
jint jmode) {
|
||||||
|
const char* filename = (const char*) filename_ptr;
|
||||||
|
|
||||||
|
// Oveeride vulkan loading to let us load vulkan ourselves
|
||||||
|
if(strstr(filename, "libvulkan.so") == filename) {
|
||||||
|
printf("LWJGL linkerhook: replacing load for libvulkan.so with custom driver\n");
|
||||||
|
return (jlong) maybe_load_vulkan();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This hook also serves the task of mitigating a bug: the idea is that since, on Android 10 and
|
||||||
|
// earlier, the linker doesn't really do namespace nesting.
|
||||||
|
// It is not a problem as most of the libraries are in the launcher path, but when you try to run
|
||||||
|
// VulkanMod which loads shaderc outside of the default jni libs directory through this method,
|
||||||
|
// it can't load it because the path is not in the allowed paths for the anonymous namesapce.
|
||||||
|
// This method fixes the issue by being in libpojavexec, and thus being in the classloader namespace
|
||||||
|
|
||||||
|
int mode = (int)jmode;
|
||||||
|
return (jlong) dlopen(filename, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install the LWJGL dlopen hook. This allows us to mitigate linker bugs and add custom library overrides.
|
||||||
|
*/
|
||||||
|
void installLinkerBugMitigation() {
|
||||||
|
__android_log_print(ANDROID_LOG_INFO, "LwjglLinkerHook", "API < 30 detected, installing linker bug mitigation");
|
||||||
|
JNIEnv* env = pojav_environ->runtimeJNIEnvPtr_JRE;
|
||||||
|
jclass dynamicLinkLoader = (*env)->FindClass(env, "org/lwjgl/system/linux/DynamicLinkLoader");
|
||||||
|
if(dynamicLinkLoader == NULL) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "LwjglLinkerHook", "Failed to find the target class");
|
||||||
|
(*env)->ExceptionClear(env);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JNINativeMethod ndlopenMethod[] = {
|
||||||
|
{"ndlopen", "(JI)J", &ndlopen_bugfix}
|
||||||
|
};
|
||||||
|
if((*env)->RegisterNatives(env, dynamicLinkLoader, ndlopenMethod, 1) != 0) {
|
||||||
|
__android_log_print(ANDROID_LOG_ERROR, "LwjglLinkerHook", "Failed to register the hooked method");
|
||||||
|
(*env)->ExceptionClear(env);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user