-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor: Unified egl_bridge implementation (#4816)
* Start working on bridge unification * Fin[bridge]: unified bridge structure * Fix[egl_bridge]: remove legacy functions and make initialization more early * Fix[bridge_tbl]: add forgotten gl_get_current * Clean[jre_launcher]: remove stray adrsp_test() declaration
- Loading branch information
Showing
10 changed files
with
274 additions
and
142 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// | ||
// Created by maks on 18.10.2023. | ||
// | ||
|
||
#ifndef POJAVLAUNCHER_BRIDGE_TBL_H | ||
#define POJAVLAUNCHER_BRIDGE_TBL_H | ||
|
||
#include <ctxbridges/common.h> | ||
#include <ctxbridges/gl_bridge.h> | ||
#include <ctxbridges/osm_bridge.h> | ||
|
||
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// | ||
// Created by maks on 18.10.2023. | ||
// | ||
#include <malloc.h> | ||
#include <string.h> | ||
#include <environ/environ.h> | ||
#include <android/log.h> | ||
#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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// | ||
// Created by maks on 18.10.2023. | ||
// | ||
#include <android/native_window.h> | ||
#include <stdbool.h> | ||
#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 |
Oops, something went wrong.