mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-14 23:28:52 -04:00
New thing: pojav_environ
Now, instead of using a lot of env vars, we have a global thing: the pojav_environ! It provides a global storage between libraries that were loaded multiple times. Currently it is used to store config_renderer, the Pojav window and the main window bundle of gl bridge. It finally swaps surfaces on my device!
This commit is contained in:
parent
0e7d663974
commit
4841f6a4d3
@ -36,6 +36,7 @@ LOCAL_SRC_FILES := \
|
||||
ctxbridges/gl_bridge.c \
|
||||
ctxbridges/egl_loader.c \
|
||||
ctxbridges/osmesa_loader.c \
|
||||
environ/environ.c \
|
||||
input_bridge_v3.c \
|
||||
jre_launcher.c \
|
||||
utils.c
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdbool.h>
|
||||
#include <environ/environ.h>
|
||||
#include "gl_bridge.h"
|
||||
#include "egl_loader.h"
|
||||
|
||||
@ -17,9 +18,7 @@
|
||||
#define STATE_RENDERER_ALIVE 0
|
||||
#define STATE_RENDERER_NEW_WINDOW 1
|
||||
static const char* g_LogTag = "GLBridge";
|
||||
struct ANativeWindow* newWindow;
|
||||
static __thread render_window_t* currentBundle;
|
||||
static render_window_t* mainWindowBundle;
|
||||
static EGLDisplay g_EglDisplay;
|
||||
|
||||
bool gl_init() {
|
||||
@ -104,10 +103,10 @@ void gl_make_current(render_window_t* bundle) {
|
||||
return;
|
||||
}
|
||||
bool hasSetMainWindow = false;
|
||||
if(mainWindowBundle == NULL) {
|
||||
mainWindowBundle = bundle;
|
||||
__android_log_print(ANDROID_LOG_INFO, g_LogTag, "Main window bundle is now %p", mainWindowBundle);
|
||||
mainWindowBundle->newNativeSurface = newWindow;
|
||||
if(pojav_environ->mainWindowBundle == NULL) {
|
||||
pojav_environ->mainWindowBundle = bundle;
|
||||
__android_log_print(ANDROID_LOG_INFO, g_LogTag, "Main window bundle is now %p", pojav_environ->mainWindowBundle);
|
||||
pojav_environ->mainWindowBundle->newNativeSurface = pojav_environ->pojavWindow;
|
||||
hasSetMainWindow = true;
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_INFO, g_LogTag, "Making current, surface=%p, nativeSurface=%p, newNativeSurface=%p", bundle->surface, bundle->nativeSurface, bundle->newNativeSurface);
|
||||
@ -118,9 +117,9 @@ void gl_make_current(render_window_t* bundle) {
|
||||
currentBundle = bundle;
|
||||
}else {
|
||||
if(hasSetMainWindow) {
|
||||
mainWindowBundle->newNativeSurface = NULL;
|
||||
gl_swap_surface(mainWindowBundle);
|
||||
mainWindowBundle = NULL;
|
||||
pojav_environ->mainWindowBundle->newNativeSurface = NULL;
|
||||
gl_swap_surface(pojav_environ->mainWindowBundle);
|
||||
pojav_environ->mainWindowBundle = NULL;
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_ERROR, g_LogTag, "eglMakeCurrent returned with error: %04x", eglGetError_p());
|
||||
}
|
||||
@ -145,12 +144,11 @@ void gl_swap_buffers() {
|
||||
|
||||
}
|
||||
|
||||
void gl_setup_window(struct ANativeWindow* window) {
|
||||
if(mainWindowBundle != NULL) {
|
||||
mainWindowBundle->state = STATE_RENDERER_NEW_WINDOW;
|
||||
mainWindowBundle->newNativeSurface = window;
|
||||
}else{
|
||||
newWindow = window;
|
||||
void gl_setup_window() {
|
||||
if(pojav_environ->mainWindowBundle != NULL) {
|
||||
__android_log_print(ANDROID_LOG_INFO, g_LogTag, "Main window bundle is not NULL, changing state");
|
||||
pojav_environ->mainWindowBundle->state = STATE_RENDERER_NEW_WINDOW;
|
||||
pojav_environ->mainWindowBundle->newNativeSurface = pojav_environ->pojavWindow;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
//
|
||||
// Created by maks on 17.09.2022.
|
||||
//
|
||||
|
||||
#include <EGL//egl.h>
|
||||
#include <stdbool.h>
|
||||
#ifndef POJAVLAUNCHER_GL_BRIDGE_H
|
||||
#define POJAVLAUNCHER_GL_BRIDGE_H
|
||||
|
||||
@ -19,7 +20,7 @@ bool gl_init();
|
||||
render_window_t* gl_init_context(render_window_t* share);
|
||||
void gl_make_current(render_window_t* bundle);
|
||||
void gl_swap_buffers();
|
||||
void gl_setup_window(struct ANativeWindow* window);
|
||||
void gl_setup_window();
|
||||
void gl_swap_interval(int swapInterval);
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <android/native_window_jni.h>
|
||||
#include <android/rect.h>
|
||||
#include <string.h>
|
||||
#include <environ/environ.h>
|
||||
#include "utils.h"
|
||||
#include "ctxbridges/gl_bridge.h"
|
||||
// region OSMESA internals
|
||||
@ -580,7 +581,6 @@ typedef struct osmesa_context
|
||||
};
|
||||
// endregion OSMESA internals
|
||||
struct PotatoBridge {
|
||||
/*ANativeWindow */ void* androidWindow;
|
||||
|
||||
/* EGLContext */ void* eglContextOld;
|
||||
/* EGLContext */ void* eglContext;
|
||||
@ -603,7 +603,6 @@ void (*vtest_swap_buffers_p) (void);
|
||||
#define RENDERER_VK_ZINK 2
|
||||
#define RENDERER_VIRGL 3
|
||||
|
||||
int config_renderer;
|
||||
void* gbuffer;
|
||||
|
||||
void* egl_make_current(void* window);
|
||||
@ -617,7 +616,7 @@ void pojav_openGLOnUnload() {
|
||||
void pojavTerminate() {
|
||||
printf("EGLBridge: Terminating\n");
|
||||
|
||||
switch (config_renderer) {
|
||||
switch (pojav_environ->config_renderer) {
|
||||
case RENDERER_GL4ES: {
|
||||
eglMakeCurrent_p(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglDestroySurface_p(potatoBridge.eglDisplay, potatoBridge.eglSurface);
|
||||
@ -638,24 +637,20 @@ void pojavTerminate() {
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_setupBridgeWindow(JNIEnv* env, jclass clazz, jobject surface) {
|
||||
potatoBridge.androidWindow = ANativeWindow_fromSurface(env, surface);
|
||||
if(config_renderer == RENDERER_GL4ES) {
|
||||
gl_setup_window(potatoBridge.androidWindow);
|
||||
pojav_environ->pojavWindow = ANativeWindow_fromSurface(env, surface);
|
||||
if(pojav_environ->config_renderer == RENDERER_GL4ES) {
|
||||
gl_setup_window();
|
||||
}
|
||||
char *ptrStr;
|
||||
asprintf(&ptrStr, "%ld", (long) potatoBridge.androidWindow);
|
||||
setenv("POJAV_WINDOW_PTR", ptrStr, 1);
|
||||
free(ptrStr);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_net_kdt_pojavlaunch_utils_JREUtils_releaseBridgeWindow(JNIEnv *env, jclass clazz) {
|
||||
ANativeWindow_release(potatoBridge.androidWindow);
|
||||
ANativeWindow_release(pojav_environ->pojavWindow);
|
||||
}
|
||||
|
||||
void* pojavGetCurrentContext() {
|
||||
switch (config_renderer) {
|
||||
switch (pojav_environ->config_renderer) {
|
||||
case RENDERER_GL4ES:
|
||||
return (void *)eglGetCurrentContext_p();
|
||||
case RENDERER_VIRGL:
|
||||
@ -701,7 +696,7 @@ void dlsym_OSMesa(void* dl_handle) {
|
||||
}*/
|
||||
|
||||
bool loadSymbols() {
|
||||
switch (config_renderer) {
|
||||
switch (pojav_environ->config_renderer) {
|
||||
case RENDERER_VIRGL:
|
||||
dlsym_EGL();
|
||||
case RENDERER_VK_ZINK:
|
||||
@ -714,7 +709,7 @@ bool loadSymbols() {
|
||||
}
|
||||
|
||||
bool loadSymbolsVirGL() {
|
||||
config_renderer = RENDERER_VIRGL;
|
||||
pojav_environ->config_renderer = RENDERER_VIRGL;
|
||||
loadSymbols();
|
||||
|
||||
char* fileName = calloc(1, 1024);
|
||||
@ -732,16 +727,15 @@ bool loadSymbolsVirGL() {
|
||||
}
|
||||
|
||||
int pojavInit() {
|
||||
potatoBridge.androidWindow = (void *)atol(getenv("POJAV_WINDOW_PTR"));
|
||||
ANativeWindow_acquire(potatoBridge.androidWindow);
|
||||
savedWidth = ANativeWindow_getWidth(potatoBridge.androidWindow);
|
||||
savedHeight = ANativeWindow_getHeight(potatoBridge.androidWindow);
|
||||
ANativeWindow_setBuffersGeometry(potatoBridge.androidWindow,savedWidth,savedHeight,AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM);
|
||||
ANativeWindow_acquire(pojav_environ->pojavWindow);
|
||||
savedWidth = ANativeWindow_getWidth(pojav_environ->pojavWindow);
|
||||
savedHeight = ANativeWindow_getHeight(pojav_environ->pojavWindow);
|
||||
ANativeWindow_setBuffersGeometry(pojav_environ->pojavWindow,savedWidth,savedHeight,AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM);
|
||||
|
||||
// NOTE: Override for now.
|
||||
const char *renderer = getenv("POJAV_RENDERER");
|
||||
if (strncmp("opengles3_virgl", renderer, 15) == 0) {
|
||||
config_renderer = RENDERER_VIRGL;
|
||||
pojav_environ->config_renderer = RENDERER_VIRGL;
|
||||
setenv("GALLIUM_DRIVER","virpipe",1);
|
||||
setenv("OSMESA_NO_FLUSH_FRONTBUFFER","1",false);
|
||||
if(strcmp(getenv("OSMESA_NO_FLUSH_FRONTBUFFER"),"1") == 0) {
|
||||
@ -749,21 +743,21 @@ int pojavInit() {
|
||||
}
|
||||
loadSymbolsVirGL();
|
||||
} else if (strncmp("opengles", renderer, 8) == 0) {
|
||||
config_renderer = RENDERER_GL4ES;
|
||||
pojav_environ->config_renderer = RENDERER_GL4ES;
|
||||
//loadSymbols();
|
||||
} else if (strcmp(renderer, "vulkan_zink") == 0) {
|
||||
config_renderer = RENDERER_VK_ZINK;
|
||||
pojav_environ->config_renderer = RENDERER_VK_ZINK;
|
||||
setenv("GALLIUM_DRIVER","zink",1);
|
||||
loadSymbols();
|
||||
}
|
||||
if(config_renderer == RENDERER_GL4ES) {
|
||||
if(pojav_environ->config_renderer == RENDERER_GL4ES) {
|
||||
if(gl_init()) {
|
||||
gl_setup_window(potatoBridge.androidWindow);
|
||||
gl_setup_window(pojav_environ->pojavWindow);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (config_renderer == RENDERER_VIRGL) {
|
||||
if (pojav_environ->config_renderer == RENDERER_VIRGL) {
|
||||
if (potatoBridge.eglDisplay == NULL || potatoBridge.eglDisplay == EGL_NO_DISPLAY) {
|
||||
potatoBridge.eglDisplay = eglGetDisplay_p(EGL_DEFAULT_DISPLAY);
|
||||
if (potatoBridge.eglDisplay == EGL_NO_DISPLAY) {
|
||||
@ -773,7 +767,7 @@ int pojavInit() {
|
||||
}
|
||||
|
||||
printf("EGLBridge: Initializing\n");
|
||||
// printf("EGLBridge: ANativeWindow pointer = %p\n", potatoBridge.androidWindow);
|
||||
// printf("EGLBridge: ANativeWindow pointer = %p\n", pojav_environ->pojavWindow);
|
||||
//(*env)->ThrowNew(env,(*env)->FindClass(env,"java/lang/Exception"),"Trace exception");
|
||||
if (!eglInitialize_p(potatoBridge.eglDisplay, NULL, NULL)) {
|
||||
printf("EGLBridge: Error eglInitialize() failed: %s\n", eglGetError_p());
|
||||
@ -807,11 +801,11 @@ int pojavInit() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ANativeWindow_setBuffersGeometry(potatoBridge.androidWindow, 0, 0, vid);
|
||||
ANativeWindow_setBuffersGeometry(pojav_environ->pojavWindow, 0, 0, vid);
|
||||
|
||||
eglBindAPI_p(EGL_OPENGL_ES_API);
|
||||
|
||||
potatoBridge.eglSurface = eglCreateWindowSurface_p(potatoBridge.eglDisplay, config, potatoBridge.androidWindow, NULL);
|
||||
potatoBridge.eglSurface = eglCreateWindowSurface_p(potatoBridge.eglDisplay, config, pojav_environ->pojavWindow, NULL);
|
||||
|
||||
if (!potatoBridge.eglSurface) {
|
||||
printf("EGLBridge: Error eglCreateWindowSurface failed: %p\n", eglGetError_p());
|
||||
@ -833,12 +827,12 @@ int pojavInit() {
|
||||
potatoBridge.eglDisplay,
|
||||
potatoBridge.eglSurface
|
||||
);
|
||||
if (config_renderer != RENDERER_VIRGL) {
|
||||
if (pojav_environ->config_renderer != RENDERER_VIRGL) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (config_renderer == RENDERER_VIRGL) {
|
||||
if (pojav_environ->config_renderer == RENDERER_VIRGL) {
|
||||
// Init EGL context and vtest server
|
||||
const EGLint ctx_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||
@ -852,7 +846,7 @@ int pojavInit() {
|
||||
usleep(100*1000); // need enough time for the server to init
|
||||
}
|
||||
|
||||
if (config_renderer == RENDERER_VK_ZINK || config_renderer == RENDERER_VIRGL) {
|
||||
if (pojav_environ->config_renderer == RENDERER_VK_ZINK || pojav_environ->config_renderer == RENDERER_VIRGL) {
|
||||
if(OSMesaCreateContext_p == NULL) {
|
||||
printf("OSMDroid: %s\n",dlerror());
|
||||
return 0;
|
||||
@ -879,7 +873,7 @@ void pojavSwapBuffers() {
|
||||
if (stopSwapBuffers) {
|
||||
return;
|
||||
}
|
||||
switch (config_renderer) {
|
||||
switch (pojav_environ->config_renderer) {
|
||||
case RENDERER_GL4ES: {
|
||||
gl_swap_buffers();
|
||||
} break;
|
||||
@ -897,9 +891,9 @@ void pojavSwapBuffers() {
|
||||
}
|
||||
OSMesaMakeCurrent_p(ctx,buf.bits,GL_UNSIGNED_BYTE,savedWidth,savedHeight);
|
||||
glFinish_p();
|
||||
ANativeWindow_unlockAndPost(potatoBridge.androidWindow);
|
||||
ANativeWindow_unlockAndPost(pojav_environ->pojavWindow);
|
||||
//OSMesaMakeCurrent_p(ctx,gbuffer,GL_UNSIGNED_BYTE,savedWidth,savedHeight);
|
||||
ANativeWindow_lock(potatoBridge.androidWindow,&buf,NULL);
|
||||
ANativeWindow_lock(pojav_environ->pojavWindow,&buf,NULL);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
@ -918,7 +912,7 @@ void* egl_make_current(void* window) {
|
||||
printf("EGLBridge: eglMakeCurrent() succeed!\n");
|
||||
}
|
||||
|
||||
if (config_renderer == RENDERER_VIRGL) {
|
||||
if (pojav_environ->config_renderer == RENDERER_VIRGL) {
|
||||
printf("VirGL: vtest_main = %p\n", vtest_main_p);
|
||||
printf("VirGL: Calling VTest server's main function\n");
|
||||
vtest_main_p(3, (const char*[]){"vtest", "--no-loop-or-fork", "--use-gles", NULL, NULL});
|
||||
@ -931,17 +925,17 @@ void pojavMakeCurrent(void* window) {
|
||||
// printf("OSMDroid: skipped context reset\n");
|
||||
// return JNI_TRUE;
|
||||
//}
|
||||
if(config_renderer == RENDERER_GL4ES) {
|
||||
if(pojav_environ->config_renderer == RENDERER_GL4ES) {
|
||||
gl_make_current((render_window_t*)window);
|
||||
}
|
||||
if (config_renderer == RENDERER_VK_ZINK || config_renderer == RENDERER_VIRGL) {
|
||||
if (pojav_environ->config_renderer == RENDERER_VK_ZINK || pojav_environ->config_renderer == RENDERER_VIRGL) {
|
||||
printf("OSMDroid: making current\n");
|
||||
OSMesaMakeCurrent_p((OSMesaContext)window,gbuffer,GL_UNSIGNED_BYTE,savedWidth,savedHeight);
|
||||
if (config_renderer == RENDERER_VK_ZINK) {
|
||||
ANativeWindow_lock(potatoBridge.androidWindow,&buf,NULL);
|
||||
if (pojav_environ->config_renderer == RENDERER_VK_ZINK) {
|
||||
ANativeWindow_lock(pojav_environ->pojavWindow,&buf,NULL);
|
||||
OSMesaPixelStore_p(OSMESA_ROW_LENGTH,buf.stride);
|
||||
stride = buf.stride;
|
||||
//ANativeWindow_unlockAndPost(potatoBridge.androidWindow);
|
||||
//ANativeWindow_unlockAndPost(pojav_environ->pojavWindow);
|
||||
OSMesaPixelStore_p(OSMESA_Y_UP,0);
|
||||
}
|
||||
|
||||
@ -964,7 +958,7 @@ JNIEXPORT void JNICALL
|
||||
Java_org_lwjgl_glfw_GLFW_nativeEglDetachOnCurrentThread(JNIEnv *env, jclass clazz) {
|
||||
//Obstruct the context on the current thread
|
||||
|
||||
switch (config_renderer) {
|
||||
switch (pojav_environ->config_renderer) {
|
||||
case RENDERER_GL4ES: {
|
||||
eglMakeCurrent_p(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
} break;
|
||||
@ -978,7 +972,7 @@ Java_org_lwjgl_glfw_GLFW_nativeEglDetachOnCurrentThread(JNIEnv *env, jclass claz
|
||||
*/
|
||||
|
||||
void* pojavCreateContext(void* contextSrc) {
|
||||
if (config_renderer == RENDERER_GL4ES) {
|
||||
if (pojav_environ->config_renderer == RENDERER_GL4ES) {
|
||||
/*const EGLint ctx_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, atoi(getenv("LIBGL_ES")),
|
||||
EGL_NONE
|
||||
@ -991,7 +985,7 @@ void* pojavCreateContext(void* contextSrc) {
|
||||
return gl_init_context(contextSrc);
|
||||
}
|
||||
|
||||
if (config_renderer == RENDERER_VK_ZINK || config_renderer == RENDERER_VIRGL) {
|
||||
if (pojav_environ->config_renderer == RENDERER_VK_ZINK || pojav_environ->config_renderer == RENDERER_VIRGL) {
|
||||
printf("OSMDroid: generating context\n");
|
||||
void* ctx = OSMesaCreateContext_p(OSMESA_RGBA,contextSrc);
|
||||
printf("OSMDroid: context=%p\n",ctx);
|
||||
@ -1020,7 +1014,7 @@ Java_org_lwjgl_opengl_GL_getNativeWidthHeight(JNIEnv *env, jobject thiz) {
|
||||
return ret;
|
||||
}
|
||||
void pojavSwapInterval(int interval) {
|
||||
switch (config_renderer) {
|
||||
switch (pojav_environ->config_renderer) {
|
||||
case RENDERER_GL4ES: {
|
||||
gl_swap_interval(interval);
|
||||
} break;
|
||||
|
26
app_pojavlauncher/src/main/jni/environ/environ.c
Normal file
26
app_pojavlauncher/src/main/jni/environ/environ.c
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// Created by maks on 24.09.2022.
|
||||
//
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <android/log.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "environ.h"
|
||||
struct pojav_environ_s *pojav_environ;
|
||||
__attribute__((constructor)) void env_init() {
|
||||
char* strptr_env = getenv("POJAV_ENVIRON");
|
||||
if(strptr_env == NULL) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "Environ", "No environ found, creating...");
|
||||
pojav_environ = malloc(sizeof(struct pojav_environ_s));
|
||||
assert(pojav_environ);
|
||||
memset(pojav_environ, 0 , sizeof(struct pojav_environ_s));
|
||||
assert(asprintf(&strptr_env, "%p", pojav_environ) != -1);
|
||||
setenv("POJAV_ENVIRON", strptr_env, 1);
|
||||
free(strptr_env);
|
||||
}else{
|
||||
__android_log_print(ANDROID_LOG_INFO, "Environ", "Found existing environ: %s", strptr_env);
|
||||
pojav_environ = (void*) strtoul(strptr_env, NULL, 0x10);
|
||||
}
|
||||
__android_log_print(ANDROID_LOG_INFO, "Environ", "%p", pojav_environ);
|
||||
}
|
17
app_pojavlauncher/src/main/jni/environ/environ.h
Normal file
17
app_pojavlauncher/src/main/jni/environ/environ.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Created by maks on 24.09.2022.
|
||||
//
|
||||
|
||||
#ifndef POJAVLAUNCHER_ENVIRON_H
|
||||
#define POJAVLAUNCHER_ENVIRON_H
|
||||
|
||||
#include <ctxbridges/gl_bridge.h>
|
||||
|
||||
struct pojav_environ_s {
|
||||
struct ANativeWindow* pojavWindow;
|
||||
render_window_t* mainWindowBundle;
|
||||
int config_renderer;
|
||||
};
|
||||
extern struct pojav_environ_s *pojav_environ;
|
||||
|
||||
#endif //POJAVLAUNCHER_ENVIRON_H
|
Loading…
x
Reference in New Issue
Block a user