5 #include "coregl_internal.h"
7 CoreGL_Opt_Flag api_opt = COREGL_UNKNOWN_PATH;
9 Mutex ctx_list_access_mutex = MUTEX_INITIALIZER;
14 GLContext_List *glctx_list = NULL;
16 int trace_api_flag = 0;
17 int trace_ctx_flag = 0;
18 int trace_ctx_force_flag = 0;
19 int trace_state_flag = 0;
21 FILE *trace_fp = NULL;
23 // Symbol definition for real
24 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) RET_TYPE (*_sym_##FUNC_NAME) PARAM_LIST;
25 #include "headers/sym.h"
29 get_env_setting(const char *name)
32 static char *fp_default = "\0";
33 fp_env = getenv(name);
34 if (fp_env == NULL) fp_env = fp_default;
39 add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
43 GLContext_List *current = NULL;
44 GLContext_List *newitm = NULL;
46 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
50 tid = get_current_thread();
53 while (current != NULL)
55 if (current->option_len == option_len &&
56 memcmp(current->option, option, option_len) == 0 &&
57 current->thread_id == tid)
59 AST(current->cstate == cstate);
62 current = current->next;
65 newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
68 ERR("Failed to create context list.\n");
72 newitm->cstate = cstate;
73 newitm->thread_id = tid;
74 newitm->option_len = option_len;
75 newitm->option = (void *)malloc(option_len);
76 memcpy(newitm->option, option, option_len);
78 if (glctx_list != NULL)
79 newitm->next = glctx_list;
100 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
106 get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
108 GLContextState *ret = NULL;
109 GLContext_List *current = NULL;
112 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
114 tid = get_current_thread();
116 current = glctx_list;
117 while (current != NULL)
119 if (current->option_len == option_len &&
120 memcmp(current->option, option, option_len) == 0 &&
121 current->thread_id == tid)
123 ret = current->cstate;
126 current = current->next;
131 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
136 remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
140 GLContext_List *olditm = NULL;
141 GLContext_List *current = NULL;
143 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
147 tid = get_current_thread();
148 current = glctx_list;
150 while (current != NULL)
152 if (current->cstate == cstate)
154 GLContext_List *nextitm = NULL;
157 olditm->next = current->next;
158 nextitm = olditm->next;
162 glctx_list = current->next;
163 nextitm = glctx_list;
171 current = current->next;
176 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
181 init_new_thread_state()
184 GLThreadState *tstate = NULL;
186 tstate = get_current_thread_state();
189 tstate = (GLThreadState *)calloc(1, sizeof(GLThreadState));
190 tstate->thread_id = get_current_thread();
191 tstate->binded_api = EGL_OPENGL_ES_API;
193 set_current_thread_state(&ctx_list_access_mutex, tstate);
195 #ifdef COREGL_TRACE_CONTEXT_INFO
196 add_to_general_trace_list(&thread_trace_list, tstate);
197 #endif // COREGL_TRACE_CONTEXT_INFO
208 ERR("GL symbol missing!\n");
215 #define FINDSYM(libhandle, getproc, dst, sym) \
216 if ((!dst) && (getproc)) dst = (__typeof__(dst))getproc(sym); \
217 if (!dst) dst = (__typeof__(dst))dlsym(libhandle, sym);
219 #define FALLBAK(dst) \
220 if (!dst) { dst = (__typeof__(dst))_sym_missing; ERR("WARNING : symbol '"#dst"' missing!\n"); }
223 #ifndef _COREGL_DESKTOP_GL
224 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
225 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
226 if (IS_EXTENSION == GL_TRUE) { \
227 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
228 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
229 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
230 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"KHR"); \
231 } else { FALLBAK(_sym_##FUNC_NAME); }
232 # include "headers/sym_egl.h"
233 # undef _COREGL_SYMBOL
235 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
236 FINDSYM(glue_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
237 if (IS_EXTENSION == GL_TRUE) { \
238 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
239 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
240 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
241 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"MESA"); \
242 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"SGI"); \
243 } else { FALLBAK(_sym_##FUNC_NAME); }
244 # include "headers/sym_glx.h"
245 # undef _COREGL_SYMBOL
258 #define FINDSYM(libhandle, getproc, dst, sym) \
259 if ((!dst) && (getproc)) dst = (__typeof__(dst))getproc(sym); \
260 if (!dst) dst = (__typeof__(dst))dlsym(gl_lib_handle, sym);
261 #define FALLBAK(dst) \
262 if (!dst) { dst = (__typeof__(dst))_sym_missing; ERR("WARNING : symbol '"#dst"' missing!\n"); }
264 #ifndef _COREGL_DESKTOP_GL
265 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
266 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
267 if (IS_EXTENSION == GL_TRUE) { \
268 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
269 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
270 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
271 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"KHR"); \
272 } else { FALLBAK(_sym_##FUNC_NAME); }
273 # include "headers/sym_gl.h"
274 # undef _COREGL_SYMBOL
276 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
277 if (IS_EXTENSION == GL_TRUE) { \
278 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
279 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
280 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
281 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
282 } else { FALLBAK(_sym_##FUNC_NAME); }
283 # include "headers/sym_gl.h"
284 # undef _COREGL_SYMBOL
293 COREGL_API void coregl_symbol_exported()
295 LOG("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL)\E[0m\n");
302 #ifndef _COREGL_DESKTOP_GL
303 //------------------------------------------------//
304 // Open EGL Library as EGL is separate
305 #ifndef _COREGL_EMBED_EVAS
306 egl_lib_handle = dlopen("libEGL_drv.so", RTLD_NOW);
308 egl_lib_handle = dlopen("libEGL.so.1", RTLD_NOW);
310 egl_lib_handle = dlopen("libEGL.so", RTLD_NOW);
314 ERR("\E[0;31;1mERROR : %s\E[0m\n\n", dlerror());
315 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libEGL_drv)\E[0m\n");
319 // test for invalid linking egl
320 if (dlsym(egl_lib_handle, "coregl_symbol_exported"))
322 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libEGL_drv)\E[0m\n");
326 // use gl_lib handle for GL symbols
327 #ifndef _COREGL_EMBED_EVAS
328 gl_lib_handle = dlopen("libGLESv2_drv.so", RTLD_NOW);
330 gl_lib_handle = dlopen("libGLESv2.so.1", RTLD_NOW);
332 gl_lib_handle = dlopen("libGLESv2.so", RTLD_NOW);
336 ERR("\E[0;31;1mERROR : %s\E[0m\n\n", dlerror());
337 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libGLESv2_drv)\E[0m\n");
341 // test for invalid linking gl
342 if (dlsym(gl_lib_handle, "coregl_symbol_exported"))
344 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libGLESv2_drv)\E[0m\n");
347 //------------------------------------------------//
352 #ifndef _COREGL_EMBED_EVAS
353 gl_lib_handle = dlopen("libGL_drv.so", RTLD_NOW);
355 gl_lib_handle = dlopen("libGL.so.1", RTLD_NOW);
357 gl_lib_handle = dlopen("libGL.so", RTLD_NOW);
361 ERR("%s\n", dlerror());
365 //------------------------------------------------//
367 #endif // _COREGL_DESKTOP_GL
369 if (!_glue_sym_init()) return 0;
370 if (!_gl_sym_init()) return 0;
375 extern void init_fast_gl();
376 extern void init_wrap_gl();
378 #ifndef _COREGL_EMBED_EVAS
379 __attribute__((constructor))
384 int fastpath_opt = 0;
388 if (!_gl_lib_init()) return 0;
390 fastpath_opt = atoi(get_env_setting("COREGL_FASTPATH"));
392 switch (fastpath_opt)
395 api_opt = COREGL_FAST_PATH;
396 LOG(": (%d) Fastpath enabled...\n", fastpath_opt);
400 LOG(": (%d) Default API path enabled...\n", fastpath_opt);
401 api_opt = COREGL_NORMAL_PATH;
407 const char *output_file = NULL;
408 output_file = get_env_setting("COREGL_LOG_FILE");
409 if (strlen(output_file) > 0)
411 trace_fp = fopen(output_file, "w");
413 if (trace_fp == NULL)
417 #ifdef COREGL_TRACE_APICALL_INFO
418 trace_api_flag = atoi(get_env_setting("COREGL_TRACE_API"));
420 #ifdef COREGL_TRACE_CONTEXT_INFO
421 trace_ctx_flag = atoi(get_env_setting("COREGL_TRACE_CTX"));
423 #ifdef COREGL_TRACE_CONTEXT_INFO
424 trace_ctx_force_flag = atoi(get_env_setting("COREGL_TRACE_CTX_FORCE"));
426 #ifdef COREGL_TRACE_STATE_INFO
427 trace_state_flag = atoi(get_env_setting("COREGL_TRACE_STATE"));
430 debug_nofp = atoi(get_env_setting("COREGL_DEBUG_NOFP"));
433 override_glue_apis(api_opt);
434 override_gl_apis(api_opt);
439 extern void free_fast_gl();
440 extern void free_wrap_gl();
442 #ifndef _COREGL_EMBED_EVAS
443 __attribute__((destructor))
448 GLContext_List *current = NULL;
452 case COREGL_FAST_PATH:
460 AST(mutex_lock(&ctx_list_access_mutex) == 1);
463 // Destroy remained context & Detect leaks
464 int retry_destroy = 0;
469 current = glctx_list;
472 if (current->cstate != NULL)
474 ERR("\E[0;31;1mWARNING : Context attached to [dpy=%p|rctx=%p] has not been completely destroyed.(leak)\E[0m\n", current->cstate->rdpy, current->cstate->rctx);
476 #ifndef _COREGL_DESKTOP_GL
477 _sym_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
478 _sym_eglDestroyContext(current->cstate->rdpy, current->cstate->rctx);
480 _sym_glXDestroyContext(current->cstate->rdpy, current->cstate->rctx);
483 remove_context_states_from_list(current->cstate, NULL);
488 glctx_list = current->next;
490 current = glctx_list;
492 if (retry_destroy == 0) break;
496 #ifndef _COREGL_DESKTOP_GL
497 if (egl_lib_handle) dlclose(egl_lib_handle);
499 if (gl_lib_handle) dlclose(gl_lib_handle);
503 AST(mutex_unlock(&ctx_list_access_mutex) == 1);