Fix[gl_bridge]: provide implementation for gl4es_getMainFBSize (#6284)

- Fixes broken main framebuffer blits in gl4es, thus fixing 1.21.2+
This commit is contained in:
Maksim Belov 2024-11-15 23:32:37 +03:00 committed by GitHub
parent 546238663c
commit ed1b879618
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 0 deletions

View File

@ -25,6 +25,10 @@ EGLint (*eglGetError_p) (void);
EGLContext (*eglCreateContext_p) (EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list); EGLContext (*eglCreateContext_p) (EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
EGLBoolean (*eglSwapInterval_p) (EGLDisplay dpy, EGLint interval); EGLBoolean (*eglSwapInterval_p) (EGLDisplay dpy, EGLint interval);
EGLSurface (*eglGetCurrentSurface_p) (EGLint readdraw); EGLSurface (*eglGetCurrentSurface_p) (EGLint readdraw);
EGLBoolean (*eglQuerySurface_p)( EGLDisplay display,
EGLSurface surface,
EGLint attribute,
EGLint * value);
__eglMustCastToProperFunctionPointerType (*eglGetProcAddress_p) (const char *procname); __eglMustCastToProperFunctionPointerType (*eglGetProcAddress_p) (const char *procname);
bool dlsym_EGL() { bool dlsym_EGL() {
@ -53,5 +57,6 @@ bool dlsym_EGL() {
eglSwapInterval_p = (void*) eglGetProcAddress_p("eglSwapInterval"); eglSwapInterval_p = (void*) eglGetProcAddress_p("eglSwapInterval");
eglTerminate_p = (void*) eglGetProcAddress_p("eglTerminate"); eglTerminate_p = (void*) eglGetProcAddress_p("eglTerminate");
eglGetCurrentSurface_p = (void*) eglGetProcAddress_p("eglGetCurrentSurface"); eglGetCurrentSurface_p = (void*) eglGetProcAddress_p("eglGetCurrentSurface");
eglQuerySurface_p = (void*) eglGetProcAddress_p("eglQuerySurface");
return true; return true;
} }

View File

@ -24,6 +24,10 @@ extern EGLint (*eglGetError_p) (void);
extern EGLContext (*eglCreateContext_p) (EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list); extern EGLContext (*eglCreateContext_p) (EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
extern EGLBoolean (*eglSwapInterval_p) (EGLDisplay dpy, EGLint interval); extern EGLBoolean (*eglSwapInterval_p) (EGLDisplay dpy, EGLint interval);
extern EGLSurface (*eglGetCurrentSurface_p) (EGLint readdraw); extern EGLSurface (*eglGetCurrentSurface_p) (EGLint readdraw);
extern EGLBoolean (*eglQuerySurface_p)( EGLDisplay display,
EGLSurface surface,
EGLint attribute,
EGLint * value);
extern __eglMustCastToProperFunctionPointerType (*eglGetProcAddress_p) (const char *procname); extern __eglMustCastToProperFunctionPointerType (*eglGetProcAddress_p) (const char *procname);
bool dlsym_EGL(); bool dlsym_EGL();

View File

@ -39,6 +39,41 @@ gl_render_window_t* gl_get_current() {
return currentBundle; return currentBundle;
} }
static void gl4esi_get_display_dimensions(int* width, int* height) {
if(currentBundle == NULL) goto zero;
EGLSurface surface = currentBundle->surface;
// Fetch dimensions from the EGL surface - the most reliable way
EGLBoolean result_width = eglQuerySurface_p(g_EglDisplay, surface, EGL_WIDTH, width);
EGLBoolean result_height = eglQuerySurface_p(g_EglDisplay, surface, EGL_HEIGHT, height);
if(!result_width || !result_height) goto zero;
return;
zero:
// No idea what to do, but feeding gl4es incorrect or non-initialized dimensions may be
// a bad idea. Set to zero in case of errors.
*width = 0;
*height = 0;
}
static bool already_initialized = false;
static void gl_init_gl4es_internals() {
if(already_initialized) return;
already_initialized = true;
void* gl4es = dlopen("libgl4es_114.so", RTLD_NOLOAD);
if(gl4es == NULL) return;
void (*set_getmainfbsize)(void (*new_getMainFBSize)(int* width, int* height));
set_getmainfbsize = dlsym(gl4es, "set_getmainfbsize");
if(set_getmainfbsize == NULL) goto warn;
set_getmainfbsize(gl4esi_get_display_dimensions);
goto cleanup;
warn:
printf("gl4esinternals warning: gl4es was found but internals not initialized. expect rendering issues.\n");
cleanup:
// dlclose just decreases a ref counter, so this is fine
dlclose(gl4es);
}
gl_render_window_t* gl_init_context(gl_render_window_t *share) { gl_render_window_t* gl_init_context(gl_render_window_t *share) {
gl_render_window_t* bundle = malloc(sizeof(gl_render_window_t)); gl_render_window_t* bundle = malloc(sizeof(gl_render_window_t));
memset(bundle, 0, sizeof(gl_render_window_t)); memset(bundle, 0, sizeof(gl_render_window_t));
@ -110,6 +145,11 @@ void gl_swap_surface(gl_render_window_t* bundle) {
} }
void gl_make_current(gl_render_window_t* bundle) { void gl_make_current(gl_render_window_t* bundle) {
// Perform initialization here as the renderer may not be loaded when gl_init or gl_init_context is called.
// Yes, even though it is dlopened on MC startup by Pojav, due to linker namespacing weirdness
// on API 29/MIUI it may not be loaded at the point of the gl_init call in the current namespace.
gl_init_gl4es_internals();
if(bundle == NULL) { if(bundle == NULL) {
if(eglMakeCurrent_p(g_EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) { if(eglMakeCurrent_p(g_EglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
currentBundle = NULL; currentBundle = NULL;