1 
2 #include "evas_gl_api_ext.h"
3 
4 #ifndef _WIN32
5 # include <dlfcn.h>
6 #endif
7 
8 #define EVGL_FUNC_BEGIN() if (UNLIKELY(_need_context_restore)) _context_restore()
9 
10 // list of egl extensions
11 #ifdef GL_GLES
12 static char *_egl_ext_string = NULL;
13 #endif
14 // list of gles 2.0 exts by official name
15 static char *_gl_ext_string = NULL;
16 // list of exts by official name only like "GL_EXT_discard_framebuffer GL_EXT_multi_draw_arrays"
17 static char *_gl_ext_string_official = NULL;
18 // list of gles 1.1 exts by official name
19 static char *_gles1_ext_string = NULL;
20 static char *_gles1_ext_string_official = NULL;
21 // list of gles 3.1 exts by official name
22 static char *_gles3_ext_string = NULL;
23 static char *_gles3_ext_string_official = NULL;
24 // indexed pointer list of each extension of gles 3
25 Eina_Array *_gles3_ext_plist = NULL;
26 
27 typedef void (*_getproc_fn) (void);
28 typedef _getproc_fn (*fp_getproc)(const char *);
29 
30 #ifndef EGL_NATIVE_PIXMAP_KHR
31 # define EGL_NATIVE_PIXMAP_KHR 0x30b0
32 #endif
33 
34 #ifndef EGL_WL_bind_wayland_display
35 struct wl_display;
36 struct wl_resource;
37 #endif
38 
39 /////////////////////////////////////////////////////////////////////////////////////////////////////
40 // Extension HEADER
41 /////////////////////////////////////////////////////////////////////////////////////////////////////
42 #define _EVASGL_EXT_CHECK_SUPPORT(name)
43 #define _EVASGL_EXT_DISCARD_SUPPORT()
44 #define _EVASGL_EXT_BEGIN(name)
45 #define _EVASGL_EXT_END()
46 #define _EVASGL_EXT_DRVNAME(name)
47 #define _EVASGL_EXT_DRVNAME_PRIVATE(name)
48 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
49 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
50    ret (*egl_ext_sym_##name) param1 = NULL; \
51    ret (*gl_ext_sym_##name) param1 = NULL; \
52    ret (*gles1_ext_sym_##name) param1 = NULL; \
53    ret (*gles3_ext_sym_##name) param1 = NULL;
54 #define _EVASGL_EXT_FUNCTION_END()
55 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
56 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
57 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
58 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
59 
60 #include "evas_gl_api_ext_def.h"
61 
62 #undef _EVASGL_EXT_CHECK_SUPPORT
63 #undef _EVASGL_EXT_DISCARD_SUPPORT
64 #undef _EVASGL_EXT_BEGIN
65 #undef _EVASGL_EXT_END
66 #undef _EVASGL_EXT_DRVNAME
67 #undef _EVASGL_EXT_DRVNAME_PRIVATE
68 #undef _EVASGL_EXT_DRVNAME_DESKTOP
69 #undef _EVASGL_EXT_FUNCTION_BEGIN
70 #undef _EVASGL_EXT_FUNCTION_END
71 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
72 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
73 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
74 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
75 /////////////////////////////////////////////////////////////////////////////////////////////////////
76 
77 /////////////////////////////////////////////////////////////////////////////////////////////////////
78 // Extension HEADER
79 /////////////////////////////////////////////////////////////////////////////////////////////////////
80 #define _EVASGL_EXT_CHECK_SUPPORT(name)
81 #define _EVASGL_EXT_DISCARD_SUPPORT()
82 #define _EVASGL_EXT_BEGIN(name) \
83    int _egl_ext_support_##name = 0; \
84    int _gl_ext_support_##name = 0; \
85    int _gles1_ext_support_##name = 0; \
86    int _gles3_ext_support_##name = 0;
87 #define _EVASGL_EXT_END()
88 #define _EVASGL_EXT_DRVNAME(name)
89 #define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
90    int _egl_ext_support_func_##name = 0; \
91    int _gl_ext_support_func_##name = 0; \
92    int _gles1_ext_support_func_##name = 0; \
93    int _gles3_ext_support_func_##name = 0;
94 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
95 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2)
96 #define _EVASGL_EXT_FUNCTION_END()
97 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
98 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
99 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
100 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
101 
102 #include "evas_gl_api_ext_def.h"
103 
104 #undef _EVASGL_EXT_ENABLE_EGL
105 #undef _EVASGL_EXT_ENABLE_GL_GLES
106 #undef _EVASGL_EXT_CHECK_SUPPORT
107 #undef _EVASGL_EXT_DISCARD_SUPPORT
108 #undef _EVASGL_EXT_BEGIN
109 #undef _EVASGL_EXT_END
110 #undef _EVASGL_EXT_DRVNAME
111 #undef _EVASGL_EXT_DRVNAME_PRIVATE
112 #undef _EVASGL_EXT_DRVNAME_DESKTOP
113 #undef _EVASGL_EXT_FUNCTION_BEGIN
114 #undef _EVASGL_EXT_FUNCTION_END
115 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
116 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
117 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
118 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
119 /////////////////////////////////////////////////////////////////////////////////////////////////////
120 
121 #define EVGL_FUNC_BEGIN() if (UNLIKELY(_need_context_restore)) _context_restore()
122 
123 // Evas extensions from EGL extensions
124 #ifdef GL_GLES
125 #define EGLDISPLAY_GET(a) _evgl_egl_display_get(__func__, a)
126 
127 // this struct defines an EvasGLImage when using EGL
128 typedef struct _EvasGLImage {
129    EGLDisplay  dpy;
130    EGLImageKHR img;
131 } EvasGLImage_EGL;
132 
133 static EGLDisplay
_evgl_egl_display_get(const char * function,Evas_GL * evgl)134 _evgl_egl_display_get(const char *function, Evas_GL *evgl)
135 {
136    EGLDisplay dpy = EGL_NO_DISPLAY;
137    EVGL_Resource *rsc;
138 
139    if (!evgl_engine || !evgl_engine->funcs || !evgl_engine->funcs->display_get)
140      {
141         ERR("%s: Invalid Engine... (Can't acccess EGL Display)\n", function);
142         evas_gl_common_error_set(EVAS_GL_BAD_DISPLAY);
143         return EGL_NO_DISPLAY;
144      }
145 
146    if (!(rsc=_evgl_tls_resource_get()))
147      {
148         if (evgl) goto fallback;
149         ERR("%s: Unable to execute GL command. Error retrieving tls", function);
150         evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
151         return EGL_NO_DISPLAY;
152      }
153 
154    if (!rsc->current_eng)
155      {
156         if (evgl) goto fallback;
157         ERR("%s: no current engine set; ensure you've called evas_gl_make_current()", function);
158         evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
159         return EGL_NO_DISPLAY;
160      }
161 
162    dpy = (EGLDisplay) evgl_engine->funcs->display_get(rsc->current_eng);
163    return dpy;
164 
165 fallback:
166    dpy = (EGLDisplay) evgl_engine->funcs->display_get(_evgl_engine_data_get(evgl));
167    return dpy;
168 }
169 
170 static void *
_evgl_eglCreateImageKHR(EGLDisplay dpy,EGLContext ctx,int target,void * buffer,const int * attrib_list)171 _evgl_eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx,
172                         int target, void* buffer, const int *attrib_list)
173 {
174    EvasGLImage_EGL *img;
175    int *attribs = NULL;
176    void *eglimg;
177 
178    /* Convert 0 terminator into a EGL_NONE terminator */
179    if (attrib_list)
180      {
181         int cnt = 0;
182         int *a;
183 
184         for (a = (int *) attrib_list; (*a) && (*a != EGL_NONE); a += 2)
185           {
186              /* TODO: Verify supported attributes */
187              cnt += 2;
188           }
189 
190         attribs = alloca(sizeof(int) * (cnt + 1));
191         for (a = attribs; (*attrib_list) && (*attrib_list != EGL_NONE);
192              a += 2, attrib_list += 2)
193           {
194              a[0] = attrib_list[0];
195              a[1] = attrib_list[1];
196           }
197         *a = EGL_NONE;
198      }
199 
200    eglimg = EXT_FUNC_EGL(eglCreateImage)(dpy, ctx, target, buffer, attribs);
201    if (!eglimg) return NULL;
202 
203    img = calloc(1, sizeof(EvasGLImage_EGL));
204    img->dpy = dpy;
205    img->img = eglimg;
206    return img;
207 }
208 
209 static void *
_evgl_evasglCreateImage(int target,void * buffer,const int * attrib_list)210 _evgl_evasglCreateImage(int target, void* buffer, const int *attrib_list)
211 {
212    EGLDisplay dpy = EGLDISPLAY_GET(NULL);
213    EGLContext ctx = EGL_NO_CONTEXT;
214 
215    if (!dpy)
216      {
217         WRN("No display found, use evasglCreateImageForContext instead.");
218         return NULL;
219      }
220 
221    /* EGL_NO_CONTEXT will always fail for TEXTURE_2D */
222    if (target == EVAS_GL_TEXTURE_2D)
223      {
224         ctx = eglGetCurrentContext();
225         DBG("Creating EGL image based on the current context: %p", ctx);
226      }
227 
228    return _evgl_eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
229 }
230 
231 static void *
_evgl_evasglCreateImageForContext(Evas_GL * evasgl,Evas_GL_Context * evasctx,int target,void * buffer,const int * attrib_list)232 _evgl_evasglCreateImageForContext(Evas_GL *evasgl, Evas_GL_Context *evasctx,
233                                  int target, void* buffer, const int *attrib_list)
234 {
235    EGLDisplay dpy = EGLDISPLAY_GET(evasgl);
236    EGLContext ctx = EGL_NO_CONTEXT;
237 
238    if (!dpy || !evasgl)
239      {
240         ERR("Evas_GL can not be NULL here.");
241         evas_gl_common_error_set(EVAS_GL_BAD_DISPLAY);
242         return NULL;
243      }
244 
245    ctx = _evgl_native_context_get(evasctx);
246    return _evgl_eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list);
247 }
248 
249 static void
_evgl_evasglDestroyImage(EvasGLImage image)250 _evgl_evasglDestroyImage(EvasGLImage image)
251 {
252    EvasGLImage_EGL *img = image;
253 
254    if (!img)
255      {
256         ERR("EvasGLImage is NULL.");
257         evas_gl_common_error_set(EVAS_GL_BAD_PARAMETER);
258         return;
259      }
260 
261    EXT_FUNC_EGL(eglDestroyImage)(img->dpy, img->img);
262    free(img);
263 }
264 
265 static void
_evgl_glEvasGLImageTargetTexture2D(GLenum target,EvasGLImage image)266 _evgl_glEvasGLImageTargetTexture2D(GLenum target, EvasGLImage image)
267 {
268    EvasGLImage_EGL *img = image;
269    EVGL_Resource *rsc;
270    EVGL_Context *ctx;
271 
272    if (!(rsc=_evgl_tls_resource_get()))
273      {
274         ERR("Unable to execute GL command. Error retrieving tls");
275         return;
276      }
277 
278    if (!rsc->current_eng)
279      {
280         ERR("Unable to retrieve Current Engine");
281         return;
282      }
283 
284    ctx = rsc->current_ctx;
285    if (!ctx)
286      {
287         ERR("Unable to retrieve Current Context");
288         return;
289      }
290 
291   if (!img)
292     {
293        ERR("EvasGLImage is NULL");
294        EXT_FUNC(glEGLImageTargetTexture2DOES)(target, NULL);
295        return;
296     }
297 
298    EXT_FUNC(glEGLImageTargetTexture2DOES)(target, img->img);
299 }
300 
301 static void
_evgl_glEvasGLImageTargetRenderbufferStorage(GLenum target,EvasGLImage image)302 _evgl_glEvasGLImageTargetRenderbufferStorage(GLenum target, EvasGLImage image)
303 {
304    EvasGLImage_EGL *img = image;
305    EVGL_Resource *rsc;
306    EVGL_Context *ctx;
307 
308    if (!(rsc=_evgl_tls_resource_get()))
309      {
310         ERR("Unable to execute GL command. Error retrieving tls");
311         return;
312      }
313 
314    if (!rsc->current_eng)
315      {
316         ERR("Unable to retrieve Current Engine");
317         return;
318      }
319 
320    ctx = rsc->current_ctx;
321    if (!ctx)
322      {
323         ERR("Unable to retrieve Current Context");
324         return;
325      }
326 
327   if (!img)
328     {
329        ERR("EvasGLImage is NULL");
330        EXT_FUNC(glEGLImageTargetRenderbufferStorageOES)(target, NULL);
331        return;
332     }
333 
334    EXT_FUNC(glEGLImageTargetRenderbufferStorageOES)(target, img->img);
335 }
336 
337 static EvasGLSync
_evgl_evasglCreateSync(Evas_GL * evas_gl,unsigned int type,const int * attrib_list)338 _evgl_evasglCreateSync(Evas_GL *evas_gl,
339                       unsigned int type, const int *attrib_list)
340 {
341    EGLDisplay dpy = EGLDISPLAY_GET(evas_gl);
342    if (!dpy) return NULL;
343    return EXT_FUNC_EGL(eglCreateSyncKHR)(dpy, type, attrib_list);
344 }
345 
346 static Eina_Bool
_evgl_evasglDestroySync(Evas_GL * evas_gl,EvasGLSync sync)347 _evgl_evasglDestroySync(Evas_GL *evas_gl, EvasGLSync sync)
348 {
349    EGLDisplay dpy = EGLDISPLAY_GET(evas_gl);
350    if (!dpy) return EINA_FALSE;
351    return EXT_FUNC_EGL(eglDestroySyncKHR)(dpy, sync);
352 }
353 
354 static int
_evgl_evasglClientWaitSync(Evas_GL * evas_gl,EvasGLSync sync,int flags,EvasGLTime timeout)355 _evgl_evasglClientWaitSync(Evas_GL *evas_gl,
356                           EvasGLSync sync, int flags, EvasGLTime timeout)
357 {
358    EGLDisplay dpy = EGLDISPLAY_GET(evas_gl);
359    if (!dpy) return EINA_FALSE;
360    return EXT_FUNC_EGL(eglClientWaitSyncKHR)(dpy, sync, flags, timeout);
361 }
362 
363 static Eina_Bool
_evgl_evasglSignalSync(Evas_GL * evas_gl,EvasGLSync sync,unsigned mode)364 _evgl_evasglSignalSync(Evas_GL *evas_gl,
365                       EvasGLSync sync, unsigned mode)
366 {
367    EGLDisplay dpy = EGLDISPLAY_GET(evas_gl);
368    if (!dpy) return EINA_FALSE;
369    return EXT_FUNC_EGL(eglSignalSyncKHR)(dpy, sync, mode);
370 }
371 
372 static Eina_Bool
_evgl_evasglGetSyncAttrib(Evas_GL * evas_gl,EvasGLSync sync,int attribute,int * value)373 _evgl_evasglGetSyncAttrib(Evas_GL *evas_gl,
374                          EvasGLSync sync, int attribute, int *value)
375 {
376    EGLDisplay dpy = EGLDISPLAY_GET(evas_gl);
377    if (!dpy) return EINA_FALSE;
378    return EXT_FUNC_EGL(eglGetSyncAttribKHR)(dpy, sync, attribute, value);
379 }
380 
381 static int
_evgl_evasglWaitSync(Evas_GL * evas_gl,EvasGLSync sync,int flags)382 _evgl_evasglWaitSync(Evas_GL *evas_gl,
383                     EvasGLSync sync, int flags)
384 {
385    EGLDisplay dpy = EGLDISPLAY_GET(evas_gl);
386    if (!dpy) return EINA_FALSE;
387    return EXT_FUNC_EGL(eglWaitSyncKHR)(dpy, sync, flags);
388 }
389 
390 static Eina_Bool
_evgl_evasglBindWaylandDisplay(Evas_GL * evas_gl,void * wl_display)391 _evgl_evasglBindWaylandDisplay(Evas_GL *evas_gl,
392                               void *wl_display)
393 {
394    EGLDisplay dpy = EGLDISPLAY_GET(evas_gl);
395    if (!dpy) return EINA_FALSE;
396    return EXT_FUNC_EGL(eglBindWaylandDisplayWL)(dpy, wl_display);
397 }
398 
399 static Eina_Bool
_evgl_evasglUnbindWaylandDisplay(Evas_GL * evas_gl,void * wl_display)400 _evgl_evasglUnbindWaylandDisplay(Evas_GL *evas_gl,
401                                 void *wl_display)
402 {
403    EGLDisplay dpy = EGLDISPLAY_GET(evas_gl);
404    if (!dpy) return EINA_FALSE;
405    return EXT_FUNC_EGL(eglUnbindWaylandDisplayWL)(dpy, wl_display);
406 }
407 
408 static Eina_Bool
_evgl_evasglQueryWaylandBuffer(Evas_GL * evas_gl,void * buffer,int attribute,int * value)409 _evgl_evasglQueryWaylandBuffer(Evas_GL *evas_gl,
410                               void *buffer, int attribute, int *value)
411 {
412    EGLDisplay dpy = EGLDISPLAY_GET(evas_gl);
413    if (!dpy) return EINA_FALSE;
414    return EXT_FUNC_EGL(eglQueryWaylandBufferWL)(dpy, buffer, attribute, value);
415 }
416 
417 #else
418 #endif
419 
420 static void
_evgl_glDiscardFramebufferEXT(GLenum target,GLsizei numAttachments,const GLenum * attachments)421 _evgl_glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum* attachments)
422 {
423    EVGL_Resource *rsc;
424    EVGL_Context *ctx;
425    Eina_Bool target_is_fbo = EINA_FALSE;
426 
427    if (!(rsc=_evgl_tls_resource_get()))
428      {
429         ERR("Unable to execute GL command. Error retrieving tls");
430         return;
431      }
432 
433    if (!rsc->current_eng)
434      {
435         ERR("Unable to retrieve Current Engine");
436         return;
437      }
438 
439    ctx = rsc->current_ctx;
440    if (!ctx)
441      {
442         ERR("Unable to retrieve Current Context");
443         return;
444      }
445 
446    if (!_evgl_direct_enabled())
447      {
448         if (ctx->current_fbo == 0)
449           target_is_fbo = EINA_TRUE;
450      }
451 
452    if (target_is_fbo && numAttachments)
453      {
454         GLenum *att;
455         int i = 0;
456         att = (GLenum *)calloc(1, numAttachments * sizeof(GLenum));
457         if (!att)
458           return;
459 
460         memcpy(att, attachments, numAttachments * sizeof(GLenum));
461         while (i < numAttachments)
462           {
463              if (att[i] == GL_COLOR_EXT)
464                att[i] = GL_COLOR_ATTACHMENT0;
465              else if (att[i] == GL_DEPTH_EXT)
466                att[i] = GL_DEPTH_ATTACHMENT;
467              else if (att[i] == GL_STENCIL_EXT)
468                att[i] = GL_STENCIL_ATTACHMENT;
469              i++;
470           }
471         EXT_FUNC(glDiscardFramebuffer)(target, numAttachments, att);
472         free(att);
473      }
474    else
475      {
476         EXT_FUNC(glDiscardFramebuffer)(target, numAttachments, attachments);
477      }
478 }
479 
480 //2.0 ext bodies
481 #define _EVASGL_EXT_CHECK_SUPPORT(name)
482 #define _EVASGL_EXT_DISCARD_SUPPORT()
483 #define _EVASGL_EXT_BEGIN(name)
484 #define _EVASGL_EXT_END()
485 #define _EVASGL_EXT_DRVNAME(name)
486 #define _EVASGL_EXT_DRVNAME_PRIVATE(name)
487 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
488 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
489     static ret evgl_##name param1 { EVGL_FUNC_BEGIN(); return EXT_FUNC(name) param2; }
490 #define _EVASGL_EXT_FUNCTION_END()
491 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
492 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
493 #define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param1, param2)
494 #define _EVASGL_EXT_FUNCTION_PRIVATE_END()
495 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
496 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
497 
498 #include "evas_gl_api_ext_def.h"
499 
500 #undef _EVASGL_EXT_CHECK_SUPPORT
501 #undef _EVASGL_EXT_DISCARD_SUPPORT
502 #undef _EVASGL_EXT_BEGIN
503 #undef _EVASGL_EXT_END
504 #undef _EVASGL_EXT_DRVNAME
505 #undef _EVASGL_EXT_DRVNAME_PRIVATE
506 #undef _EVASGL_EXT_DRVNAME_DESKTOP
507 #undef _EVASGL_EXT_FUNCTION_BEGIN
508 #undef _EVASGL_EXT_FUNCTION_END
509 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
510 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
511 #undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
512 #undef _EVASGL_EXT_FUNCTION_PRIVATE_END
513 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
514 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
515 
516 //1.1 ext bodies
517 #define _EVASGL_EXT_CHECK_SUPPORT(name)
518 #define _EVASGL_EXT_DISCARD_SUPPORT()
519 #define _EVASGL_EXT_BEGIN(name)
520 #define _EVASGL_EXT_END()
521 #define _EVASGL_EXT_DRVNAME(name)
522 #define _EVASGL_EXT_DRVNAME_PRIVATE(name)
523 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
524 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
525     static ret evgl_gles1_##name param1 { EVGL_FUNC_BEGIN(); return EXT_FUNC_GLES1(name) param2; }
526 #define _EVASGL_EXT_FUNCTION_END()
527 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
528 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
529 #define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param1, param2)
530 #define _EVASGL_EXT_FUNCTION_PRIVATE_END()
531 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
532 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
533 
534 #include "evas_gl_api_ext_def.h"
535 
536 #undef _EVASGL_EXT_CHECK_SUPPORT
537 #undef _EVASGL_EXT_DISCARD_SUPPORT
538 #undef _EVASGL_EXT_BEGIN
539 #undef _EVASGL_EXT_END
540 #undef _EVASGL_EXT_DRVNAME
541 #undef _EVASGL_EXT_DRVNAME_PRIVATE
542 #undef _EVASGL_EXT_DRVNAME_DESKTOP
543 #undef _EVASGL_EXT_FUNCTION_BEGIN
544 #undef _EVASGL_EXT_FUNCTION_END
545 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
546 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
547 #undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
548 #undef _EVASGL_EXT_FUNCTION_PRIVATE_END
549 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
550 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
551 
552 //3.X ext bodies
553 #define _EVASGL_EXT_CHECK_SUPPORT(name)
554 #define _EVASGL_EXT_DISCARD_SUPPORT()
555 #define _EVASGL_EXT_BEGIN(name)
556 #define _EVASGL_EXT_END()
557 #define _EVASGL_EXT_DRVNAME(name)
558 #define _EVASGL_EXT_DRVNAME_PRIVATE(name)
559 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
560 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
561     static ret evgl_gles3_##name param1 { EVGL_FUNC_BEGIN(); return EXT_FUNC_GLES3(name) param2; }
562 #define _EVASGL_EXT_FUNCTION_END()
563 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
564 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
565 #define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param1, param2)
566 #define _EVASGL_EXT_FUNCTION_PRIVATE_END()
567 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
568 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
569 
570 #include "evas_gl_api_ext_def.h"
571 
572 #undef _EVASGL_EXT_CHECK_SUPPORT
573 #undef _EVASGL_EXT_DISCARD_SUPPORT
574 #undef _EVASGL_EXT_BEGIN
575 #undef _EVASGL_EXT_END
576 #undef _EVASGL_EXT_DRVNAME
577 #undef _EVASGL_EXT_DRVNAME_PRIVATE
578 #undef _EVASGL_EXT_DRVNAME_DESKTOP
579 #undef _EVASGL_EXT_FUNCTION_BEGIN
580 #undef _EVASGL_EXT_FUNCTION_END
581 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
582 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
583 #undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
584 #undef _EVASGL_EXT_FUNCTION_PRIVATE_END
585 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
586 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
587 
588 //  0: not initialized,
589 //  1: GLESv2 initialized,
590 //  3: GLESv1 and GLESv2 initialized,
591 //  5: GLESv3 and GLESv2 initialized,
592 //  7: GLESv3 + GLESv2  + GLESv1 all initialized.
593 static int _evgl_api_ext_status = 0;
594 #define EVASGL_API_GLES2_EXT_INITIALIZED 0x1
595 #define EVASGL_API_GLES1_EXT_INITIALIZED 0x2
596 #define EVASGL_API_GLES3_EXT_INITIALIZED 0x4
597 #define EVASGL_API_EGL_EXT_INITIALIZED   0x8
598 
599 #ifdef GL_GLES
600 Eina_Bool
evgl_api_egl_ext_init(void * getproc,const char * glueexts)601 evgl_api_egl_ext_init(void *getproc, const char *glueexts)
602 {
603    fp_getproc gp = (fp_getproc)getproc;
604    int _curext_supported = 0;
605    Eina_Strbuf *sb = NULL;
606 
607    if (_evgl_api_ext_status & EVASGL_API_EGL_EXT_INITIALIZED)
608      return EINA_TRUE;
609 
610    sb = eina_strbuf_new();
611 
612    // Always supported by Evas GL (faked with internal pbuffer if needed)
613    // See also GL_OES_surfaceless_context (needs some more work to be actually
614    // supported).
615    eina_strbuf_append(sb, "EGL_KHR_surfaceless_context ");
616 
617    /////////////////////////////////////////////////////////////////////////////////////////////////////
618    // Extension HEADER
619    /////////////////////////////////////////////////////////////////////////////////////////////////////
620 #define GETPROCADDR(sym) \
621    (((!(*drvfunc)) && (gp)) ? (__typeof__((*drvfunc)))gp(sym) : (__typeof__((*drvfunc)))dlsym(RTLD_DEFAULT, sym))
622 
623 #define _EVASGL_EXT_BEGIN(name) \
624      { \
625         int *ext_support = &_egl_ext_support_##name; \
626         *ext_support = 0;
627 
628 #define _EVASGL_EXT_END() \
629      }
630 
631 #define _EVASGL_EXT_CHECK_SUPPORT(name) \
632    (strstr(glueexts, name) != NULL)
633 
634 #define _EVASGL_EXT_DISCARD_SUPPORT() \
635    *ext_support = 0;
636 
637 #define _EVASGL_EXT_DRVNAME(name) \
638    if (_EVASGL_EXT_CHECK_SUPPORT(#name)) *ext_support = 1;
639 
640 #define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
641    if (_EVASGL_EXT_CHECK_SUPPORT(#name)) { *ext_support = 1; _egl_ext_support_func_##name = 1; }
642 
643 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname) \
644    if (_EVASGL_EXT_CHECK_SUPPORT(deskname)) *ext_support = 1;
645 
646 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
647      { \
648         ret (**drvfunc)param1 = &egl_ext_sym_##name; \
649         if (*ext_support == 1) \
650           {
651 
652 #define _EVASGL_EXT_FUNCTION_END() \
653           } \
654         if ((*drvfunc) == NULL) _EVASGL_EXT_DISCARD_SUPPORT(); \
655      }
656 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
657 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
658 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name) \
659    if ((*drvfunc) == NULL) *drvfunc = name;
660 
661 // This adds all the function names to the "safe" list but only one pointer
662 // will be stored in the hash table.
663 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name) \
664    if ((*drvfunc) == NULL) \
665      { \
666         *drvfunc = GETPROCADDR(name); \
667         evgl_safe_extension_add(name, (void *) (*drvfunc)); \
668      } \
669    else evgl_safe_extension_add(name, NULL);
670 
671 #ifdef _EVASGL_EXT_FUNCTION_WHITELIST
672 # undef _EVASGL_EXT_FUNCTION_WHITELIST
673 #endif
674 #define _EVASGL_EXT_FUNCTION_WHITELIST(name) evgl_safe_extension_add(name, NULL);
675 
676 #define _EVASGL_EXT_ENABLE_GL_GLES 0
677 #define _EVASGL_EXT_ENABLE_EGL 1
678 
679 #include "evas_gl_api_ext_def.h"
680 
681 #undef _EVASGL_EXT_ENABLE_EGL
682 #undef _EVASGL_EXT_ENABLE_GL_GLES
683 #undef _EVASGL_EXT_FUNCTION_WHITELIST
684 #undef _EVASGL_EXT_CHECK_SUPPORT
685 #undef _EVASGL_EXT_DISCARD_SUPPORT
686 #undef _EVASGL_EXT_BEGIN
687 #undef _EVASGL_EXT_END
688 #undef _EVASGL_EXT_DRVNAME
689 #undef _EVASGL_EXT_DRVNAME_PRIVATE
690 #undef _EVASGL_EXT_DRVNAME_DESKTOP
691 #undef _EVASGL_EXT_FUNCTION_BEGIN
692 #undef _EVASGL_EXT_FUNCTION_END
693 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
694 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
695 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
696 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
697 
698 #undef GETPROCADDR
699    /////////////////////////////////////////////////////////////////////////////////////////////////////
700 
701    /////////////////////////////////////////////////////////////////////////////////////////////////////
702    // Extension HEADER
703    /////////////////////////////////////////////////////////////////////////////////////////////////////
704 #define _EVASGL_EXT_BEGIN(name) \
705      if (_egl_ext_support_##name != 0) \
706        { \
707           eina_strbuf_append(sb, #name" "); \
708           _curext_supported = 1; \
709        } \
710      else _curext_supported = 0;
711 
712 #define _EVASGL_EXT_END()
713 #define _EVASGL_EXT_CHECK_SUPPORT(name)
714 #define _EVASGL_EXT_DISCARD_SUPPORT()
715 #define _EVASGL_EXT_DRVNAME_PRINT(name) \
716        { \
717           if ((strncmp(name, "EGL_", 4) == 0) && (strstr(eina_strbuf_string_get(sb), name) == NULL)) \
718             eina_strbuf_append(sb, name" "); \
719        }
720 #define _EVASGL_EXT_DRVNAME(name) \
721      if (_curext_supported) \
722        _EVASGL_EXT_DRVNAME_PRINT(#name)
723 #define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
724      if (_curext_supported && _egl_ext_support_func_##name) \
725        _EVASGL_EXT_DRVNAME_PRINT(#name)
726 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
727 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2)
728 #define _EVASGL_EXT_FUNCTION_END()
729 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
730 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
731 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
732 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
733 
734 #define _EVASGL_EXT_ENABLE_GL_GLES 0
735 #define _EVASGL_EXT_ENABLE_EGL 1
736 
737 #include "evas_gl_api_ext_def.h"
738 
739 #undef _EVASGL_EXT_ENABLE_EGL
740 #undef _EVASGL_EXT_ENABLE_GL_GLES
741 #undef _EVASGL_EXT_CHECK_SUPPORT
742 #undef _EVASGL_EXT_DISCARD_SUPPORT
743 #undef _EVASGL_EXT_BEGIN
744 #undef _EVASGL_EXT_END
745 #undef _EVASGL_EXT_DRVNAME_PRINT
746 #undef _EVASGL_EXT_DRVNAME
747 #undef _EVASGL_EXT_DRVNAME_DESKTOP
748 #undef _EVASGL_EXT_DRVNAME_PRIVATE
749 #undef _EVASGL_EXT_FUNCTION_BEGIN
750 #undef _EVASGL_EXT_FUNCTION_END
751 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
752 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
753 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
754 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
755    /////////////////////////////////////////////////////////////////////////////////////////////////////
756 
757    if (_egl_ext_string) free(_egl_ext_string);
758    _egl_ext_string = eina_strbuf_string_steal(sb);
759    eina_strbuf_free(sb);
760 
761   INF("EGL extension string: %s", _egl_ext_string);
762 
763   _evgl_api_ext_status |= EVASGL_API_EGL_EXT_INITIALIZED;
764    return EINA_TRUE;
765 }
766 #endif
767 
768 Eina_Bool
_evgl_api_gles2_ext_init(void * getproc,const char * glueexts)769 _evgl_api_gles2_ext_init(void *getproc, const char *glueexts)
770 {
771    const char *glexts;
772    fp_getproc gp = (fp_getproc)getproc;
773    int _curext_supported = 0;
774    Eina_Strbuf *sb = eina_strbuf_new();
775    Eina_Strbuf *sboff = eina_strbuf_new();
776 
777 #ifndef GL_GLES
778    /* Add some extension strings that are always working on desktop GL */
779    static const char *desktop_exts =
780          "GL_EXT_read_format_bgra "
781          "GL_EXT_texture_format_BGRA8888 "
782          "GL_EXT_texture_type_2_10_10_10_REV ";
783    eina_strbuf_append(sb, desktop_exts);
784    eina_strbuf_append(sboff, desktop_exts);
785 #endif
786 
787    // GLES Extensions
788    glexts = (const char*)glGetString(GL_EXTENSIONS);
789    if (!glexts)
790      {
791         ERR("glGetString returned NULL! Something is very wrong...");
792         eina_strbuf_free(sb);
793         eina_strbuf_free(sboff);
794         return EINA_FALSE;
795      }
796 
797    /////////////////////////////////////////////////////////////////////////////////////////////////////
798    // Extension HEADER
799    /////////////////////////////////////////////////////////////////////////////////////////////////////
800 #define GETPROCADDR(sym) \
801    (((!(*drvfunc)) && (gp)) ? (__typeof__((*drvfunc)))gp(sym) : (__typeof__((*drvfunc)))dlsym(RTLD_DEFAULT, sym))
802 
803 #define _EVASGL_EXT_BEGIN(name) \
804      { \
805         int *ext_support = &_gl_ext_support_##name; \
806         *ext_support = 0;
807 
808 #define _EVASGL_EXT_END() \
809      }
810 
811 #define _EVASGL_EXT_CHECK_SUPPORT(name) \
812    (strstr(glexts, name) != NULL || strstr(glueexts, name) != NULL)
813 
814 #define _EVASGL_EXT_DISCARD_SUPPORT() \
815    *ext_support = 0;
816 
817 #define _EVASGL_EXT_DRVNAME(name) \
818    if (_EVASGL_EXT_CHECK_SUPPORT(#name)) *ext_support = 1;
819 
820 #define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
821    if (_EVASGL_EXT_CHECK_SUPPORT(#name)) { *ext_support = 1; _gl_ext_support_func_##name = 1; }
822 
823 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname) \
824    if (_EVASGL_EXT_CHECK_SUPPORT(deskname)) *ext_support = 1;
825 
826 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
827      { \
828         ret (**drvfunc)param1 = &gl_ext_sym_##name; \
829         if (*ext_support == 1) \
830           {
831 
832 #define _EVASGL_EXT_FUNCTION_END() \
833           } \
834         if ((*drvfunc) == NULL) _EVASGL_EXT_DISCARD_SUPPORT(); \
835      }
836 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
837 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
838 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name) \
839    if ((*drvfunc) == NULL) *drvfunc = name;
840 
841 // This adds all the function names to the "safe" list but only one pointer
842 // will be stored in the hash table.
843 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name) \
844    if ((*drvfunc) == NULL) \
845      { \
846         *drvfunc = GETPROCADDR(name); \
847         evgl_safe_extension_add(name, (void *) (*drvfunc)); \
848      } \
849    else evgl_safe_extension_add(name, NULL);
850 
851 #ifdef _EVASGL_EXT_FUNCTION_WHITELIST
852 # undef _EVASGL_EXT_FUNCTION_WHITELIST
853 #endif
854 #define _EVASGL_EXT_FUNCTION_WHITELIST(name) evgl_safe_extension_add(name, NULL);
855 
856 #define _EVASGL_EXT_ENABLE_GL_GLES 1
857 #define _EVASGL_EXT_ENABLE_EGL 1
858 
859 #include "evas_gl_api_ext_def.h"
860 
861 #undef _EVASGL_EXT_ENABLE_EGL
862 #undef _EVASGL_EXT_ENABLE_GL_GLES
863 #undef _EVASGL_EXT_FUNCTION_WHITELIST
864 #undef _EVASGL_EXT_CHECK_SUPPORT
865 #undef _EVASGL_EXT_DISCARD_SUPPORT
866 #undef _EVASGL_EXT_BEGIN
867 #undef _EVASGL_EXT_END
868 #undef _EVASGL_EXT_DRVNAME
869 #undef _EVASGL_EXT_DRVNAME_PRIVATE
870 #undef _EVASGL_EXT_DRVNAME_DESKTOP
871 #undef _EVASGL_EXT_FUNCTION_BEGIN
872 #undef _EVASGL_EXT_FUNCTION_END
873 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
874 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
875 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
876 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
877 
878 #undef GETPROCADDR
879    /////////////////////////////////////////////////////////////////////////////////////////////////////
880 
881    /////////////////////////////////////////////////////////////////////////////////////////////////////
882    // Extension HEADER
883    /////////////////////////////////////////////////////////////////////////////////////////////////////
884 #define _EVASGL_EXT_BEGIN(name) \
885      if (_gl_ext_support_##name != 0) \
886        { \
887           eina_strbuf_append(sb, #name" "); \
888           _curext_supported = 1; \
889        } \
890      else _curext_supported = 0;
891 
892 #define _EVASGL_EXT_END()
893 #define _EVASGL_EXT_CHECK_SUPPORT(name)
894 #define _EVASGL_EXT_DISCARD_SUPPORT()
895 #define _EVASGL_EXT_DRVNAME_PRINT(name) \
896        { \
897           eina_strbuf_append(sb, name" "); \
898           if ((strncmp(name, "GL_", 3) == 0) && (strstr(eina_strbuf_string_get(sboff), name) == NULL)) \
899             eina_strbuf_append(sboff, name" "); \
900        }
901 #define _EVASGL_EXT_DRVNAME(name) \
902      if (_curext_supported) \
903        _EVASGL_EXT_DRVNAME_PRINT(#name)
904 #define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
905      if (_curext_supported && _gl_ext_support_func_##name) \
906        _EVASGL_EXT_DRVNAME_PRINT(#name)
907 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
908 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2)
909 #define _EVASGL_EXT_FUNCTION_END()
910 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
911 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
912 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
913 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
914 #define _EVASGL_EXT_ENABLE_GL_GLES 1
915 #define _EVASGL_EXT_ENABLE_EGL 1
916 
917 #include "evas_gl_api_ext_def.h"
918 
919 #undef _EVASGL_EXT_ENABLE_EGL
920 #undef _EVASGL_EXT_ENABLE_GL_GLES
921 #undef _EVASGL_EXT_CHECK_SUPPORT
922 #undef _EVASGL_EXT_DISCARD_SUPPORT
923 #undef _EVASGL_EXT_BEGIN
924 #undef _EVASGL_EXT_END
925 #undef _EVASGL_EXT_DRVNAME_PRINT
926 #undef _EVASGL_EXT_DRVNAME
927 #undef _EVASGL_EXT_DRVNAME_DESKTOP
928 #undef _EVASGL_EXT_DRVNAME_PRIVATE
929 #undef _EVASGL_EXT_FUNCTION_BEGIN
930 #undef _EVASGL_EXT_FUNCTION_END
931 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
932 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
933 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
934 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
935    /////////////////////////////////////////////////////////////////////////////////////////////////////
936 
937    if (_gl_ext_string) free(_gl_ext_string);
938    if (_gl_ext_string_official) free(_gl_ext_string_official);
939    _gl_ext_string = eina_strbuf_string_steal(sb);
940    _gl_ext_string_official = eina_strbuf_string_steal(sboff);
941    eina_strbuf_free(sb);
942    eina_strbuf_free(sboff);
943 
944   _evgl_api_ext_status |= EVASGL_API_GLES2_EXT_INITIALIZED;
945    return EINA_TRUE;
946 }
947 
948 void
evgl_api_gles2_ext_get(Evas_GL_API * gl_funcs,void * getproc,const char * glueexts)949 evgl_api_gles2_ext_get(Evas_GL_API *gl_funcs, void *getproc, const char *glueexts)
950 {
951    if (!(_evgl_api_ext_status & EVASGL_API_GLES2_EXT_INITIALIZED))
952      {
953         DBG("Initializing GLESv2 extensions...");
954         if (!_evgl_api_gles2_ext_init(getproc, glueexts))
955           {
956              ERR("GLESv2 extensions initialization failed");
957              return;
958           }
959      }
960 #define ORD(f) EVAS_API_OVERRIDE(f, gl_funcs, evgl_)
961 
962    /////////////////////////////////////////////////////////////////////////////////////////////////////
963    // Extension HEADER
964    /////////////////////////////////////////////////////////////////////////////////////////////////////
965 #define _EVASGL_EXT_CHECK_SUPPORT(name)
966 #define _EVASGL_EXT_DISCARD_SUPPORT()
967 #define _EVASGL_EXT_BEGIN(name) \
968    if (_gl_ext_support_##name != 0) \
969      {
970 #define _EVASGL_EXT_END() \
971      }
972 #define _EVASGL_EXT_DRVNAME(name)
973 #define _EVASGL_EXT_DRVNAME_PRIVATE(name)
974 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
975 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
976    ORD(name);
977 #define _EVASGL_EXT_FUNCTION_END()
978 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
979 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
980 #define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param1, param2)
981 #define _EVASGL_EXT_FUNCTION_PRIVATE_END()
982 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
983 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
984 
985 #undef _EVASGL_EXT_WHITELIST_ONLY
986 #define _EVASGL_EXT_WHITELIST_ONLY 0
987 
988 #define _EVASGL_EXT_ENABLE_GL_GLES 1
989 #define _EVASGL_EXT_ENABLE_EGL 1
990 
991 #include "evas_gl_api_ext_def.h"
992 
993 #undef _EVASGL_EXT_ENABLE_EGL
994 #undef _EVASGL_EXT_ENABLE_GL_GLES
995 #undef _EVASGL_EXT_WHITELIST_ONLY
996 #undef _EVASGL_EXT_CHECK_SUPPORT
997 #undef _EVASGL_EXT_DISCARD_SUPPORT
998 #undef _EVASGL_EXT_BEGIN
999 #undef _EVASGL_EXT_END
1000 #undef _EVASGL_EXT_DRVNAME
1001 #undef _EVASGL_EXT_DRVNAME_PRIVATE
1002 #undef _EVASGL_EXT_DRVNAME_DESKTOP
1003 #undef _EVASGL_EXT_FUNCTION_BEGIN
1004 #undef _EVASGL_EXT_FUNCTION_END
1005 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
1006 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
1007 #undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
1008 #undef _EVASGL_EXT_FUNCTION_PRIVATE_END
1009 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
1010 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
1011    /////////////////////////////////////////////////////////////////////////////////////////////////////
1012 #undef ORD
1013 
1014 }
1015 
1016 Eina_Bool
_evgl_api_gles1_ext_init(void * getproc,const char * glueexts)1017 _evgl_api_gles1_ext_init(void *getproc, const char *glueexts)
1018 {
1019    const char *glexts;
1020    fp_getproc gp = (fp_getproc)getproc;
1021    int _curext_supported = 0;
1022    Evas_GL_API *gles1_funcs;
1023    Eina_Strbuf *sb = eina_strbuf_new();
1024    Eina_Strbuf *sboff = eina_strbuf_new();
1025 
1026 #ifdef GL_GLES
1027    EVGL_Resource *rsc;
1028    EGLint context_version;
1029    EGLDisplay dpy = EGLDISPLAY_GET(NULL);
1030 
1031    /* glGetString returns the information for the currently bound context
1032     * So, update glexts only if GLES1 context is currently bound.
1033     * Check here if GLESv1 is current
1034     */
1035    if (!(rsc=_evgl_tls_resource_get()))
1036      {
1037         ERR("Unable to initialize GLES1 extensions. Error retrieving tls");
1038         goto error;
1039      }
1040 
1041    if ((dpy == EGL_NO_DISPLAY) || !rsc->current_ctx)
1042      {
1043         DBG("Unable to initialize GLES1 extensions. Engine not initialized");
1044         goto error;
1045      }
1046 
1047    if (!eglQueryContext(dpy, rsc->current_ctx->context, EGL_CONTEXT_CLIENT_VERSION, &context_version))
1048      {
1049         ERR("Unable to initialize GLES1 extensions. eglQueryContext failed 0x%x", eglGetError());
1050         goto error;
1051      }
1052 
1053    if (context_version != EVAS_GL_GLES_1_X)
1054      {
1055         DBG("GLESv1 context not bound");
1056         goto error;
1057      }
1058 #endif
1059 
1060    gles1_funcs = _evgl_api_gles1_internal_get();
1061    if (!gles1_funcs || !gles1_funcs->glGetString)
1062      {
1063         ERR("Could not get address of glGetString in GLESv1 library!");
1064         goto error;
1065      }
1066 
1067    glexts = (const char *) gles1_funcs->glGetString(GL_EXTENSIONS);
1068    if (!glexts)
1069      {
1070         ERR("GLESv1:glGetString(GL_EXTENSIONS) returned NULL!");
1071         goto error;
1072      }
1073 
1074    /////////////////////////////////////////////////////////////////////////////////////////////////////
1075    // Scanning supported extensions, sets the variables
1076    /////////////////////////////////////////////////////////////////////////////////////////////////////
1077 
1078    // Preparing all the magic macros
1079 #define GETPROCADDR(sym) \
1080    (((!(*drvfunc)) && (gp)) ? (__typeof__((*drvfunc)))gp(sym) : (__typeof__((*drvfunc)))dlsym(RTLD_DEFAULT, sym))
1081 
1082 #define _EVASGL_EXT_BEGIN(name) \
1083    { \
1084       int *ext_support = &_gles1_ext_support_##name; \
1085       *ext_support = 0;
1086 
1087 #define _EVASGL_EXT_END() \
1088    }
1089 
1090 #define _EVASGL_EXT_CHECK_SUPPORT(name) \
1091    ((strstr(glexts, name) != NULL) || (strstr(glueexts, name) != NULL))
1092 
1093 #define _EVASGL_EXT_DISCARD_SUPPORT() \
1094    *ext_support = 0;
1095 
1096 #define _EVASGL_EXT_DRVNAME(name) \
1097    if (_EVASGL_EXT_CHECK_SUPPORT(#name)) *ext_support = 1;
1098 
1099 #define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
1100    if (_EVASGL_EXT_CHECK_SUPPORT(#name)) { *ext_support = 1; _gles1_ext_support_func_##name = 1; }
1101 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname) \
1102    if (_EVASGL_EXT_CHECK_SUPPORT(deskname)) *ext_support = 1;
1103 
1104 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
1105      { \
1106         ret (**drvfunc)param1 = &gles1_ext_sym_##name; \
1107         if (*ext_support == 1) \
1108           {
1109 
1110 #define _EVASGL_EXT_FUNCTION_END() \
1111           } \
1112         if ((*drvfunc) == NULL) _EVASGL_EXT_DISCARD_SUPPORT(); \
1113      }
1114 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN() \
1115    if (EINA_FALSE) \
1116      {
1117 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END() \
1118      }
1119 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name) \
1120    if ((*drvfunc) == NULL) *drvfunc = name;
1121 
1122 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name) \
1123    if ((*drvfunc) == NULL) \
1124      { \
1125         *drvfunc = GETPROCADDR(name); \
1126         evgl_safe_extension_add(name, (void *) (*drvfunc)); \
1127      } \
1128    else evgl_safe_extension_add(name, NULL);
1129 
1130 #ifdef _EVASGL_EXT_FUNCTION_WHITELIST
1131 # undef _EVASGL_EXT_FUNCTION_WHITELIST
1132 #endif
1133 #define _EVASGL_EXT_FUNCTION_WHITELIST(name) evgl_safe_extension_add(name, NULL);
1134 
1135 #define _EVASGL_EXT_ENABLE_GL_GLES 1
1136 #define _EVASGL_EXT_ENABLE_EGL 1
1137 #define _EVASGL_EXT_GLES1_ONLY 1
1138 
1139    // Okay, now we are ready to scan.
1140 #include "evas_gl_api_ext_def.h"
1141 
1142 #undef _EVASGL_EXT_GLES1_ONLY
1143 #undef _EVASGL_EXT_ENABLE_EGL
1144 #undef _EVASGL_EXT_ENABLE_GL_GLES
1145 #undef _EVASGL_EXT_FUNCTION_WHITELIST
1146 #undef _EVASGL_EXT_CHECK_SUPPORT
1147 #undef _EVASGL_EXT_DISCARD_SUPPORT
1148 #undef _EVASGL_EXT_BEGIN
1149 #undef _EVASGL_EXT_END
1150 #undef _EVASGL_EXT_DRVNAME
1151 #undef _EVASGL_EXT_DRVNAME_PRIVATE
1152 #undef _EVASGL_EXT_DRVNAME_DESKTOP
1153 #undef _EVASGL_EXT_FUNCTION_BEGIN
1154 #undef _EVASGL_EXT_FUNCTION_END
1155 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
1156 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
1157 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
1158 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
1159 #undef GETPROCADDR
1160 
1161 #define _EVASGL_EXT_BEGIN(name) \
1162      if (_gles1_ext_support_##name != 0) \
1163        { \
1164           eina_strbuf_append(sb, #name" "); \
1165           _curext_supported = 1; \
1166        } \
1167      else _curext_supported = 0;
1168 
1169 
1170    /////////////////////////////////////////////////////////////////////////////////////////////////////
1171    // Scanning again to add to the gles1 ext string list
1172    /////////////////////////////////////////////////////////////////////////////////////////////////////
1173 
1174 #define _EVASGL_EXT_END()
1175 #define _EVASGL_EXT_CHECK_SUPPORT(name)
1176 #define _EVASGL_EXT_DISCARD_SUPPORT()
1177 #define _EVASGL_EXT_DRVNAME_PRINT(name) \
1178      { \
1179         eina_strbuf_append(sb, name" "); \
1180         if ((strncmp(name, "GL_", 3) == 0) && (strstr(eina_strbuf_string_get(sboff), name) == NULL)) \
1181           eina_strbuf_append(sboff, name" "); \
1182      }
1183 #define _EVASGL_EXT_DRVNAME(name) \
1184    if (_curext_supported) \
1185       _EVASGL_EXT_DRVNAME_PRINT(#name)
1186 #define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
1187    if (_curext_supported && _gles1_ext_support_func_##name) \
1188       _EVASGL_EXT_DRVNAME_PRINT(#name)
1189 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
1190 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2)
1191 #define _EVASGL_EXT_FUNCTION_END()
1192 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
1193 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
1194 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
1195 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
1196 #define _EVASGL_EXT_ENABLE_GL_GLES 1
1197 #define _EVASGL_EXT_ENABLE_EGL 1
1198 
1199 #include "evas_gl_api_ext_def.h"
1200 
1201 #undef _EVASGL_EXT_ENABLE_EGL
1202 #undef _EVASGL_EXT_ENABLE_GL_GLES
1203 #undef _EVASGL_EXT_CHECK_SUPPORT
1204 #undef _EVASGL_EXT_DISCARD_SUPPORT
1205 #undef _EVASGL_EXT_BEGIN
1206 #undef _EVASGL_EXT_END
1207 #undef _EVASGL_EXT_DRVNAME_PRINT
1208 #undef _EVASGL_EXT_DRVNAME
1209 #undef _EVASGL_EXT_DRVNAME_PRIVATE
1210 #undef _EVASGL_EXT_DRVNAME_DESKTOP
1211 #undef _EVASGL_EXT_FUNCTION_BEGIN
1212 #undef _EVASGL_EXT_FUNCTION_END
1213 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
1214 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
1215 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
1216 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
1217 
1218    if (_gles1_ext_string) free(_gles1_ext_string);
1219    if (_gles1_ext_string_official) free(_gles1_ext_string_official);
1220    _gles1_ext_string = eina_strbuf_string_steal(sb);
1221    _gles1_ext_string_official = eina_strbuf_string_steal(sboff);
1222    eina_strbuf_free(sb);
1223    eina_strbuf_free(sboff);
1224 
1225    if (evgl_engine->api_debug_mode)
1226      DBG("GLES1: List of supported extensions:\n%s", _gles1_ext_string);
1227 
1228    // GLESv1 version has been initialized!
1229    _evgl_api_ext_status |= EVASGL_API_GLES1_EXT_INITIALIZED;
1230    return EINA_TRUE;
1231 error:
1232    eina_strbuf_free(sb);
1233    eina_strbuf_free(sboff);
1234    return EINA_FALSE;
1235 }
1236 
1237 void
evgl_api_gles1_ext_get(Evas_GL_API * gl_funcs,void * getproc,const char * glueexts)1238 evgl_api_gles1_ext_get(Evas_GL_API *gl_funcs, void *getproc, const char *glueexts)
1239 {
1240    if (!(_evgl_api_ext_status & EVASGL_API_GLES1_EXT_INITIALIZED))
1241      {
1242         DBG("Initializing GLESv1 extensions...");
1243         if (!_evgl_api_gles1_ext_init(getproc, glueexts))
1244           {
1245              ERR("GLESv1 extensions initialization failed");
1246              return;
1247           }
1248      }
1249 
1250 #define ORD(f) EVAS_API_OVERRIDE(f, gl_funcs, evgl_gles1_)
1251 
1252    /////////////////////////////////////////////////////////////////////////////////////////////////////
1253    // Extension HEADER
1254    /////////////////////////////////////////////////////////////////////////////////////////////////////
1255 #define _EVASGL_EXT_CHECK_SUPPORT(name)
1256 #define _EVASGL_EXT_DISCARD_SUPPORT()
1257 #define _EVASGL_EXT_BEGIN(name) \
1258    if (_gles1_ext_support_##name != 0) \
1259      {
1260 #define _EVASGL_EXT_END() \
1261      }
1262 #define _EVASGL_EXT_DRVNAME(name)
1263 #define _EVASGL_EXT_DRVNAME_PRIVATE(name)
1264 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
1265 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
1266    ORD(name);
1267 #define _EVASGL_EXT_FUNCTION_END()
1268 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
1269 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
1270 #define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param1, param2)
1271 #define _EVASGL_EXT_FUNCTION_PRIVATE_END()
1272 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
1273 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
1274 
1275 #undef _EVASGL_EXT_WHITELIST_ONLY
1276 #define _EVASGL_EXT_WHITELIST_ONLY 0
1277 #define _EVASGL_EXT_ENABLE_GL_GLES 1
1278 #define _EVASGL_EXT_ENABLE_EGL 1
1279 
1280 #include "evas_gl_api_ext_def.h"
1281 
1282 #undef _EVASGL_EXT_ENABLE_EGL
1283 #undef _EVASGL_EXT_ENABLE_GL_GLES
1284 #undef _EVASGL_EXT_CHECK_SUPPORT
1285 #undef _EVASGL_EXT_DISCARD_SUPPORT
1286 #undef _EVASGL_EXT_BEGIN
1287 #undef _EVASGL_EXT_END
1288 #undef _EVASGL_EXT_DRVNAME
1289 #undef _EVASGL_EXT_DRVNAME_PRIVATE
1290 #undef _EVASGL_EXT_DRVNAME_DESKTOP
1291 #undef _EVASGL_EXT_FUNCTION_BEGIN
1292 #undef _EVASGL_EXT_FUNCTION_END
1293 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
1294 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
1295 #undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
1296 #undef _EVASGL_EXT_FUNCTION_PRIVATE_END
1297 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
1298 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
1299    /////////////////////////////////////////////////////////////////////////////////////////////////////
1300 #undef ORD
1301 
1302 }
1303 
1304 Eina_Bool
_evgl_api_gles3_ext_init(void * getproc,const char * glueexts)1305 _evgl_api_gles3_ext_init(void *getproc, const char *glueexts)
1306 {
1307    const char *glexts;
1308    fp_getproc gp = (fp_getproc)getproc;
1309    int _curext_supported = 0;
1310    Evas_GL_API *gles3_funcs;
1311    Eina_Strbuf *sb = eina_strbuf_new();
1312    Eina_Strbuf *sboff = eina_strbuf_new();
1313 
1314 #ifdef GL_GLES
1315    EVGL_Resource *rsc;
1316    EGLint context_version;
1317    EGLDisplay dpy = EGLDISPLAY_GET(NULL);
1318 
1319    /* glGetString returns the information for the currently bound context
1320     * So, update gles3_exts only if GLES3 context is currently bound.
1321     * Check here if GLESv3 is current
1322     */
1323    if (!(rsc=_evgl_tls_resource_get()))
1324      {
1325         ERR("Unable to initialize GLES3 extensions. Error retrieving tls");
1326         goto error;
1327      }
1328 
1329    if ((dpy == EGL_NO_DISPLAY) || !rsc->current_ctx)
1330      {
1331         DBG("Unable to initialize GLES3 extensions. Engine not initialized");
1332         goto error;
1333      }
1334 
1335    if (!eglQueryContext(dpy, rsc->current_ctx->context, EGL_CONTEXT_CLIENT_VERSION, &context_version))
1336      {
1337         ERR("Unable to initialize GLES3 extensions. eglQueryContext failed 0x%x", eglGetError());
1338         goto error;
1339      }
1340 
1341    if (context_version != EVAS_GL_GLES_3_X)
1342      {
1343         DBG("GLESv3 context not bound");
1344         goto error;
1345      }
1346 #endif
1347 
1348    _gles3_ext_plist = eina_array_new(1);
1349    gles3_funcs = _evgl_api_gles3_internal_get();
1350    if (!gles3_funcs || !gles3_funcs->glGetString)
1351      {
1352         ERR("Could not get address of glGetString in GLESv3 library!");
1353         goto error;
1354      }
1355 
1356    glexts = (const char *) gles3_funcs->glGetString(GL_EXTENSIONS);
1357    if (!glexts)
1358      {
1359         ERR("GLESv3:glGetString(GL_EXTENSIONS) returned NULL!");
1360         goto error;
1361      }
1362 
1363    /////////////////////////////////////////////////////////////////////////////////////////////////////
1364    // Scanning supported extensions, sets the variables
1365    /////////////////////////////////////////////////////////////////////////////////////////////////////
1366 
1367    // Preparing all the magic macros
1368 #define GETPROCADDR(sym) \
1369       (((!(*drvfunc)) && (gp)) ? (__typeof__((*drvfunc)))gp(sym) : (__typeof__((*drvfunc)))dlsym(RTLD_DEFAULT, sym))
1370 
1371 #define _EVASGL_EXT_BEGIN(name) \
1372    { \
1373       int *ext_support = &_gles3_ext_support_##name; \
1374       *ext_support = 0;
1375 
1376 #define _EVASGL_EXT_END() \
1377    }
1378 
1379 #define _EVASGL_EXT_CHECK_SUPPORT(name) \
1380    ((strstr(glexts, name) != NULL) || (strstr(glueexts, name) != NULL))
1381 
1382 #define _EVASGL_EXT_DISCARD_SUPPORT() \
1383    *ext_support = 0;
1384 
1385 #define _EVASGL_EXT_DRVNAME(name) \
1386    if (_EVASGL_EXT_CHECK_SUPPORT(#name)) *ext_support = 1;
1387 
1388 #define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
1389    if (_EVASGL_EXT_CHECK_SUPPORT(#name)) { *ext_support = 1; _gles3_ext_support_func_##name = 1; }
1390 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname) \
1391    if (_EVASGL_EXT_CHECK_SUPPORT(deskname)) *ext_support = 1;
1392 
1393 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
1394      { \
1395         ret (**drvfunc)param1 = &gles3_ext_sym_##name; \
1396         if (*ext_support == 1) \
1397           {
1398 
1399 #define _EVASGL_EXT_FUNCTION_END() \
1400           } \
1401         if ((*drvfunc) == NULL) _EVASGL_EXT_DISCARD_SUPPORT(); \
1402      }
1403 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
1404 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
1405 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name) \
1406    if ((*drvfunc) == NULL) *drvfunc = name;
1407 
1408 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name) \
1409    if ((*drvfunc) == NULL) \
1410      { \
1411         *drvfunc = GETPROCADDR(name); \
1412         evgl_safe_extension_add(name, (void *) (*drvfunc)); \
1413      } \
1414    else evgl_safe_extension_add(name, NULL);
1415 
1416 #ifdef _EVASGL_EXT_FUNCTION_WHITELIST
1417 # undef _EVASGL_EXT_FUNCTION_WHITELIST
1418 #endif
1419 #define _EVASGL_EXT_FUNCTION_WHITELIST(name) evgl_safe_extension_add(name, NULL);
1420 
1421 #define _EVASGL_EXT_ENABLE_GL_GLES 1
1422 #define _EVASGL_EXT_ENABLE_EGL 1
1423 
1424    // Okay, now we are ready to scan.
1425 #include "evas_gl_api_ext_def.h"
1426 
1427 #undef _EVASGL_EXT_ENABLE_EGL
1428 #undef _EVASGL_EXT_ENABLE_GL_GLES
1429 #undef _EVASGL_EXT_FUNCTION_WHITELIST
1430 #undef _EVASGL_EXT_CHECK_SUPPORT
1431 #undef _EVASGL_EXT_DISCARD_SUPPORT
1432 #undef _EVASGL_EXT_BEGIN
1433 #undef _EVASGL_EXT_END
1434 #undef _EVASGL_EXT_DRVNAME
1435 #undef _EVASGL_EXT_DRVNAME_PRIVATE
1436 #undef _EVASGL_EXT_DRVNAME_DESKTOP
1437 #undef _EVASGL_EXT_FUNCTION_BEGIN
1438 #undef _EVASGL_EXT_FUNCTION_END
1439 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
1440 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
1441 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
1442 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
1443 #undef GETPROCADDR
1444 
1445 #define _EVASGL_EXT_BEGIN(name) \
1446      if (_gles3_ext_support_##name != 0) \
1447        { \
1448           eina_strbuf_append(sb, #name" "); \
1449           _curext_supported = 1; \
1450        } \
1451      else _curext_supported = 0;
1452 
1453 
1454    /////////////////////////////////////////////////////////////////////////////////////////////////////
1455    // Scanning again to add to the gles3 ext string list
1456    /////////////////////////////////////////////////////////////////////////////////////////////////////
1457 
1458 #define _EVASGL_EXT_END()
1459 #define _EVASGL_EXT_CHECK_SUPPORT(name)
1460 #define _EVASGL_EXT_DISCARD_SUPPORT()
1461 #define _EVASGL_EXT_DRVNAME_PRINT(name) \
1462      { \
1463         eina_strbuf_append(sb, name" "); \
1464         if ((strncmp(name, "GL_", 3) == 0) && (strstr(eina_strbuf_string_get(sboff), name) == NULL)) \
1465           { \
1466              eina_strbuf_append(sboff, name" "); \
1467              eina_array_push(_gles3_ext_plist, name); \
1468           } \
1469      }
1470 #define _EVASGL_EXT_DRVNAME(name) \
1471    if (_curext_supported) \
1472       _EVASGL_EXT_DRVNAME_PRINT(#name)
1473 #define _EVASGL_EXT_DRVNAME_PRIVATE(name) \
1474    if (_curext_supported && _gles3_ext_support_func_##name) \
1475       _EVASGL_EXT_DRVNAME_PRINT(#name)
1476 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
1477 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2)
1478 #define _EVASGL_EXT_FUNCTION_END()
1479 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
1480 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
1481 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
1482 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
1483 
1484 #define _EVASGL_EXT_ENABLE_GL_GLES 1
1485 #define _EVASGL_EXT_ENABLE_EGL 1
1486 
1487 #include "evas_gl_api_ext_def.h"
1488 
1489 #undef _EVASGL_EXT_ENABLE_EGL
1490 #undef _EVASGL_EXT_ENABLE_GL_GLES
1491 #undef _EVASGL_EXT_CHECK_SUPPORT
1492 #undef _EVASGL_EXT_DISCARD_SUPPORT
1493 #undef _EVASGL_EXT_BEGIN
1494 #undef _EVASGL_EXT_END
1495 #undef _EVASGL_EXT_DRVNAME_PRINT
1496 #undef _EVASGL_EXT_DRVNAME
1497 #undef _EVASGL_EXT_DRVNAME_PRIVATE
1498 #undef _EVASGL_EXT_DRVNAME_DESKTOP
1499 #undef _EVASGL_EXT_FUNCTION_BEGIN
1500 #undef _EVASGL_EXT_FUNCTION_END
1501 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
1502 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
1503 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
1504 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
1505 
1506    if (_gles3_ext_string) free(_gles3_ext_string);
1507    if (_gles3_ext_string_official) free(_gles3_ext_string_official);
1508    _gles3_ext_string = eina_strbuf_string_steal(sb);
1509    _gles3_ext_string_official = eina_strbuf_string_steal(sboff);
1510    eina_strbuf_free(sb);
1511    eina_strbuf_free(sboff);
1512 
1513    if (evgl_engine->api_debug_mode)
1514      DBG("GLES3: List of supported extensions:\n%s", _gles3_ext_string);
1515 
1516    // GLESv3 version has been initialized!
1517    _evgl_api_ext_status |= EVASGL_API_GLES3_EXT_INITIALIZED;
1518    return EINA_TRUE;
1519 error:
1520    eina_strbuf_free(sb);
1521    eina_strbuf_free(sboff);
1522    return EINA_FALSE;
1523 }
1524 
1525 void
evgl_api_gles3_ext_get(Evas_GL_API * gl_funcs,void * getproc,const char * glueexts)1526 evgl_api_gles3_ext_get(Evas_GL_API *gl_funcs, void *getproc, const char *glueexts)
1527 {
1528    if (!(_evgl_api_ext_status & EVASGL_API_GLES3_EXT_INITIALIZED))
1529      {
1530         DBG("Initializing GLESv3 extensions...");
1531         if (!_evgl_api_gles3_ext_init(getproc, glueexts))
1532           {
1533              ERR("GLESv3 extensions initialization failed");
1534              return;
1535           }
1536      }
1537 
1538 #define ORD(f) EVAS_API_OVERRIDE(f, gl_funcs, evgl_gles3_)
1539 
1540    /////////////////////////////////////////////////////////////////////////////////////////////////////
1541    // Extension HEADER
1542    /////////////////////////////////////////////////////////////////////////////////////////////////////
1543 #define _EVASGL_EXT_CHECK_SUPPORT(name)
1544 #define _EVASGL_EXT_DISCARD_SUPPORT()
1545 #define _EVASGL_EXT_BEGIN(name) \
1546    if (_gles3_ext_support_##name != 0) \
1547      {
1548 #define _EVASGL_EXT_END() \
1549      }
1550 #define _EVASGL_EXT_DRVNAME(name)
1551 #define _EVASGL_EXT_DRVNAME_PRIVATE(name)
1552 #define _EVASGL_EXT_DRVNAME_DESKTOP(deskname)
1553 #define _EVASGL_EXT_FUNCTION_BEGIN(ret, name, param1, param2) \
1554    ORD(name);
1555 #define _EVASGL_EXT_FUNCTION_END()
1556 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN()
1557 #define _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END()
1558 #define _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN(ret, name, param1, param2)
1559 #define _EVASGL_EXT_FUNCTION_PRIVATE_END()
1560 #define _EVASGL_EXT_FUNCTION_DRVFUNC(name)
1561 #define _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR(name)
1562 
1563 #undef _EVASGL_EXT_WHITELIST_ONLY
1564 #define _EVASGL_EXT_WHITELIST_ONLY 0
1565 
1566 #define _EVASGL_EXT_ENABLE_GL_GLES 1
1567 #define _EVASGL_EXT_ENABLE_EGL 1
1568 
1569 #include "evas_gl_api_ext_def.h"
1570 
1571 #undef _EVASGL_EXT_ENABLE_EGL
1572 #undef _EVASGL_EXT_ENABLE_GL_GLES
1573 #undef _EVASGL_EXT_CHECK_SUPPORT
1574 #undef _EVASGL_EXT_DISCARD_SUPPORT
1575 #undef _EVASGL_EXT_BEGIN
1576 #undef _EVASGL_EXT_END
1577 #undef _EVASGL_EXT_DRVNAME
1578 #undef _EVASGL_EXT_DRVNAME_PRIVATE
1579 #undef _EVASGL_EXT_DRVNAME_DESKTOP
1580 #undef _EVASGL_EXT_FUNCTION_BEGIN
1581 #undef _EVASGL_EXT_FUNCTION_END
1582 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_BEGIN
1583 #undef _EVASGL_EXT_FUNCTION_DISABLE_FOR_GLES1_END
1584 #undef _EVASGL_EXT_FUNCTION_PRIVATE_BEGIN
1585 #undef _EVASGL_EXT_FUNCTION_PRIVATE_END
1586 #undef _EVASGL_EXT_FUNCTION_DRVFUNC
1587 #undef _EVASGL_EXT_FUNCTION_DRVFUNC_PROCADDR
1588    /////////////////////////////////////////////////////////////////////////////////////////////////////
1589 #undef ORD
1590 
1591 }
1592 
1593 const char *
evgl_api_ext_egl_string_get(void)1594 evgl_api_ext_egl_string_get(void)
1595 {
1596 #ifdef GL_GLES
1597    if (!(_evgl_api_ext_status & EVASGL_API_EGL_EXT_INITIALIZED))
1598      {
1599         ERR("EVGL extension for egl is not yet initialized.");
1600         return NULL;
1601      }
1602 
1603    return _egl_ext_string;
1604 #else
1605    return "";
1606 #endif
1607 }
1608 
1609 const char *
evgl_api_ext_string_get(Eina_Bool official,int version)1610 evgl_api_ext_string_get(Eina_Bool official, int version)
1611 {
1612    if (_evgl_api_ext_status < 1)
1613      {
1614         ERR("EVGL extension is not yet initialized.");
1615         return NULL;
1616      }
1617 
1618    if (version == EVAS_GL_GLES_1_X)
1619      return (official?_gles1_ext_string_official:_gles1_ext_string);
1620 
1621    if (version == EVAS_GL_GLES_3_X)
1622      return (official?_gles3_ext_string_official:_gles3_ext_string);
1623 
1624    return (official?_gl_ext_string_official:_gl_ext_string);
1625 }
1626 
1627 const char *
evgl_api_ext_stringi_get(GLuint index,int version)1628 evgl_api_ext_stringi_get(GLuint index, int version)
1629 {
1630    if (_evgl_api_ext_status < 1)
1631      {
1632         ERR("EVGL extension is not yet initialized.");
1633         return NULL;
1634      }
1635 
1636    if (version == EVAS_GL_GLES_3_X)
1637      {
1638         if (index < evgl_api_ext_num_extensions_get(version))
1639           {
1640              return eina_array_data_get(_gles3_ext_plist, index);
1641           }
1642      }
1643 
1644    return NULL;
1645 }
1646 
1647 GLuint
evgl_api_ext_num_extensions_get(int version)1648 evgl_api_ext_num_extensions_get(int version)
1649 {
1650    if (version == EVAS_GL_GLES_3_X)
1651      return eina_array_count_get(_gles3_ext_plist);
1652 
1653    return 0;
1654 }
1655