Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dl everything #1966

Merged
merged 3 commits into from
Sep 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app_pojavlauncher/src/main/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
# Link GLESv2 for test
LOCAL_LDLIBS := -ldl -llog -landroid -lEGL
LOCAL_LDLIBS := -ldl -llog -landroid
# -lGLESv2
LOCAL_MODULE := pojavexec
# LOCAL_CFLAGS += -DDEBUG
Expand Down
154 changes: 104 additions & 50 deletions app_pojavlauncher/src/main/jni/egl_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,8 @@ struct PotatoBridge {
};
EGLConfig config;
struct PotatoBridge potatoBridge;

/* OSMesa functions */
GLboolean (*OSMesaMakeCurrent_p) (OSMesaContext ctx, void *buffer, GLenum type,
GLsizei width, GLsizei height);
OSMesaContext (*OSMesaGetCurrentContext_p) (void);
Expand All @@ -603,6 +605,24 @@ void (*glFinish_p) (void);
void (*glClearColor_p) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
void (*glClear_p) (GLbitfield mask);

/*EGL functions */
EGLBoolean (*eglMakeCurrent_p) (EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
EGLBoolean (*eglDestroyContext_p) (EGLDisplay dpy, EGLContext ctx);
EGLBoolean (*eglDestroySurface_p) (EGLDisplay dpy, EGLSurface surface);
EGLBoolean (*eglTerminate_p) (EGLDisplay dpy);
EGLBoolean (*eglReleaseThread_p) (void);
EGLContext (*eglGetCurrentContext_p) (void);
EGLDisplay (*eglGetDisplay_p) (NativeDisplayType display);
EGLBoolean (*eglInitialize_p) (EGLDisplay dpy, EGLint *major, EGLint *minor);
EGLBoolean (*eglChooseConfig_p) (EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
EGLBoolean (*eglGetConfigAttrib_p) (EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
EGLBoolean (*eglBindAPI_p) (EGLenum api);
EGLSurface (*eglCreateWindowSurface_p) (EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
EGLBoolean (*eglSwapBuffers_p) (EGLDisplay dpy, EGLSurface draw);
EGLint (*eglGetError_p) (void);
EGLContext (*eglCreateContext_p) (EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
EGLBoolean (*eglSwapInterval_p) (EGLDisplay dpy, EGLint interval);
EGLSurface (*eglGetCurrentSurface_p) (EGLint readdraw);
#define RENDERER_GL4ES 1
#define RENDERER_VK_ZINK 2

Expand All @@ -620,11 +640,11 @@ void terminateEgl() {

switch (config_renderer) {
case RENDERER_GL4ES: {
eglMakeCurrent(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface(potatoBridge.eglDisplay, potatoBridge.eglSurface);
eglDestroyContext(potatoBridge.eglDisplay, potatoBridge.eglContext);
eglTerminate(potatoBridge.eglDisplay);
eglReleaseThread();
eglMakeCurrent_p(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroySurface_p(potatoBridge.eglDisplay, potatoBridge.eglSurface);
eglDestroyContext_p(potatoBridge.eglDisplay, potatoBridge.eglContext);
eglTerminate_p(potatoBridge.eglDisplay);
eglReleaseThread_p();

potatoBridge.eglContext = EGL_NO_CONTEXT;
potatoBridge.eglDisplay = EGL_NO_DISPLAY;
Expand All @@ -644,15 +664,71 @@ JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_setupBridgeWindow
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglGetCurrentContext(JNIEnv* env, jclass clazz) {
switch (config_renderer) {
case RENDERER_GL4ES:
return (jlong) eglGetCurrentContext();
return (jlong) eglGetCurrentContext_p();

case RENDERER_VK_ZINK:
return (jlong) OSMesaGetCurrentContext_p();

default: return (jlong) 0;
}
}
bool loadSymbols() {
char* fileName;
char* fileNameExt;
switch (config_renderer) {
case RENDERER_VK_ZINK:
fileName = "libOSMesa_8.so";
fileNameExt = "libOSMesa.so.8";
case RENDERER_GL4ES:
fileName = "libEGL.so";
char* eglLib = getenv("POJAVEXEC_EGL");
fileNameExt = eglLib == NULL?"":eglLib;
}
void* dl_handle = dlopen(fileNameExt,RTLD_NOLOAD|RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
if (!dl_handle) {
dl_handle = dlopen(fileName,RTLD_NOLOAD|RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
printf("DlLoader: using default %s\n", fileName);
} else {
printf("DlLoader: using external %s\n", fileNameExt);
}

if(dl_handle == NULL) {
printf("DlLoader: unable to load: %s\n",dlerror());
return 0;
}
switch(config_renderer) {
case RENDERER_VK_ZINK:
OSMesaMakeCurrent_p = dlsym(dl_handle,"OSMesaMakeCurrent");
OSMesaGetCurrentContext_p = dlsym(dl_handle,"OSMesaGetCurrentContext");
OSMesaCreateContext_p = dlsym(dl_handle, "OSMesaCreateContext");
OSMesaDestroyContext_p = dlsym(dl_handle, "OSMesaDestroyContext");
OSMesaPixelStore_p = dlsym(dl_handle,"OSMesaPixelStore");
glGetString_p = dlsym(dl_handle,"glGetString");
glClearColor_p = dlsym(dl_handle, "glClearColor");
glClear_p = dlsym(dl_handle,"glClear");
glFinish_p = dlsym(dl_handle,"glFinish");
break;
case RENDERER_GL4ES:
eglBindAPI_p = dlsym(dl_handle,"eglBindAPI");
eglChooseConfig_p = dlsym(dl_handle, "eglChooseConfig");
eglCreateContext_p = dlsym(dl_handle, "eglCreateContext");
eglCreateWindowSurface_p = dlsym(dl_handle, "eglCreateWindowSurface");
eglDestroyContext_p = dlsym(dl_handle, "eglDestroyContext");
eglDestroySurface_p = dlsym(dl_handle, "eglDestroySurface");
eglGetConfigAttrib_p = dlsym(dl_handle, "eglGetConfigAttrib");
eglGetCurrentContext_p = dlsym(dl_handle, "eglGetCurrentContext");
eglGetDisplay_p = dlsym(dl_handle, "eglGetDisplay");
eglGetError_p = dlsym(dl_handle, "eglGetError");
eglInitialize_p = dlsym(dl_handle, "eglInitialize");
eglMakeCurrent_p = dlsym(dl_handle, "eglMakeCurrent");
eglSwapBuffers_p = dlsym(dl_handle, "eglSwapBuffers");
eglReleaseThread_p = dlsym(dl_handle, "eglReleaseThread");
eglSwapInterval_p = dlsym(dl_handle, "eglSwapInterval");
eglTerminate_p = dlsym(dl_handle, "eglTerminate");
eglGetCurrentSurface_p = dlsym(dl_handle,"eglGetCurrentSurface");
break;
}
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglInit(JNIEnv* env, jclass clazz) {
ANativeWindow_acquire(potatoBridge.androidWindow);
savedWidth = ANativeWindow_getWidth(potatoBridge.androidWindow);
Expand All @@ -662,20 +738,20 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglInit(JNIEnv* env, j
const char *renderer = getenv("POJAV_RENDERER");
if (strncmp("opengles", renderer, 8) == 0) {
config_renderer = RENDERER_GL4ES;

loadSymbols();
if (potatoBridge.eglDisplay == NULL || potatoBridge.eglDisplay == EGL_NO_DISPLAY) {
potatoBridge.eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
potatoBridge.eglDisplay = eglGetDisplay_p(EGL_DEFAULT_DISPLAY);
if (potatoBridge.eglDisplay == EGL_NO_DISPLAY) {
printf("EGLBridge: Error eglGetDefaultDisplay() failed: %p\n", eglGetError());
printf("EGLBridge: Error eglGetDefaultDisplay() failed: %p\n", eglGetError_p());
return JNI_FALSE;
}
}

printf("EGLBridge: Initializing\n");
// printf("EGLBridge: ANativeWindow pointer = %p\n", potatoBridge.androidWindow);
//(*env)->ThrowNew(env,(*env)->FindClass(env,"java/lang/Exception"),"Trace exception");
if (!eglInitialize(potatoBridge.eglDisplay, NULL, NULL)) {
printf("EGLBridge: Error eglInitialize() failed: %s\n", eglGetError());
if (!eglInitialize_p(potatoBridge.eglDisplay, NULL, NULL)) {
printf("EGLBridge: Error eglInitialize() failed: %s\n", eglGetError_p());
return JNI_FALSE;
}

Expand All @@ -693,35 +769,35 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglInit(JNIEnv* env, j
EGLint num_configs;
EGLint vid;

if (!eglChooseConfig(potatoBridge.eglDisplay, attribs, &config, 1, &num_configs)) {
printf("EGLBridge: Error couldn't get an EGL visual config: %s\n", eglGetError());
if (!eglChooseConfig_p(potatoBridge.eglDisplay, attribs, &config, 1, &num_configs)) {
printf("EGLBridge: Error couldn't get an EGL visual config: %s\n", eglGetError_p());
return JNI_FALSE;
}

assert(config);
assert(num_configs > 0);

if (!eglGetConfigAttrib(potatoBridge.eglDisplay, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("EGLBridge: Error eglGetConfigAttrib() failed: %s\n", eglGetError());
if (!eglGetConfigAttrib_p(potatoBridge.eglDisplay, config, EGL_NATIVE_VISUAL_ID, &vid)) {
printf("EGLBridge: Error eglGetConfigAttrib() failed: %s\n", eglGetError_p());
return JNI_FALSE;
}

ANativeWindow_setBuffersGeometry(potatoBridge.androidWindow, 0, 0, vid);

eglBindAPI(EGL_OPENGL_ES_API);
eglBindAPI_p(EGL_OPENGL_ES_API);

potatoBridge.eglSurface = eglCreateWindowSurface(potatoBridge.eglDisplay, config, potatoBridge.androidWindow, NULL);
potatoBridge.eglSurface = eglCreateWindowSurface_p(potatoBridge.eglDisplay, config, potatoBridge.androidWindow, NULL);

if (!potatoBridge.eglSurface) {
printf("EGLBridge: Error eglCreateWindowSurface failed: %p\n", eglGetError());
printf("EGLBridge: Error eglCreateWindowSurface failed: %p\n", eglGetError_p());
//(*env)->ThrowNew(env,(*env)->FindClass(env,"java/lang/Exception"),"Trace exception");
return JNI_FALSE;
}

// sanity checks
{
EGLint val;
assert(eglGetConfigAttrib(potatoBridge.eglDisplay, config, EGL_SURFACE_TYPE, &val));
assert(eglGetConfigAttrib_p(potatoBridge.eglDisplay, config, EGL_SURFACE_TYPE, &val));
assert(val & EGL_WINDOW_BIT);
}

Expand All @@ -737,29 +813,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglInit(JNIEnv* env, j
config_renderer = RENDERER_VK_ZINK;

setenv("GALLIUM_DRIVER","zink",1);
void* dl_handle = dlopen("libOSMesa.so.8",RTLD_NOLOAD|RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
if (!dl_handle) {
dl_handle = dlopen("libOSMesa_8.so",RTLD_NOLOAD|RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE);
printf("OSMDroid: using built-in libOSMesa_8.so\n");
} else {
printf("OSMDroid: using developer libOSMesa.so.8 instead of built-in\n");
}

if(dl_handle == NULL) {
printf("OSMDroid: unable to load: %s\n",dlerror());
return JNI_FALSE;
}

OSMesaMakeCurrent_p = dlsym(dl_handle,"OSMesaMakeCurrent");
OSMesaGetCurrentContext_p = dlsym(dl_handle,"OSMesaGetCurrentContext");
OSMesaCreateContext_p = dlsym(dl_handle, "OSMesaCreateContext");
OSMesaDestroyContext_p = dlsym(dl_handle, "OSMesaDestroyContext");
OSMesaPixelStore_p = dlsym(dl_handle,"OSMesaPixelStore");
glGetString_p = dlsym(dl_handle,"glGetString");
glClearColor_p = dlsym(dl_handle, "glClearColor");
glClear_p = dlsym(dl_handle,"glClear");
glFinish_p = dlsym(dl_handle,"glFinish");

loadSymbols();
if(OSMesaCreateContext_p == NULL) {
printf("OSMDroid: %s\n",dlerror());
return JNI_FALSE;
Expand All @@ -785,8 +839,8 @@ bool stopSwapBuffers;
void flipFrame() {
switch (config_renderer) {
case RENDERER_GL4ES: {
if (!eglSwapBuffers(potatoBridge.eglDisplay, eglGetCurrentSurface(EGL_DRAW))) {
if (eglGetError() == EGL_BAD_SURFACE) {
if (!eglSwapBuffers_p(potatoBridge.eglDisplay, eglGetCurrentSurface_p(EGL_DRAW))) {
if (eglGetError_p() == EGL_BAD_SURFACE) {
stopSwapBuffers = true;
closeGLFWWindow();
}
Expand Down Expand Up @@ -821,7 +875,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglMakeCurrent(JNIEnv*

switch (config_renderer) {
case RENDERER_GL4ES: {
EGLContext *currCtx = eglGetCurrentContext();
EGLContext *currCtx = eglGetCurrentContext_p();
printf("EGLBridge: Comparing: thr=%d, this=%p, curr=%p\n", gettid(), window, currCtx);
if (currCtx == NULL || window == 0) {
/*if (window != 0x0 && potatoBridge.eglContextOld != NULL && potatoBridge.eglContextOld != (void *) window) {
Expand All @@ -841,14 +895,14 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglMakeCurrent(JNIEnv*
//potatoBridge.eglContextOld = (void *) window;
// eglMakeCurrent(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
printf("EGLBridge: Making current on window %p on thread %d\n", window, gettid());
EGLBoolean success = eglMakeCurrent(
EGLBoolean success = eglMakeCurrent_p(
potatoBridge.eglDisplay,
window==0 ? (EGLSurface *) 0 : potatoBridge.eglSurface,
window==0 ? (EGLSurface *) 0 : potatoBridge.eglSurface,
/* window==0 ? EGL_NO_CONTEXT : */ (EGLContext *) window
);
if (success == EGL_FALSE) {
printf("EGLBridge: Error: eglMakeCurrent() failed: %p\n", eglGetError());
printf("EGLBridge: Error: eglMakeCurrent() failed: %p\n", eglGetError_p());
} else {
printf("EGLBridge: eglMakeCurrent() succeed!\n");
}
Expand Down Expand Up @@ -904,7 +958,7 @@ Java_org_lwjgl_glfw_GLFW_nativeEglDetachOnCurrentThread(JNIEnv *env, jclass claz

switch (config_renderer) {
case RENDERER_GL4ES: {
eglMakeCurrent(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglMakeCurrent_p(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
} break;

case RENDERER_VK_ZINK: {
Expand All @@ -921,7 +975,7 @@ Java_org_lwjgl_glfw_GLFW_nativeEglCreateContext(JNIEnv *env, jclass clazz, jlong
EGL_CONTEXT_CLIENT_VERSION, atoi(getenv("LIBGL_ES")),
EGL_NONE
};
EGLContext* ctx = eglCreateContext(potatoBridge.eglDisplay, config, (void*)contextSrc, ctx_attribs);
EGLContext* ctx = eglCreateContext_p(potatoBridge.eglDisplay, config, (void*)contextSrc, ctx_attribs);

potatoBridge.eglContext = ctx;

Expand Down Expand Up @@ -967,7 +1021,7 @@ Java_org_lwjgl_opengl_GL_getNativeWidthHeight(JNIEnv *env, jobject thiz) {
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglSwapInterval(JNIEnv *env, jclass clazz, jint interval) {
switch (config_renderer) {
case RENDERER_GL4ES: {
return eglSwapInterval(potatoBridge.eglDisplay, interval);
return eglSwapInterval_p(potatoBridge.eglDisplay, interval);
} break;

case RENDERER_VK_ZINK: {
Expand Down