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_state_flag = 0;
21 // Symbol definition for real
22 #define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) RET_TYPE (*_sym_##FUNC_NAME) PARAM_LIST;
23 #include "headers/sym.h"
27 get_env_setting(const char *name)
30 static char *fp_default = "\0";
31 fp_env = getenv(name);
32 if (fp_env == NULL) fp_env = fp_default;
37 add_context_state_to_list(const void *option, const int option_len, GLContextState *cstate, Mutex *mtx)
41 GLContext_List *current = NULL;
42 GLContext_List *newitm = NULL;
44 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
48 tid = get_current_thread();
51 while (current != NULL)
53 if (current->option_len == option_len &&
54 memcmp(current->option, option, option_len) == 0 &&
55 current->thread_id == tid)
57 AST(current->cstate == cstate);
60 current = current->next;
63 newitm = (GLContext_List *)calloc(1, sizeof(GLContext_List));
66 ERR("Failed to create context list.\n");
70 newitm->cstate = cstate;
71 newitm->thread_id = tid;
72 newitm->option_len = option_len;
73 newitm->option = (void *)malloc(option_len);
74 memcpy(newitm->option, option, option_len);
76 if (glctx_list != NULL)
77 newitm->next = glctx_list;
98 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
104 get_context_state_from_list(const void *option, const int option_len, Mutex *mtx)
106 GLContextState *ret = NULL;
107 GLContext_List *current = NULL;
110 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
112 tid = get_current_thread();
114 current = glctx_list;
115 while (current != NULL)
117 if (current->option_len == option_len &&
118 memcmp(current->option, option, option_len) == 0 &&
119 current->thread_id == tid)
121 ret = current->cstate;
124 current = current->next;
129 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
134 remove_context_states_from_list(GLContextState *cstate, Mutex *mtx)
138 GLContext_List *olditm = NULL;
139 GLContext_List *current = NULL;
141 if (mtx != NULL) AST(mutex_lock(mtx) == 1);
145 tid = get_current_thread();
146 current = glctx_list;
148 while (current != NULL)
150 if (current->cstate == cstate)
152 GLContext_List *nextitm = NULL;
155 olditm->next = current->next;
156 nextitm = olditm->next;
160 glctx_list = current->next;
161 nextitm = glctx_list;
169 current = current->next;
174 if (mtx != NULL) AST(mutex_unlock(mtx) == 1);
179 init_new_thread_state()
182 GLThreadState *tstate = NULL;
184 tstate = get_current_thread_state();
187 tstate = (GLThreadState *)calloc(1, sizeof(GLThreadState));
188 tstate->thread_id = get_current_thread();
189 tstate->binded_api = EGL_NONE;
191 set_current_thread_state(&ctx_list_access_mutex, tstate);
193 #ifdef COREGL_TRACE_CONTEXT_INFO
194 add_to_general_trace_list(&thread_trace_list, tstate);
195 #endif // COREGL_TRACE_CONTEXT_INFO
206 ERR("GL symbol missing!\n");
213 #define FINDSYM(libhandle, getproc, dst, sym) \
214 if ((!dst) && (getproc)) dst = (__typeof__(dst))getproc(sym); \
215 if (!dst) dst = (__typeof__(dst))dlsym(libhandle, sym);
217 #define FALLBAK(dst) \
218 if (!dst) { dst = (__typeof__(dst))_sym_missing; ERR("WARNING : symbol '"#dst"' missing!\n"); }
221 #ifndef _COREGL_DESKTOP_GL
222 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
223 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
224 if (IS_EXTENSION == GL_TRUE) { \
225 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
226 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
227 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
228 FINDSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"KHR"); \
229 } else { FALLBAK(_sym_##FUNC_NAME); }
230 # include "headers/sym_egl.h"
231 # undef _COREGL_SYMBOL
233 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
234 FINDSYM(glue_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
235 if (IS_EXTENSION == GL_TRUE) { \
236 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
237 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
238 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
239 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"MESA"); \
240 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"SGI"); \
241 } else { FALLBAK(_sym_##FUNC_NAME); }
242 # include "headers/sym_glx.h"
243 # undef _COREGL_SYMBOL
256 #define FINDSYM(libhandle, getproc, dst, sym) \
257 if ((!dst) && (getproc)) dst = (__typeof__(dst))getproc(sym); \
258 if (!dst) dst = (__typeof__(dst))dlsym(gl_lib_handle, sym);
259 #define FALLBAK(dst) \
260 if (!dst) { dst = (__typeof__(dst))_sym_missing; ERR("WARNING : symbol '"#dst"' missing!\n"); }
262 #ifndef _COREGL_DESKTOP_GL
263 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
264 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
265 if (IS_EXTENSION == GL_TRUE) { \
266 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
267 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
268 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
269 FINDSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"KHR"); \
270 } else { FALLBAK(_sym_##FUNC_NAME); }
271 # include "headers/sym_gl.h"
272 # undef _COREGL_SYMBOL
274 # define _COREGL_SYMBOL(IS_EXTENSION, RET_TYPE, FUNC_NAME, PARAM_LIST) \
275 if (IS_EXTENSION == GL_TRUE) { \
276 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME); \
277 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"EXT"); \
278 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"ARB"); \
279 FINDSYM(gl_lib_handle, _sym_glXGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME"OES"); \
280 } else { FALLBAK(_sym_##FUNC_NAME); }
281 # include "headers/sym_gl.h"
282 # undef _COREGL_SYMBOL
291 COREGL_API void coregl_symbol_exported()
293 LOG("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL)\E[0m\n");
300 #ifndef _COREGL_DESKTOP_GL
301 //------------------------------------------------//
302 // Open EGL Library as EGL is separate
303 #ifndef _COREGL_EMBED_EVAS
304 egl_lib_handle = dlopen("libEGL_drv.so", RTLD_NOW);
306 egl_lib_handle = dlopen("libEGL.so.1", RTLD_NOW);
308 egl_lib_handle = dlopen("libEGL.so", RTLD_NOW);
312 ERR("\E[0;31;1mERROR : %s\E[0m\n\n", dlerror());
313 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libEGL_drv)\E[0m\n");
317 // test for invalid linking egl
318 if (dlsym(egl_lib_handle, "coregl_symbol_exported"))
320 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libEGL_drv)\E[0m\n");
324 // use gl_lib handle for GL symbols
325 #ifndef _COREGL_EMBED_EVAS
326 gl_lib_handle = dlopen("libGLESv2_drv.so", RTLD_NOW);
328 gl_lib_handle = dlopen("libGLESv2.so.1", RTLD_NOW);
330 gl_lib_handle = dlopen("libGLESv2.so", RTLD_NOW);
334 ERR("\E[0;31;1mERROR : %s\E[0m\n\n", dlerror());
335 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libGLESv2_drv)\E[0m\n");
339 // test for invalid linking gl
340 if (dlsym(gl_lib_handle, "coregl_symbol_exported"))
342 ERR("\E[0;31;1mERROR : Invalid library link! (Check linkage of libCOREGL -> libGLESv2_drv)\E[0m\n");
345 //------------------------------------------------//
350 #ifndef _COREGL_EMBED_EVAS
351 gl_lib_handle = dlopen("libGL_drv.so", RTLD_NOW);
353 gl_lib_handle = dlopen("libGL.so.1", RTLD_NOW);
355 gl_lib_handle = dlopen("libGL.so", RTLD_NOW);
359 ERR("%s\n", dlerror());
363 //------------------------------------------------//
365 #endif // _COREGL_DESKTOP_GL
367 if (!_glue_sym_init()) return 0;
368 if (!_gl_sym_init()) return 0;
373 extern void init_fast_gl();
374 extern void init_wrap_gl();
376 #ifndef _COREGL_EMBED_EVAS
377 __attribute__((constructor))
382 int fastpath_opt = 0;
386 if (!_gl_lib_init()) return 0;
388 fastpath_opt = atoi(get_env_setting("COREGL_FASTPATH"));
390 switch (fastpath_opt)
393 api_opt = COREGL_FAST_PATH;
394 LOG(": (%d) Fastpath enabled...\n", fastpath_opt);
398 LOG(": (%d) Default API path enabled...\n", fastpath_opt);
399 api_opt = COREGL_NORMAL_PATH;
404 #ifdef COREGL_TRACE_APICALL_INFO
405 trace_api_flag = atoi(get_env_setting("COREGL_TRACE_API"));
407 #ifdef COREGL_TRACE_CONTEXT_INFO
408 trace_ctx_flag = atoi(get_env_setting("COREGL_TRACE_CTX"));
410 #ifdef COREGL_TRACE_STATE_INFO
411 trace_state_flag = atoi(get_env_setting("COREGL_TRACE_STATE"));
414 debug_nofp = atoi(get_env_setting("COREGL_DEBUG_NOFP"));
417 override_glue_apis(api_opt);
418 override_gl_apis(api_opt);
423 extern void free_fast_gl();
424 extern void free_wrap_gl();
426 #ifndef _COREGL_EMBED_EVAS
427 __attribute__((destructor))
432 GLContext_List *current = NULL;
436 case COREGL_FAST_PATH:
444 AST(mutex_lock(&ctx_list_access_mutex) == 1);
447 // Destroy remained context & Detect leaks
448 int retry_destroy = 0;
453 current = glctx_list;
456 if (current->cstate != NULL)
458 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);
460 #ifndef _COREGL_DESKTOP_GL
461 _sym_eglMakeCurrent(current->cstate->rdpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
462 _sym_eglDestroyContext(current->cstate->rdpy, current->cstate->rctx);
464 _sym_glXDestroyContext(current->cstate->rdpy, current->cstate->rctx);
467 remove_context_states_from_list(current->cstate, NULL);
472 glctx_list = current->next;
474 current = glctx_list;
476 if (retry_destroy == 0) break;
480 #ifndef _COREGL_DESKTOP_GL
481 if (egl_lib_handle) dlclose(egl_lib_handle);
483 if (gl_lib_handle) dlclose(gl_lib_handle);
487 AST(mutex_unlock(&ctx_list_access_mutex) == 1);