Add support for GLES 3.2
[platform/core/uifw/coregl.git] / src / coregl.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <dlfcn.h>
4 #include <string.h>
5
6 #include <sys/types.h>
7 #include <unistd.h>
8
9 #include "coregl_internal.h"
10 #include "coregl_export.h"
11
12 void               *egl_lib_handle;
13 void               *gl_lib_handle;
14
15 int                 driver_gl_version = 0;
16 static int          api_gl_version = COREGL_GLAPI_2;
17
18 #ifndef _COREGL_VENDOR_EGL_LIB_PATH
19 #define _COREGL_VENDOR_EGL_LIB_PATH "/usr/lib/driver/libEGL.so" /* DEFAULT EGL PATH */
20 #endif
21
22 #ifndef _COREGL_VENDOR_GLV2_LIB_PATH
23 #define _COREGL_VENDOR_GLV2_LIB_PATH "/usr/lib/driver/libGLESv2.so" /* DEFAULT GL PATH */
24 #endif
25
26 #ifndef _COREGL_VENDOR_GLV1_LIB_PATH
27 #define _COREGL_VENDOR_GLV1_LIB_PATH "/usr/lib/driver/libGLESv1_CM.so" /* GLV1 PATH */
28 #endif
29
30 // Symbol definition for real
31 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST)     RET_TYPE (*_sym_##FUNC_NAME) PARAM_LIST;
32 #include "headers/sym.h"
33 #undef _COREGL_SYMBOL
34
35 const char *
36 get_env_setting(const char *name)
37 {
38         char *fp_env = NULL;
39         static char *fp_default = "\0";
40         fp_env = getenv(name);
41         if (fp_env == NULL) fp_env = fp_default;
42         return fp_env;
43 }
44
45 void
46 cleanup_current_thread_state()
47 {
48         GLThreadState *tstate = NULL;
49
50         tstate = get_current_thread_state();
51
52         if (tstate != NULL) {
53                 COREGL_LOG("[COREGL] de-init thread state \n");
54                 deinit_modules_tstate(tstate);
55                 remove_from_general_trace_list(&thread_trace_list, tstate);
56                 free(tstate);
57                 tstate = NULL;
58         }
59
60         set_current_thread_state(NULL);
61 }
62
63 int
64 init_new_thread_state()
65 {
66         int ret = 0;
67         GLThreadState *tstate = NULL;
68
69         tstate = get_current_thread_state();
70         AST(tstate == NULL);
71
72         tstate = (GLThreadState *)calloc(1, sizeof(GLThreadState));
73         tstate->thread_id = get_current_thread();
74         add_to_general_trace_list(&thread_trace_list, tstate);
75
76         init_modules_tstate(tstate);
77         set_current_thread_state(tstate);
78
79         ret = 1;
80         goto finish;
81
82 finish:
83         return ret;
84 }
85
86 static void
87 _sym_missing()
88 {
89         COREGL_ERR("GL symbol missing! Check client version!\n");
90 }
91
92 #define FINDGLSYM(libhandle, getproc, dst, sym) \
93         if(api_gl_version <= driver_gl_version) { \
94       if (!dst || (void *)dst == (void *)_sym_missing) \
95                   if (getproc) dst = (__typeof__(dst))getproc(sym); \
96       if (!dst || (void *)dst == (void *)_sym_missing) \
97                   dst = (__typeof__(dst))dlsym(libhandle, sym); \
98           if (!dst) dst = (__typeof__(dst))_sym_missing; \
99    }
100
101 #define FINDEGLSYM(libhandle, getproc, dst, sym) { \
102       if (!dst || (void *)dst == (void *)_sym_missing) \
103                   if (getproc) dst = (__typeof__(dst))getproc(sym); \
104       if (!dst || (void *)dst == (void *)_sym_missing) \
105                   dst = (__typeof__(dst))dlsym(libhandle, sym); \
106           if (!dst) dst = (__typeof__(dst))_sym_missing;\
107    }
108
109 static int
110 _glue_sym_init(void)
111 {
112 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST) \
113     FINDEGLSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME);
114 #define _COREGL_EXT_SYMBOL_ALIAS(FUNC_NAME, ALIAS_NAME) \
115     FINDEGLSYM(egl_lib_handle, _sym_eglGetProcAddress, _sym_##ALIAS_NAME, #FUNC_NAME);
116
117 #include "headers/sym_egl.h"
118
119 #undef _COREGL_EXT_SYMBOL_ALIAS
120 #undef _COREGL_SYMBOL
121
122         return 1;
123 }
124
125 static int
126 _gl_sym_init(void)
127 {
128
129 #define _COREGL_START_API(version)              api_gl_version = version;
130 #define _COREGL_END_API(version)                api_gl_version = COREGL_GLAPI_2;
131 #define _COREGL_SYMBOL(RET_TYPE, FUNC_NAME, PARAM_LIST) \
132         FINDGLSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##FUNC_NAME, #FUNC_NAME);
133 #define _COREGL_EXT_SYMBOL_ALIAS(FUNC_NAME, ALIAS_NAME) \
134         FINDGLSYM(gl_lib_handle, _sym_eglGetProcAddress, _sym_##ALIAS_NAME, #FUNC_NAME);
135
136 #include "headers/sym_gl1.h"
137 #include "headers/sym_gl2.h"
138 #include "headers/sym_gl_common.h"
139
140 #undef _COREGL_EXT_SYMBOL_ALIAS
141 #undef _COREGL_SYMBOL
142 #undef _COREGL_START_API
143 #undef _COREGL_END_API
144
145         return 1;
146 }
147
148 #undef FINDEGLSYM
149 #undef FINDGLSYM
150
151
152 COREGL_API void coregl_symbol_exported()
153 {
154         COREGL_ERR("\E[40;31;1mInvalid library link! (Check linkage of libCOREGL)\E[0m\n");
155 }
156
157 COREGL_API void set_driver_gl_version(int version)
158 {
159         driver_gl_version = version;
160 }
161
162 static int
163 _gl_lib_init(void)
164 {
165         //------------------------------------------------//
166         // Open EGL Library as EGL is separate
167         egl_lib_handle = dlopen(_COREGL_VENDOR_EGL_LIB_PATH, RTLD_LAZY | RTLD_LOCAL);
168         if (!egl_lib_handle) {
169                 COREGL_ERR("\E[40;31;1m%s\E[0m\n\n", dlerror());
170                 COREGL_ERR("\E[40;31;1mInvalid library link! (Check linkage of libCOREGL -> %s)\E[0m\n",
171                         _COREGL_VENDOR_EGL_LIB_PATH);
172                 return 0;
173         }
174
175         // test for invalid linking egl
176         if (dlsym(egl_lib_handle, "coregl_symbol_exported")) {
177                 COREGL_ERR("\E[40;31;1mInvalid library link! (Check linkage of libCOREGL -> %s)\E[0m\n",
178                         _COREGL_VENDOR_EGL_LIB_PATH);
179                 return 0;
180         }
181
182         // use gl_lib handle for GL symbols
183         if (driver_gl_version == COREGL_GLAPI_1) {
184                 gl_lib_handle = dlopen(_COREGL_VENDOR_GLV1_LIB_PATH, RTLD_LAZY | RTLD_LOCAL);
185                 if(!gl_lib_handle) {
186                         COREGL_ERR("\E[40;31;1m%s\E[0m\n\n", dlerror());
187                         COREGL_ERR("\E[40;31;1mInvalid library link! (Check linkage of libCOREGL -> %s)\E[0m\n",
188                                 _COREGL_VENDOR_GLV1_LIB_PATH);
189                 }
190                 else {
191                         // test for invalid linking gl
192                         if (dlsym(gl_lib_handle, "coregl_symbol_exported")) {
193                                 COREGL_ERR("\E[40;31;1mInvalid library link! (Check linkage of libCOREGL -> %s)\E[0m\n",
194                                         _COREGL_VENDOR_GLV1_LIB_PATH);
195                                 return 0;
196                         }
197                         COREGL_LOG("[CoreGL] Driver GL version 1.1 \n");
198                 }
199         }
200         else if (driver_gl_version == COREGL_GLAPI_2) {
201                 gl_lib_handle = dlopen(_COREGL_VENDOR_GLV2_LIB_PATH, RTLD_LAZY | RTLD_LOCAL);
202                 if (!gl_lib_handle) {
203                         COREGL_ERR("\E[40;31;1m%s\E[0m\n\n", dlerror());
204                         COREGL_ERR("\E[40;31;1mInvalid library link! (Check linkage of libCOREGL -> %s)\E[0m\n",
205                                 _COREGL_VENDOR_GLV2_LIB_PATH);
206                 }
207                 else {
208                         // test for invalid linking gl
209                         if (dlsym(gl_lib_handle, "coregl_symbol_exported")) {
210                                 COREGL_ERR("\E[40;31;1mInvalid library link! (Check linkage of libCOREGL -> %s)\E[0m\n",
211                                         _COREGL_VENDOR_GLV2_LIB_PATH);
212                                 return 0;
213                         }
214
215                         // test for a GLES 3.x symbol
216                         if (dlsym(gl_lib_handle, "glBlendBarrier")) {
217                                 COREGL_LOG("[CoreGL] Driver GL version 3.2 \n");
218                                 driver_gl_version = COREGL_GLAPI_32;
219                         }else if (dlsym(gl_lib_handle, "glBindProgramPipeline")) {
220                                 COREGL_LOG("[CoreGL] Driver GL version 3.1 \n");
221                                 driver_gl_version = COREGL_GLAPI_31;
222                         } else if (dlsym(gl_lib_handle, "glReadBuffer")) {
223                                 COREGL_LOG("[CoreGL] Driver GL version 3.0 \n");
224                                 driver_gl_version = COREGL_GLAPI_3;
225                         } else {
226                                 COREGL_LOG("[CoreGL] Driver GL version 2.0 \n");
227                         }
228                 }
229         }
230
231         if (!_glue_sym_init()) return 0;
232         if (!_gl_sym_init()) return 0;
233
234         return 1;
235 }
236
237 static int
238 _gl_lib_deinit(void)
239 {
240         if (egl_lib_handle) dlclose(egl_lib_handle);
241         if (gl_lib_handle) dlclose(gl_lib_handle);
242
243         return 1;
244 }
245
246 int
247 coregl_initialize()
248 {
249         COREGL_LOG("[CoreGL] <%d> (%s) Library initializing...", getpid(),
250                    _COREGL_COMPILE_DATE);
251
252         if (!_gl_lib_init()) return 0;
253
254         init_export();
255
256         COREGL_LOG(" -> Completed\n");
257
258         init_modules();
259
260         return 1;
261 }
262
263 __attribute__((destructor))
264 void
265 coregl_terminate()
266 {
267         if (export_initialized != 0) {
268                 deinit_modules();
269
270                 _gl_lib_deinit();
271         }
272 }
273