diff options
author | Vasiliy Ulyanov <v.ulyanov@samsung.com> | 2016-03-03 18:14:47 +0300 |
---|---|---|
committer | Vasiliy Ulyanov <v.ulyanov@samsung.com> | 2016-03-11 10:44:43 +0300 |
commit | d686c16054547df09eb13df3699001df023696cc (patch) | |
tree | e2b3c260122ece04e0c05ce09a935f0cde199569 | |
parent | da44b0ee3500c970f903e461854c0389ba326643 (diff) | |
download | emulator-yagl-d686c16054547df09eb13df3699001df023696cc.tar.gz emulator-yagl-d686c16054547df09eb13df3699001df023696cc.tar.bz2 emulator-yagl-d686c16054547df09eb13df3699001df023696cc.zip |
YaGL: Fix dynamic symbols loading with coregl
EGL/GLES vendor-specific drivers are located in /usr/lib/driver
when emulator runs with coregl. This needs to be considered when
loading symbols internally.
Change-Id: I6461ead2c5d6d66cbf2cc1fd25ee53887981df8a
Signed-off-by: Vasiliy Ulyanov <v.ulyanov@samsung.com>
-rw-r--r-- | EGL/yagl_egl_state.c | 67 |
1 files changed, 52 insertions, 15 deletions
diff --git a/EGL/yagl_egl_state.c b/EGL/yagl_egl_state.c index 5baba61..3e56841 100644 --- a/EGL/yagl_egl_state.c +++ b/EGL/yagl_egl_state.c @@ -53,28 +53,38 @@ struct yagl_egl_state struct yagl_client_interface *gles1_iface; struct yagl_client_interface *gles2_iface; + + void *egl_handle; + void *gles1_handle; + void *gles2_handle; }; static pthread_key_t g_state_key; static pthread_once_t g_state_key_init = PTHREAD_ONCE_INIT; +static struct yagl_egl_state *yagl_egl_get_state(); + void *yagl_get_gles1_sym(const char *name) { - void *handle; + struct yagl_egl_state *state = yagl_egl_get_state(); void *sym = dlsym(NULL, name); if (sym) { return sym; } - handle = dlopen("libGLESv1_CM.so.1", RTLD_NOW|RTLD_GLOBAL); - if (!handle) { - handle = dlopen("libGLESv1_CM.so", RTLD_NOW|RTLD_GLOBAL); + if (!state->gles1_handle) { + state->gles1_handle = dlopen("/usr/lib/driver/libGLESv1_CM.so.1", + RTLD_NOW | RTLD_GLOBAL); + + if (!state->gles1_handle) { + state->gles1_handle = dlopen("/usr/lib/driver/libGLESv1_CM.so", + RTLD_NOW | RTLD_GLOBAL); + } } - if (handle) { - sym = dlsym(handle, name); - dlclose(handle); + if (state->gles1_handle) { + sym = dlsym(state->gles1_handle, name); return sym; } @@ -84,17 +94,21 @@ void *yagl_get_gles1_sym(const char *name) void *yagl_get_gles2_sym(const char *name) { - void *handle; + struct yagl_egl_state *state = yagl_egl_get_state(); void *sym = NULL; - handle = dlopen("libGLESv2.so.1", RTLD_NOW|RTLD_GLOBAL); - if (!handle) { - handle = dlopen("libGLESv2.so", RTLD_NOW|RTLD_GLOBAL); + if (!state->gles2_handle) { + state->gles2_handle = dlopen("/usr/lib/driver/libGLESv2.so.1", + RTLD_NOW | RTLD_GLOBAL); + + if (!state->gles2_handle) { + state->gles2_handle = dlopen("/usr/lib/driver/libGLESv2.so", + RTLD_NOW | RTLD_GLOBAL); + } } - if (handle) { - sym = dlsym(handle, name); - dlclose(handle); + if (state->gles2_handle) { + sym = dlsym(state->gles2_handle, name); } if (!sym) { @@ -118,6 +132,18 @@ static void yagl_egl_state_free(void* ptr) yagl_surface_release(state->draw_sfc); yagl_context_release(state->ctx); + if (state->gles2_handle) { + dlclose(state->gles2_handle); + } + + if (state->gles1_handle) { + dlclose(state->gles1_handle); + } + + if (state->egl_handle) { + dlclose(state->egl_handle); + } + yagl_free(state); YAGL_LOG_FUNC_EXIT(NULL); @@ -163,6 +189,17 @@ static void yagl_egl_state_init() state->error = EGL_SUCCESS; state->api = EGL_OPENGL_ES_API; + /* + * FIXME dlopen libEGL from libEGL :/ ... this is a hack to make + * yagl-specific symbols visible to GLES libraries. Coregl seems + * to load libEGL with RTLD_LOCAL flag which makes the symbols + * unavailable for subsequently loaded libraries. + * + * Perhaps common EGL/GLES code needs to be moved to a separate + * library in the future. + */ + state->egl_handle = dlopen("/usr/lib/driver/libEGL.so", + RTLD_NOW | RTLD_GLOBAL); pthread_setspecific(g_state_key, state); @@ -330,7 +367,7 @@ struct yagl_client_interface *yagl_get_client_interface(yagl_client_api client_a case yagl_client_api_gles2: case yagl_client_api_gles3: if (!state->gles2_iface) { - state->gles2_iface = yagl_get_gles1_sym("yagl_gles2_interface"); + state->gles2_iface = yagl_get_gles2_sym("yagl_gles2_interface"); } return state->gles2_iface; default: |