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;
22 // Symbol definition for real
23 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) RET_TYPE (*_sym_##FUNC_NAME) PARAM_LIST;
24 #include "headers/sym.h"
28 get_env_setting(const char *name)
31 static char *fp_default = "\0";
32 fp_env = getenv(name);
33 if (fp_env == NULL) fp_env = fp_default;
38 add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
42 GLContext_List *current = NULL;
43 GLContext_List *newitm = NULL;
45 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
49 tid = get_current_thread();
52 while (current != NULL)
54 if (current->option_len == option_len &&
55 memcmp(current->option, option, option_len) == 0 &&
56 current->thread_id == tid)
58 AST(current->cstate == cstate);
61 current = current->next;
64 newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
67 ERR("Failed to create context list.\n");
71 newitm->cstate = cstate;
72 newitm->thread_id = tid;
73 newitm->option_len = option_len;
74 newitm->option = (void *)malloc(option_len);
75 memcpy(newitm->option, option, option_len);
77 if (glctx_list != NULL)
78 newitm->next = glctx_list;
99 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
105 get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
107 GLContextState *ret = NULL;
108 GLContext_List *current = NULL;
111 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
113 tid = get_current_thread();
115 current = glctx_list;
116 while (current != NULL)
118 if (current->option_len == option_len &&
119 memcmp(current->option, option, option_len) == 0 &&
120 current->thread_id == tid)
122 ret = current->cstate;
125 current = current->next;
130 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
135 remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
139 GLContext_List *olditm = NULL;
140 GLContext_List *current = NULL;
142 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
146 tid = get_current_thread();
147 current = glctx_list;
149 while (current != NULL)
151 if (current->cstate == cstate)
153 GLContext_List *nextitm = NULL;
156 olditm->next = current->next;
157 nextitm = olditm->next;
161 glctx_list = current->next;
162 nextitm = glctx_list;
170 current = current->next;
175 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
180 init_new_thread_state()
183 GLThreadState *tstate = NULL;
185 tstate = get_current_thread_state();
188 tstate = (GLThreadState *)calloc(1, sizeof(GLThreadState));
189 tstate->thread_id = get_current_thread();
190 tstate->binded_api = EGL_NONE;
192 set_current_thread_state(&ctx_list_access_mutex, tstate);
194 #ifdef COREGL_TRACE_CONTEXT_INFO
195 add_to_general_trace_list(&thread_trace_list, tstate);
196 #endif // COREGL_TRACE_CONTEXT_INFO
207 ERR("GL symbol missing!\n");
214 #define FINDSYM(libhandle, getproc, dst, sym) \
215 if ((!dst) && (getproc)) dst = (__typeof__(dst))getproc(sym); \
216 if (!dst) dst = (__typeof__(dst))dlsym(libhandle, sym);
218 #define FALLBAK(dst) \
219 if (!dst) { dst = (__typeof__(dst))_sym_missing; ERR("WARNING : symbol '"#dst"' missing!\n"); }
222 #ifndef _COREGL_DESKTOP_GL
223 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
224 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
225 if (IS_EXTENSION == GL_TRUE) { \
226 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
227 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
228 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
229 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"KHR"); \
230 } else { FALLBAK(_sym_##FUNC_NAME); }
231 # include "headers/sym_egl.h"
232 # undef _COREGL_SYMBOL
234 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
235 FINDSYM(glue_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
236 if (IS_EXTENSION == GL_TRUE) { \
237 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
238 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
239 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
240 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"MESA"); \
241 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"SGI"); \
242 } else { FALLBAK(_sym_##FUNC_NAME); }
243 # include "headers/sym_glx.h"
244 # undef _COREGL_SYMBOL
257 #define FINDSYM(libhandle, getproc, dst, sym) \
258 if ((!dst) && (getproc)) dst = (__typeof__(dst))getproc(sym); \
259 if (!dst) dst = (__typeof__(dst))dlsym(gl_lib_handle, sym);
260 #define FALLBAK(dst) \
261 if (!dst) { dst = (__typeof__(dst))_sym_missing; ERR("WARNING : symbol '"#dst"' missing!\n"); }
263 #ifndef _COREGL_DESKTOP_GL
264 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
265 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
266 if (IS_EXTENSION == GL_TRUE) { \
267 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
268 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
269 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
270 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"KHR"); \
271 } else { FALLBAK(_sym_##FUNC_NAME); }
272 # include "headers/sym_gl.h"
273 # undef _COREGL_SYMBOL
275 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
276 if (IS_EXTENSION == GL_TRUE) { \
277 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
278 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
279 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
280 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
281 } else { FALLBAK(_sym_##FUNC_NAME); }
282 # include "headers/sym_gl.h"
283 # undef _COREGL_SYMBOL
292 COREGL_API void coregl_symbol_exported()
294 LOG("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL)\E[0m\n");
301 #ifndef _COREGL_DESKTOP_GL
302 //------------------------------------------------//
303 // Open EGL Library as EGL is separate
304 #ifndef _COREGL_EMBED_EVAS
305 egl_lib_handle = dlopen("libEGL_drv.so", RTLD_NOW);
307 egl_lib_handle = dlopen("libEGL.so.1", RTLD_NOW);
309 egl_lib_handle = dlopen("libEGL.so", RTLD_NOW);
313 ERR("\E[0;31;1mERROR : %s\E[0m\n\n", dlerror());
314 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libEGL_drv)\E[0m\n");
318 // test for invalid linking egl
319 if (dlsym(egl_lib_handle, "coregl_symbol_exported"))
321 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libEGL_drv)\E[0m\n");
325 // use gl_lib handle for GL symbols
326 #ifndef _COREGL_EMBED_EVAS
327 gl_lib_handle = dlopen("libGLESv2_drv.so", RTLD_NOW);
329 gl_lib_handle = dlopen("libGLESv2.so.1", RTLD_NOW);
331 gl_lib_handle = dlopen("libGLESv2.so", RTLD_NOW);
335 ERR("\E[0;31;1mERROR : %s\E[0m\n\n", dlerror());
336 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libGLESv2_drv)\E[0m\n");
340 // test for invalid linking gl
341 if (dlsym(gl_lib_handle, "coregl_symbol_exported"))
343 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libGLESv2_drv)\E[0m\n");
346 //------------------------------------------------//
351 #ifndef _COREGL_EMBED_EVAS
352 gl_lib_handle = dlopen("libGL_drv.so", RTLD_NOW);
354 gl_lib_handle = dlopen("libGL.so.1", RTLD_NOW);
356 gl_lib_handle = dlopen("libGL.so", RTLD_NOW);
360 ERR("%s\n", dlerror());
364 //------------------------------------------------//
366 #endif // _COREGL_DESKTOP_GL
368 if (!_glue_sym_init()) return 0;
369 if (!_gl_sym_init()) return 0;
374 extern void init_fast_gl();
375 extern void init_wrap_gl();
377 #ifndef _COREGL_EMBED_EVAS
378 __attribute__((constructor))
383 int fastpath_opt = 0;
387 if (!_gl_lib_init()) return 0;
389 fastpath_opt = atoi(get_env_setting("COREGL_FASTPATH"));
391 switch (fastpath_opt)
394 api_opt = COREGL_FAST_PATH;
395 LOG(": (%d) Fastpath enabled...\n", fastpath_opt);
399 LOG(": (%d) Default API path enabled...\n", fastpath_opt);
400 api_opt = COREGL_NORMAL_PATH;
405 #ifdef COREGL_TRACE_APICALL_INFO
406 trace_api_flag = atoi(get_env_setting("COREGL_TRACE_API"));
408 #ifdef COREGL_TRACE_CONTEXT_INFO
409 trace_ctx_flag = atoi(get_env_setting("COREGL_TRACE_CTX"));
411 #ifdef COREGL_TRACE_CONTEXT_INFO
412 trace_ctx_force_flag = atoi(get_env_setting("COREGL_TRACE_CTX_FORCE"));
414 #ifdef COREGL_TRACE_STATE_INFO
415 trace_state_flag = atoi(get_env_setting("COREGL_TRACE_STATE"));
418 debug_nofp = atoi(get_env_setting("COREGL_DEBUG_NOFP"));
421 override_glue_apis(api_opt);
422 override_gl_apis(api_opt);
427 extern void free_fast_gl();
428 extern void free_wrap_gl();
430 #ifndef _COREGL_EMBED_EVAS
431 __attribute__((destructor))
436 GLContext_List *current = NULL;
440 case COREGL_FAST_PATH:
448 AST(mutex_lock(&ctx_list_access_mutex) == 1);
451 // Destroy remained context & Detect leaks
452 int retry_destroy = 0;
457 current = glctx_list;
460 if (current->cstate != NULL)
462 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);
464 #ifndef _COREGL_DESKTOP_GL
465 _sym_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
466 _sym_eglDestroyContext(current->cstate->rdpy, current->cstate->rctx);
468 _sym_glXDestroyContext(current->cstate->rdpy, current->cstate->rctx);
471 remove_context_states_from_list(current->cstate, NULL);
476 glctx_list = current->next;
478 current = glctx_list;
480 if (retry_destroy == 0) break;
484 #ifndef _COREGL_DESKTOP_GL
485 if (egl_lib_handle) dlclose(egl_lib_handle);
487 if (gl_lib_handle) dlclose(gl_lib_handle);
491 AST(mutex_unlock(&ctx_list_access_mutex) == 1);