diff --git a/app_pojavlauncher/src/main/jni/Android.mk b/app_pojavlauncher/src/main/jni/Android.mk index dc3b31f9e..49bbc3bcc 100644 --- a/app_pojavlauncher/src/main/jni/Android.mk +++ b/app_pojavlauncher/src/main/jni/Android.mk @@ -46,6 +46,7 @@ LOCAL_SRC_FILES := \ bigcoreaffinity.c \ egl_bridge.c \ ctxbridges/gl_bridge.c \ + ctxbridges/osm_bridge.c \ ctxbridges/egl_loader.c \ ctxbridges/osmesa_loader.c \ environ/environ.c \ @@ -53,6 +54,7 @@ LOCAL_SRC_FILES := \ jre_launcher.c \ utils.c \ driver_helper/nsbypass.c + ifeq ($(TARGET_ARCH_ABI),arm64-v8a) LOCAL_CFLAGS += -DADRENO_POSSIBLE LOCAL_LDLIBS += -lEGL -lGLESv2 diff --git a/app_pojavlauncher/src/main/jni/ctxbridges/bridge_tbl.h b/app_pojavlauncher/src/main/jni/ctxbridges/bridge_tbl.h new file mode 100644 index 000000000..1683bc1ef --- /dev/null +++ b/app_pojavlauncher/src/main/jni/ctxbridges/bridge_tbl.h @@ -0,0 +1,45 @@ +// +// Created by maks on 18.10.2023. +// + +#ifndef POJAVLAUNCHER_BRIDGE_TBL_H +#define POJAVLAUNCHER_BRIDGE_TBL_H + +#include +#include +#include + +typedef basic_render_window_t* (*br_init_context_t)(basic_render_window_t* share); +typedef void (*br_make_current_t)(basic_render_window_t* bundle); +typedef basic_render_window_t* (*br_get_current_t)(); + +bool (*br_init)() = NULL; +br_init_context_t br_init_context = NULL; +br_make_current_t br_make_current = NULL; +br_get_current_t br_get_current = NULL; +void (*br_swap_buffers)() = NULL; +void (*br_setup_window)() = NULL; +void (*br_swap_interval)(int swapInterval) = NULL; + + +void set_osm_bridge_tbl() { + br_init = osm_init; + br_init_context = (br_init_context_t) osm_init_context; + br_make_current = (br_make_current_t) osm_make_current; + br_get_current = (br_get_current_t) osm_get_current; + br_swap_buffers = osm_swap_buffers; + br_setup_window = osm_setup_window; + br_swap_interval = osm_swap_interval; +} + +void set_gl_bridge_tbl() { + br_init = gl_init; + br_init_context = (br_init_context_t) gl_init_context; + br_make_current = (br_make_current_t) gl_make_current; + br_get_current = (br_get_current_t) gl_get_current; + br_swap_buffers = gl_swap_buffers; + br_setup_window = gl_setup_window; + br_swap_interval = gl_swap_interval; +} + +#endif //POJAVLAUNCHER_BRIDGE_TBL_H diff --git a/app_pojavlauncher/src/main/jni/ctxbridges/common.h b/app_pojavlauncher/src/main/jni/ctxbridges/common.h new file mode 100644 index 000000000..4fe10affe --- /dev/null +++ b/app_pojavlauncher/src/main/jni/ctxbridges/common.h @@ -0,0 +1,17 @@ +// +// Created by maks on 18.10.2023. +// + +#ifndef POJAVLAUNCHER_COMMON_H +#define POJAVLAUNCHER_COMMON_H + +#define STATE_RENDERER_ALIVE 0 +#define STATE_RENDERER_NEW_WINDOW 1 + +typedef struct { + char state; + struct ANativeWindow *nativeSurface; + struct ANativeWindow *newNativeSurface; +} basic_render_window_t; + +#endif //POJAVLAUNCHER_COMMON_H diff --git a/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.c b/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.c index c7f722fc4..a0efdd941 100644 --- a/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.c +++ b/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.c @@ -15,10 +15,8 @@ // Created by maks on 17.09.2022. // -#define STATE_RENDERER_ALIVE 0 -#define STATE_RENDERER_NEW_WINDOW 1 static const char* g_LogTag = "GLBridge"; -static __thread render_window_t* currentBundle; +static __thread gl_render_window_t* currentBundle; static EGLDisplay g_EglDisplay; bool gl_init() { @@ -37,9 +35,13 @@ bool gl_init() { return true; } -render_window_t* gl_init_context(render_window_t *share) { - render_window_t* bundle = malloc(sizeof(render_window_t)); - memset(bundle, 0, sizeof(render_window_t)); +gl_render_window_t* gl_get_current() { + return currentBundle; +} + +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)); EGLint egl_attributes[] = { EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_ALPHA_SIZE, 8, EGL_DEPTH_SIZE, 24, EGL_SURFACE_TYPE, EGL_WINDOW_BIT|EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE }; EGLint num_configs = 0; @@ -86,7 +88,7 @@ render_window_t* gl_init_context(render_window_t *share) { return bundle; } -void gl_swap_surface(render_window_t* bundle) { +void gl_swap_surface(gl_render_window_t* bundle) { if(bundle->nativeSurface != NULL) { ANativeWindow_release(bundle->nativeSurface); } @@ -107,7 +109,7 @@ void gl_swap_surface(render_window_t* bundle) { //eglMakeCurrent_p(g_EglDisplay, bundle->surface, bundle->surface, bundle->context); } -void gl_make_current(render_window_t* bundle) { +void gl_make_current(gl_render_window_t* bundle) { if(bundle == NULL) { if(eglMakeCurrent_p(g_EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { currentBundle = NULL; @@ -116,7 +118,7 @@ void gl_make_current(render_window_t* bundle) { } bool hasSetMainWindow = false; if(pojav_environ->mainWindowBundle == NULL) { - pojav_environ->mainWindowBundle = bundle; + pojav_environ->mainWindowBundle = (basic_render_window_t*)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; @@ -130,7 +132,7 @@ void gl_make_current(render_window_t* bundle) { }else { if(hasSetMainWindow) { pojav_environ->mainWindowBundle->newNativeSurface = NULL; - gl_swap_surface(pojav_environ->mainWindowBundle); + gl_swap_surface((gl_render_window_t*)pojav_environ->mainWindowBundle); pojav_environ->mainWindowBundle = NULL; } __android_log_print(ANDROID_LOG_ERROR, g_LogTag, "eglMakeCurrent returned with error: %04x", eglGetError_p()); diff --git a/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.h b/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.h index bb8fbbd47..7eef9b558 100644 --- a/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.h +++ b/app_pojavlauncher/src/main/jni/ctxbridges/gl_bridge.h @@ -8,17 +8,18 @@ typedef struct { char state; + struct ANativeWindow *nativeSurface; + struct ANativeWindow *newNativeSurface; EGLConfig config; EGLint format; EGLContext context; EGLSurface surface; - struct ANativeWindow *nativeSurface; - struct ANativeWindow *newNativeSurface; -} render_window_t; +} gl_render_window_t; bool gl_init(); -render_window_t* gl_init_context(render_window_t* share); -void gl_make_current(render_window_t* bundle); +gl_render_window_t* gl_get_current(); +gl_render_window_t* gl_init_context(gl_render_window_t* share); +void gl_make_current(gl_render_window_t* bundle); void gl_swap_buffers(); void gl_setup_window(); void gl_swap_interval(int swapInterval); diff --git a/app_pojavlauncher/src/main/jni/ctxbridges/osm_bridge.c b/app_pojavlauncher/src/main/jni/ctxbridges/osm_bridge.c new file mode 100644 index 000000000..c637d6504 --- /dev/null +++ b/app_pojavlauncher/src/main/jni/ctxbridges/osm_bridge.c @@ -0,0 +1,138 @@ +// +// Created by maks on 18.10.2023. +// +#include +#include +#include +#include +#include "osm_bridge.h" + +static const char* g_LogTag = "GLBridge"; +static __thread osm_render_window_t* currentBundle; +// a tiny buffer for rendering when there's nowhere t render +static char no_render_buffer[4]; + +bool osm_init() { + dlsym_OSMesa(); + return true; // no more specific initialization required +} + +osm_render_window_t* osm_get_current() { + return currentBundle; +} + +osm_render_window_t* osm_init_context(osm_render_window_t* share) { + osm_render_window_t* render_window = malloc(sizeof(osm_render_window_t)); + if(render_window == NULL) return NULL; + memset(render_window, 0, sizeof(osm_render_window_t)); + OSMesaContext osmesa_share = NULL; + if(share != NULL) osmesa_share = share->context; + OSMesaContext context = OSMesaCreateContext_p(GL_RGBA, osmesa_share); + if(context == NULL) { + free(render_window); + return NULL; + } + render_window->context = context; + return render_window; +} + +void osm_set_no_render_buffer(ANativeWindow_Buffer* buffer) { + buffer->bits = &no_render_buffer; + buffer->width = 1; + buffer->height = 1; + buffer->stride = 0; +} + +void osm_swap_surfaces(osm_render_window_t* bundle) { + if(bundle->nativeSurface != NULL && bundle->newNativeSurface != bundle->nativeSurface) { + if(!bundle->disable_rendering) { + __android_log_print(ANDROID_LOG_INFO, g_LogTag, "Unlocking for cleanup..."); + ANativeWindow_unlockAndPost(bundle->nativeSurface); + } + ANativeWindow_release(bundle->nativeSurface); + } + if(bundle->newNativeSurface != NULL) { + __android_log_print(ANDROID_LOG_ERROR, g_LogTag, "Switching to new native surface"); + bundle->nativeSurface = bundle->newNativeSurface; + bundle->newNativeSurface = NULL; + ANativeWindow_acquire(bundle->nativeSurface); + ANativeWindow_setBuffersGeometry(bundle->nativeSurface, 0, 0, WINDOW_FORMAT_RGBX_8888); + bundle->disable_rendering = false; + return; + }else { + __android_log_print(ANDROID_LOG_ERROR, g_LogTag, + "No new native surface, switching to dummy framebuffer"); + bundle->nativeSurface = NULL; + osm_set_no_render_buffer(&bundle->buffer); + bundle->disable_rendering = true; + } + +} + +void osm_release_window() { + currentBundle->newNativeSurface = NULL; + osm_swap_surfaces(currentBundle); +} + +void osm_apply_current_ll() { + ANativeWindow_Buffer* buffer = ¤tBundle->buffer; + OSMesaMakeCurrent_p(currentBundle->context, buffer->bits, GL_UNSIGNED_BYTE, buffer->width, buffer->height); + if(buffer->stride != currentBundle->last_stride) + OSMesaPixelStore_p(OSMESA_ROW_LENGTH, buffer->stride); + currentBundle->last_stride = buffer->stride; +} + +void osm_make_current(osm_render_window_t* bundle) { + if(bundle == NULL) { + //technically this does nothing as its not possible to unbind a context in OSMesa + OSMesaMakeCurrent_p(NULL, NULL, 0, 0, 0); + currentBundle = NULL; + return; + } + bool hasSetMainWindow = false; + currentBundle = bundle; + if(pojav_environ->mainWindowBundle == NULL) { + pojav_environ->mainWindowBundle = (basic_render_window_t*) 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; + } + if(bundle->nativeSurface == NULL) { + //prepare the buffer for our first render! + osm_swap_surfaces(bundle); + if(hasSetMainWindow) pojav_environ->mainWindowBundle->state = STATE_RENDERER_ALIVE; + } + osm_set_no_render_buffer(&bundle->buffer); + osm_apply_current_ll(); + OSMesaPixelStore_p(OSMESA_Y_UP,0); +} + +void osm_swap_buffers() { + if(currentBundle->state == STATE_RENDERER_NEW_WINDOW) { + osm_swap_surfaces(currentBundle); + currentBundle->state = STATE_RENDERER_ALIVE; + } + + if(currentBundle->nativeSurface != NULL && !currentBundle->disable_rendering) + if(ANativeWindow_lock(currentBundle->nativeSurface, ¤tBundle->buffer, NULL) != 0) + osm_release_window(); + + osm_apply_current_ll(); + glFinish_p(); // this will force osmesa to write the last rendered image into the buffer + + if(currentBundle->nativeSurface != NULL && !currentBundle->disable_rendering) + if(ANativeWindow_unlockAndPost(currentBundle->nativeSurface) != 0) + osm_release_window(); +} + +void osm_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; + } +} + +void osm_swap_interval(int swapInterval) { + // nothing, as you can only set the swap interval with internal system APIs +} \ No newline at end of file diff --git a/app_pojavlauncher/src/main/jni/ctxbridges/osm_bridge.h b/app_pojavlauncher/src/main/jni/ctxbridges/osm_bridge.h new file mode 100644 index 000000000..0fe610804 --- /dev/null +++ b/app_pojavlauncher/src/main/jni/ctxbridges/osm_bridge.h @@ -0,0 +1,29 @@ +// +// Created by maks on 18.10.2023. +// +#include +#include +#ifndef POJAVLAUNCHER_OSM_BRIDGE_H +#define POJAVLAUNCHER_OSM_BRIDGE_H +#include "osmesa_loader.h" + + +typedef struct { + char state; + struct ANativeWindow *nativeSurface; + struct ANativeWindow *newNativeSurface; + ANativeWindow_Buffer buffer; + int32_t last_stride; + bool disable_rendering; + OSMesaContext context; +} osm_render_window_t; + +bool osm_init(); +osm_render_window_t* osm_get_current(); +osm_render_window_t* osm_init_context(osm_render_window_t* share); +void osm_make_current(osm_render_window_t* bundle); +void osm_swap_buffers(); +void osm_setup_window(); +void osm_swap_interval(int swapInterval); + +#endif //POJAVLAUNCHER_OSM_BRIDGE_H diff --git a/app_pojavlauncher/src/main/jni/egl_bridge.c b/app_pojavlauncher/src/main/jni/egl_bridge.c index 704bcde91..029bdeff3 100644 --- a/app_pojavlauncher/src/main/jni/egl_bridge.c +++ b/app_pojavlauncher/src/main/jni/egl_bridge.c @@ -25,7 +25,8 @@ #include #include #include "utils.h" -#include "ctxbridges/gl_bridge.h" +#include "ctxbridges/bridge_tbl.h" +#include "ctxbridges/osm_bridge.h" #define GLFW_CLIENT_API 0x22001 /* Consider GLFW_NO_API as Vulkan API */ @@ -83,9 +84,7 @@ EXTERNAL_API void pojavTerminate() { JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_setupBridgeWindow(JNIEnv* env, ABI_COMPAT jclass clazz, jobject surface) { pojav_environ->pojavWindow = ANativeWindow_fromSurface(env, surface); - if(pojav_environ->config_renderer == RENDERER_GL4ES) { - gl_setup_window(); - } + if(br_setup_window != NULL) br_setup_window(); } @@ -95,25 +94,7 @@ Java_net_kdt_pojavlaunch_utils_JREUtils_releaseBridgeWindow(ABI_COMPAT JNIEnv *e } EXTERNAL_API void* pojavGetCurrentContext() { - switch (pojav_environ->config_renderer) { - case RENDERER_GL4ES: - return (void *)eglGetCurrentContext_p(); - case RENDERER_VK_ZINK: - return (void *)OSMesaGetCurrentContext_p(); - - default: return NULL; - } -} - -void loadSymbols() { - switch (pojav_environ->config_renderer) { - case RENDERER_VK_ZINK: - dlsym_OSMesa(); - break; - case RENDERER_GL4ES: - //inside glbridge - break; - } + return br_get_current(); } //#define ADRENO_POSSIBLE @@ -208,14 +189,6 @@ void load_vulkan() { set_vulkan_ptr(vulkan_ptr); } -EXTERNAL_API int pojavInit() { - ANativeWindow_acquire(pojav_environ->pojavWindow); - pojav_environ->savedWidth = ANativeWindow_getWidth(pojav_environ->pojavWindow); - pojav_environ->savedHeight = ANativeWindow_getHeight(pojav_environ->pojavWindow); - ANativeWindow_setBuffersGeometry(pojav_environ->pojavWindow,pojav_environ->savedWidth,pojav_environ->savedHeight,AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM); - return 1; -} - int pojavInitOpenGL() { // Only affects GL4ES as of now const char *forceVsync = getenv("FORCE_VSYNC"); @@ -226,30 +199,28 @@ int pojavInitOpenGL() { const char *renderer = getenv("POJAV_RENDERER"); if (strncmp("opengles", renderer, 8) == 0) { pojav_environ->config_renderer = RENDERER_GL4ES; - // Symbols are loaded inside gl_bridge + set_gl_bridge_tbl(); } else if (strcmp(renderer, "vulkan_zink") == 0) { pojav_environ->config_renderer = RENDERER_VK_ZINK; load_vulkan(); setenv("GALLIUM_DRIVER","zink",1); - loadSymbols(); + set_osm_bridge_tbl(); } - if(pojav_environ->config_renderer == RENDERER_GL4ES) { - if(gl_init()) { - gl_setup_window(); - return 1; - } - return 0; + if(br_init()) { + br_setup_window(); } - if (pojav_environ->config_renderer == RENDERER_VK_ZINK) { - if(OSMesaCreateContext_p == NULL) { - printf("OSMDroid: %s\n",dlerror()); - return 0; - } - } - return 0; } +EXTERNAL_API int pojavInit() { + ANativeWindow_acquire(pojav_environ->pojavWindow); + pojav_environ->savedWidth = ANativeWindow_getWidth(pojav_environ->pojavWindow); + pojav_environ->savedHeight = ANativeWindow_getHeight(pojav_environ->pojavWindow); + ANativeWindow_setBuffersGeometry(pojav_environ->pojavWindow,pojav_environ->savedWidth,pojav_environ->savedHeight,AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM); + pojavInitOpenGL(); + return 1; +} + EXTERNAL_API void pojavSetWindowHint(int hint, int value) { if (hint != GLFW_CLIENT_API) return; switch (value) { @@ -268,73 +239,20 @@ EXTERNAL_API void pojavSetWindowHint(int hint, int value) { } } -ANativeWindow_Buffer buf; -int32_t stride; -bool stopSwapBuffers; -void pojavSwapBuffers() { - if (stopSwapBuffers) { - return; - } - switch (pojav_environ->config_renderer) { - case RENDERER_GL4ES: { - gl_swap_buffers(); - } break; - - case RENDERER_VK_ZINK: { - OSMesaContext ctx = OSMesaGetCurrentContext_p(); - if(ctx == NULL) { - printf("Zink: attempted to swap buffers without context!"); - break; - } - OSMesaMakeCurrent_p(ctx,buf.bits,GL_UNSIGNED_BYTE,pojav_environ->savedWidth, pojav_environ->savedHeight); - glFinish_p(); - ANativeWindow_unlockAndPost(pojav_environ->pojavWindow); - ANativeWindow_lock(pojav_environ->pojavWindow,&buf,NULL); - } break; - } +EXTERNAL_API void pojavSwapBuffers() { + br_swap_buffers(); } EXTERNAL_API void pojavMakeCurrent(void* window) { - if(pojav_environ->config_renderer == RENDERER_GL4ES) { - gl_make_current((render_window_t*)window); - } - if (pojav_environ->config_renderer == RENDERER_VK_ZINK) { - printf("OSMDroid: making current %p\n", pojav_environ->pojavWindow); - ANativeWindow_lock(pojav_environ->pojavWindow,&buf,NULL); - OSMesaMakeCurrent_p((OSMesaContext)window,buf.bits,GL_UNSIGNED_BYTE,pojav_environ->savedWidth,pojav_environ->savedHeight); - OSMesaPixelStore_p(OSMESA_ROW_LENGTH,buf.stride); - OSMesaPixelStore_p(OSMESA_Y_UP,0); - - - printf("OSMDroid: vendor: %s\n",glGetString_p(GL_VENDOR)); - printf("OSMDroid: renderer: %s\n",glGetString_p(GL_RENDERER)); - glClearColor_p(0.4f, 0.4f, 0.4f, 1.0f); - glClear_p(GL_COLOR_BUFFER_BIT); - - pojavSwapBuffers(); - } + br_make_current((basic_render_window_t*)window); } EXTERNAL_API void* pojavCreateContext(void* contextSrc) { if (pojav_environ->config_renderer == RENDERER_VULKAN) { - return (void *)pojav_environ->pojavWindow; + return (void *) pojav_environ->pojavWindow; } - - pojavInitOpenGL(); - - if (pojav_environ->config_renderer == RENDERER_GL4ES) { - return gl_init_context(contextSrc); - } - - if (pojav_environ->config_renderer == RENDERER_VK_ZINK) { - printf("OSMDroid: generating context\n"); - void* ctx = OSMesaCreateContext_p(OSMESA_RGBA,contextSrc); - printf("OSMDroid: context=%p\n",ctx); - return ctx; - } - printf("Unknown config_renderer value: %i\n", pojav_environ->config_renderer); - abort(); + return br_init_context((basic_render_window_t*)contextSrc); } EXTERNAL_API JNIEXPORT jlong JNICALL @@ -347,27 +265,7 @@ Java_org_lwjgl_vulkan_VK_getVulkanDriverHandle(ABI_COMPAT JNIEnv *env, ABI_COMPA return strtoul(getenv("VULKAN_PTR"), NULL, 0x10); } -EXTERNAL_API JNIEXPORT jlong JNICALL -Java_org_lwjgl_opengl_GL_getGraphicsBufferAddr(ABI_COMPAT JNIEnv *env, ABI_COMPAT jobject thiz) { - return (jlong) buf.bits; -} -EXTERNAL_API JNIEXPORT jintArray JNICALL -Java_org_lwjgl_opengl_GL_getNativeWidthHeight(JNIEnv *env, ABI_COMPAT jobject thiz) { - jintArray ret = (*env)->NewIntArray(env,2); - jint arr[] = {pojav_environ->savedWidth, pojav_environ->savedHeight}; - (*env)->SetIntArrayRegion(env,ret,0,2,arr); - return ret; -} EXTERNAL_API void pojavSwapInterval(int interval) { - switch (pojav_environ->config_renderer) { - case RENDERER_GL4ES: { - gl_swap_interval(interval); - } break; - - case RENDERER_VK_ZINK: { - printf("eglSwapInterval: NOT IMPLEMENTED YET!\n"); - // Nothing to do here - } break; - } + br_swap_interval(interval); } diff --git a/app_pojavlauncher/src/main/jni/environ/environ.h b/app_pojavlauncher/src/main/jni/environ/environ.h index cad93f933..c49ff8aab 100644 --- a/app_pojavlauncher/src/main/jni/environ/environ.h +++ b/app_pojavlauncher/src/main/jni/environ/environ.h @@ -5,7 +5,7 @@ #ifndef POJAVLAUNCHER_ENVIRON_H #define POJAVLAUNCHER_ENVIRON_H -#include +#include #include #include @@ -32,7 +32,7 @@ typedef void GLFW_invoke_WindowSize_func(void* window, int width, int height); struct pojav_environ_s { struct ANativeWindow* pojavWindow; - render_window_t* mainWindowBundle; + basic_render_window_t* mainWindowBundle; int config_renderer; bool force_vsync; atomic_size_t eventCounter; // Count the number of events to be pumped out diff --git a/jre_lwjgl3glfw/libs/lwjgl-opengl.jar b/jre_lwjgl3glfw/libs/lwjgl-opengl.jar index 2350a2123..a8eda9d0c 100644 Binary files a/jre_lwjgl3glfw/libs/lwjgl-opengl.jar and b/jre_lwjgl3glfw/libs/lwjgl-opengl.jar differ