1 #include "evas_common_private.h" /* Also includes international specific stuff */
2 #include "evas_engine.h"
3 #include "../gl_common/evas_gl_define.h"
4 #include "../software_generic/evas_native_common.h"
5 
6 #ifdef HAVE_DLSYM
7 # include <dlfcn.h>      /* dlopen,dlclose,etc */
8 #else
9 # error gl_x11 should not get compiled if dlsym is not found on the system!
10 #endif
11 
12 #define EVAS_GL_NO_GL_H_CHECK 1
13 #include "Evas_GL.h"
14 
15 #define EVAS_GL_UPDATE_TILE_SIZE 16
16 
17 typedef struct _Render_Engine               Render_Engine;
18 
19 struct _Render_Engine
20 {
21    Render_Output_GL_Generic generic;
22 };
23 
24 const char *debug_dir;
25 int swap_buffer_debug_mode = -1;
26 int swap_buffer_debug = 0;
27 int partial_render_debug = -1;
28 int extn_have_buffer_age = 1;
29 
30 static int initted = 0;
31 static int gl_wins = 0;
32 #ifdef GL_GLES
33 static int extn_have_y_inverted = 1;
34 #endif
35 
36 typedef void            (*_eng_fn) (void);
37 typedef _eng_fn         (*glsym_func_eng_fn) ();
38 typedef void            (*glsym_func_void) ();
39 typedef void           *(*glsym_func_void_ptr) ();
40 typedef int             (*glsym_func_int) ();
41 typedef unsigned int    (*glsym_func_uint) ();
42 typedef const char     *(*glsym_func_const_char_ptr) ();
43 
44 Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL;
45 Evas_GL_Common_Image_Call glsym_evas_gl_common_image_unref = NULL;
46 Evas_GL_Common_Image_Call glsym_evas_gl_common_image_free = NULL;
47 Evas_GL_Common_Image_Call glsym_evas_gl_common_image_native_disable = NULL;
48 Evas_GL_Common_Image_Call glsym_evas_gl_common_image_native_enable = NULL;
49 Evas_GL_Common_Image_New_From_Data glsym_evas_gl_common_image_new_from_data = NULL;
50 Evas_GL_Common_Context_Call glsym_evas_gl_common_image_all_unload = NULL;
51 Evas_GL_Preload glsym_evas_gl_preload_init = NULL;
52 Evas_GL_Preload glsym_evas_gl_preload_shutdown = NULL;
53 EVGL_Engine_Call glsym_evgl_engine_shutdown = NULL;
54 EVGL_Native_Surface_Call glsym_evgl_native_surface_buffer_get = NULL;
55 EVGL_Native_Surface_Yinvert_Call glsym_evgl_native_surface_yinvert_get = NULL;
56 EVGL_Current_Native_Context_Get_Call glsym_evgl_current_native_context_get = NULL;
57 Evas_Gl_Symbols glsym_evas_gl_symbols = NULL;
58 
59 Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL;
60 Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush = NULL;
61 Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free = NULL;
62 Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use = NULL;
63 Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe = NULL;
64 Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done = NULL;
65 Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize = NULL;
66 Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump = NULL;
67 Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock = NULL;
68 Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL;
69 Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL;
70 
71 glsym_func_void     glsym_evas_gl_common_shaders_flush = NULL;
72 glsym_func_void     glsym_evas_gl_common_error_set = NULL;
73 glsym_func_int      glsym_evas_gl_common_error_get = NULL;
74 glsym_func_void_ptr glsym_evas_gl_common_current_context_get = NULL;
75 
76 #ifdef GL_GLES
77 
78 _eng_fn      (*glsym_eglGetProcAddress)            (const char *a) = NULL;
79 EGLImageKHR  (*glsym_evas_gl_common_eglCreateImage)(EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const EGLAttrib *e) = NULL;
80 int          (*glsym_evas_gl_common_eglDestroyImage) (EGLDisplay a, void *b) = NULL;
81 void         (*glsym_glEGLImageTargetTexture2DOES) (int a, void *b)  = NULL;
82 unsigned int (*glsym_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL;
83 unsigned int (*glsym_eglSetDamageRegionKHR)  (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL;
84 unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, /*struct wl_resource */void *b, EGLint c, EGLint *d) = NULL;
85 
86 #else
87 
88 typedef XID     (*glsym_func_xid) ();
89 
90 _eng_fn  (*glsym_glXGetProcAddress)  (const char *a) = NULL;
91 void     (*glsym_glXBindTexImage)    (Display *a, GLXDrawable b, int c, int *d) = NULL;
92 void     (*glsym_glXReleaseTexImage) (Display *a, GLXDrawable b, int c) = NULL;
93 int      (*glsym_glXGetVideoSync)    (unsigned int *a) = NULL;
94 int      (*glsym_glXWaitVideoSync)   (int a, int b, unsigned int *c) = NULL;
95 XID      (*glsym_glXCreatePixmap)    (Display *a, void *b, Pixmap c, const int *d) = NULL;
96 void     (*glsym_glXDestroyPixmap)   (Display *a, XID b) = NULL;
97 void     (*glsym_glXQueryDrawable)   (Display *a, XID b, int c, unsigned int *d) = NULL;
98 int      (*glsym_glXSwapIntervalSGI) (int a) = NULL;
99 void     (*glsym_glXSwapIntervalEXT) (Display *s, GLXDrawable b, int c) = NULL;
100 void     (*glsym_glXReleaseBuffersMESA)   (Display *a, XID b) = NULL;
101 
102 #endif
103 
104 static inline Outbuf *
eng_get_ob(Render_Engine * re)105 eng_get_ob(Render_Engine *re)
106 {
107    return re->generic.software.ob;
108 }
109 
110 //----------------------------------------------------------//
111 // NEW_EVAS_GL Engine Functions
112 static void *
evgl_eng_display_get(void * data)113 evgl_eng_display_get(void *data)
114 {
115    Render_Engine *re = (Render_Engine *)data;
116 
117    /* EVGLINIT(re, NULL); */
118    if (!re)
119      {
120         ERR("Invalid Render Engine Data!");
121         return NULL;
122      }
123 
124 #ifdef GL_GLES
125    if (eng_get_ob(re))
126       return (void*)eng_get_ob(re)->egl_disp;
127 #else
128    if (eng_get_ob(re)->info)
129       return (void*)eng_get_ob(re)->info->info.display;
130 #endif
131    else
132       return NULL;
133 }
134 
135 static void *
evgl_eng_evas_surface_get(void * data)136 evgl_eng_evas_surface_get(void *data)
137 {
138    Render_Engine *re = (Render_Engine *)data;
139 
140    /* EVGLINIT(re, NULL); */
141    if (!re)
142      {
143         ERR("Invalid Render Engine Data!");
144         return NULL;
145      }
146 
147 #ifdef GL_GLES
148    if (eng_get_ob(re))
149       return (void*)eng_get_ob(re)->egl_surface;
150 #else
151    if (eng_get_ob(re))
152       return (void*)eng_get_ob(re)->win;
153 #endif
154    else
155       return NULL;
156 }
157 
158 #ifdef GL_GLES
159 static EGLDisplay main_dpy  = EGL_NO_DISPLAY;
160 static EGLSurface main_draw = EGL_NO_SURFACE;
161 static EGLSurface main_read = EGL_NO_SURFACE;
162 static EGLContext main_ctx  = EGL_NO_CONTEXT;
163 
164 EGLContext
evas_eglGetCurrentContext(void)165 evas_eglGetCurrentContext(void)
166 {
167    if (eina_main_loop_is())
168      return main_ctx;
169    else
170      return eglGetCurrentContext();
171 }
172 
173 EGLSurface
evas_eglGetCurrentSurface(EGLint readdraw)174 evas_eglGetCurrentSurface(EGLint readdraw)
175 {
176    if (eina_main_loop_is())
177      return (readdraw == EGL_READ) ? main_read : main_draw;
178    else
179      return eglGetCurrentSurface(readdraw);
180 }
181 
182 EGLDisplay
evas_eglGetCurrentDisplay(void)183 evas_eglGetCurrentDisplay(void)
184 {
185    if (eina_main_loop_is())
186      return main_dpy;
187    else
188      return eglGetCurrentDisplay();
189 }
190 
191 EGLBoolean
evas_eglMakeCurrent(EGLDisplay dpy,EGLSurface draw,EGLSurface read,EGLContext ctx)192 evas_eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
193 {
194    if (eina_main_loop_is())
195      {
196         EGLBoolean ret;
197 
198         if ((dpy == main_dpy) && (draw == main_draw) &&
199             (read == main_read) && (ctx == main_ctx))
200           return 1;
201 
202         ret = eglMakeCurrent(dpy, draw, read, ctx);
203         if (ret)
204           {
205              main_dpy  = dpy;
206              main_draw = draw;
207              main_read = read;
208              main_ctx  = ctx;
209           }
210         return ret;
211      }
212    else
213      return eglMakeCurrent(dpy, draw, read, ctx);
214 }
215 #endif
216 
217 static int
evgl_eng_make_current(void * data,void * surface,void * context,int flush)218 evgl_eng_make_current(void *data, void *surface, void *context, int flush)
219 {
220    Render_Engine *re = (Render_Engine *)data;
221    int ret = 0;
222 
223    /* EVGLINIT(re, 0); */
224    if (!re)
225      {
226         ERR("Invalid Render Engine Data!");
227         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
228         return 0;
229      }
230 
231 #ifdef GL_GLES
232    EGLContext ctx = (EGLContext)context;
233    EGLSurface sfc = (EGLSurface)surface;
234    EGLDisplay dpy = eng_get_ob(re)->egl_disp; //eglGetCurrentDisplay();
235 
236    if ((!context) && (!surface))
237      {
238         ret = evas_eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
239         if (!ret)
240           {
241              int err = eglGetError();
242              glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
243              ERR("evas_eglMakeCurrent() failed! Error Code=%#x", err);
244              return 0;
245           }
246         return 1;
247      }
248 
249    // FIXME: Check (eglGetCurrentDisplay() != dpy) ?
250    if ((evas_eglGetCurrentContext() != ctx) ||
251        (evas_eglGetCurrentSurface(EGL_READ) != sfc) ||
252        (evas_eglGetCurrentSurface(EGL_DRAW) != sfc) )
253      {
254 
255         //!!!! Does it need to be flushed with it's set to NULL above??
256         // Flush remainder of what's in Evas' pipeline
257         if (flush) eng_window_use(NULL);
258 
259         // Do a make current
260         ret = evas_eglMakeCurrent(dpy, sfc, sfc, ctx);
261 
262         if (!ret)
263           {
264              int err = eglGetError();
265              glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
266              ERR("evas_eglMakeCurrent() failed! Error Code=%#x", err);
267              return 0;
268           }
269      }
270 
271    return 1;
272 #else
273    GLXContext ctx = (GLXContext)context;
274    Window     sfc = (Window)surface;
275 
276    if ((!context) && (!surface))
277      {
278         ret = __glXMakeContextCurrent(eng_get_ob(re)->info->info.display, 0, NULL);
279         if (!ret)
280           {
281              ERR("glXMakeContextCurrent() failed!");
282              glsym_evas_gl_common_error_set(EVAS_GL_BAD_DISPLAY);
283              return 0;
284           }
285         return 1;
286      }
287 
288 
289    if ((glXGetCurrentContext() != ctx))
290      {
291         //!!!! Does it need to be flushed with it's set to NULL above??
292         // Flush remainder of what's in Evas' pipeline
293         if (flush) eng_window_use(NULL);
294 
295         // Do a make current
296         if ((sfc == eng_get_ob(re)->win) ||
297             (sfc == eng_get_ob(re)->glxwin))
298           ret = __glXMakeContextCurrent(eng_get_ob(re)->info->info.display,
299                                         eng_get_ob(re)->glxwin, ctx);
300         else
301           ret = __glXMakeContextCurrent(eng_get_ob(re)->info->info.display,
302                                         sfc, ctx);
303         if (!ret)
304           {
305              ERR("glXMakeContextCurrent() failed. Ret: %d! Context: %p Surface: %p",
306                  ret, (void *)ctx, (void *)sfc);
307              glsym_evas_gl_common_error_set(EVAS_GL_BAD_DISPLAY);
308              return 0;
309           }
310      }
311    return 1;
312 #endif
313 }
314 
315 
316 
317 static void *
evgl_eng_native_window_create(void * data)318 evgl_eng_native_window_create(void *data)
319 {
320    Render_Engine *re = (Render_Engine *)data;
321 
322    /* EVGLINIT(re, NULL); */
323    if (!re)
324      {
325         ERR("Invalid Render Engine Data!");
326         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
327         return NULL;
328      }
329 
330    XSetWindowAttributes attr;
331    Window win;
332 
333    attr.backing_store = NotUseful;
334    attr.override_redirect = True;
335    attr.border_pixel = 0;
336    attr.background_pixmap = None;
337    attr.bit_gravity = NorthWestGravity;
338    attr.win_gravity = NorthWestGravity;
339    attr.save_under = False;
340    attr.do_not_propagate_mask = NoEventMask;
341    attr.event_mask = 0;
342 
343    win = XCreateWindow(eng_get_ob(re)->info->info.display,
344                        eng_get_ob(re)->win,
345                        -20, -20, 2, 2, 0,
346                        CopyFromParent, InputOutput, CopyFromParent,
347                        CWBackingStore | CWOverrideRedirect |
348                        CWBorderPixel | CWBackPixmap |
349                        CWSaveUnder | CWDontPropagate |
350                        CWEventMask | CWBitGravity |
351                        CWWinGravity, &attr);
352    if (!win)
353      {
354         ERR("Creating native X window failed.");
355         glsym_evas_gl_common_error_set(EVAS_GL_BAD_DISPLAY);
356         return NULL;
357      }
358 
359    return (void*)win;
360 }
361 
362 static int
evgl_eng_native_window_destroy(void * data,void * native_window)363 evgl_eng_native_window_destroy(void *data, void *native_window)
364 {
365    Render_Engine *re = (Render_Engine *)data;
366 
367    /* EVGLINIT(re, 0); */
368    if (!re)
369      {
370         ERR("Invalid Render Engine Data!");
371         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
372         return 0;
373      }
374 
375    if (!native_window)
376      {
377         ERR("Inavlid native surface.");
378         glsym_evas_gl_common_error_set(EVAS_GL_BAD_NATIVE_WINDOW);
379         return 0;
380      }
381 
382    XDestroyWindow(eng_get_ob(re)->info->info.display, (Window)native_window);
383 
384    native_window = NULL;
385 
386    return 1;
387 }
388 
389 
390 // Theoretically, we wouldn't need this functoin if the surfaceless context
391 // is supported. But, until then...
392 static void *
evgl_eng_window_surface_create(void * data,void * native_window EINA_UNUSED)393 evgl_eng_window_surface_create(void *data, void *native_window EINA_UNUSED)
394 {
395    Render_Engine *re = (Render_Engine *)data;
396 
397    /* EVGLINIT(re, NULL); */
398    if (!re)
399      {
400         ERR("Invalid Render Engine Data!");
401         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
402         return NULL;
403      }
404 
405 #ifdef GL_GLES
406    EGLSurface surface = EGL_NO_SURFACE;
407 
408    // Create resource surface for EGL
409    surface = eglCreateWindowSurface(eng_get_ob(re)->egl_disp,
410                                     eng_get_ob(re)->egl_config,
411                                     (EGLNativeWindowType)native_window,
412                                     NULL);
413    if (!surface)
414      {
415         ERR("Creating window surface failed. Error: %#x.", eglGetError());
416         abort();
417         return NULL;
418      }
419 
420    return (void*)surface;
421 #else
422    /*
423    // We don't need to create new one for GLX
424    Window surface;
425 
426    surface = eng_get_ob(re)->win;
427 
428    return (void *)surface;
429    */
430    return (void *)native_window;
431 #endif
432 }
433 
434 static int
evgl_eng_window_surface_destroy(void * data,void * surface)435 evgl_eng_window_surface_destroy(void *data, void *surface)
436 {
437    Render_Engine *re = (Render_Engine *)data;
438 
439    /* EVGLINIT(re, 0); */
440    if (!re)
441      {
442         ERR("Invalid Render Engine Data!");
443         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
444         return 0;
445      }
446 
447 #ifdef GL_GLES
448    if (!surface)
449      {
450         ERR("Invalid surface.");
451         glsym_evas_gl_common_error_set(EVAS_GL_BAD_SURFACE);
452         return 0;
453      }
454 
455    eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)surface);
456 #endif
457 
458    return 1;
459    if (surface) return 0;
460 }
461 
462 static void *
evgl_eng_context_create(void * data,void * share_ctx,Evas_GL_Context_Version version)463 evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version)
464 {
465    Render_Engine *re = (Render_Engine *)data;
466 
467    /* EVGLINIT(re, NULL); */
468    if (!re)
469      {
470         ERR("Invalid Render Engine Data!");
471         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
472         return NULL;
473      }
474 
475    if ((version < EVAS_GL_GLES_1_X) || (version > EVAS_GL_GLES_3_X))
476      {
477         ERR("Invalid context version number %d", version);
478         glsym_evas_gl_common_error_set(EVAS_GL_BAD_PARAMETER);
479         return NULL;
480      }
481 
482 #ifdef GL_GLES
483    if ((version == EVAS_GL_GLES_3_X) &&
484        ((!eng_get_ob(re)->gl_context) || (eng_get_ob(re)->gl_context->gles_version != EVAS_GL_GLES_3_X)))
485      {
486         ERR("GLES 3 version not supported!");
487         glsym_evas_gl_common_error_set(EVAS_GL_BAD_ATTRIBUTE);
488         return NULL;
489      }
490    EGLContext context = EGL_NO_CONTEXT;
491    int context_attrs[3];
492 
493    /* Upgrade GLES 2 to GLES 3.
494     *
495     * FIXME: Maybe we don't want to do this, unless we have no choice.
496     * An alternative would be to use eglCreateImage() to share the indirect
497     * rendering FBO between two contexts of incompatible version. For now,
498     * we always upgrade the real context version to GLES 3 when it's available.
499     * But this leads to some issues, namely that the list of extensions is
500     * different, and MSAA surfaces also work differently.
501     */
502    if (gles3_supported && (version >= EVAS_GL_GLES_2_X))
503      version = 3;
504 
505    context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
506    context_attrs[1] = version;
507    context_attrs[2] = EGL_NONE;
508 
509    // Share context already assumes that it's sharing with evas' context
510    if (share_ctx)
511      {
512         context = eglCreateContext(eng_get_ob(re)->egl_disp,
513                                    eng_get_ob(re)->egl_config,
514                                    (EGLContext)share_ctx,
515                                    context_attrs);
516      }
517    else if ((version == EVAS_GL_GLES_1_X) || (version == EVAS_GL_GLES_3_X))
518      {
519         context = eglCreateContext(eng_get_ob(re)->egl_disp,
520                                    eng_get_ob(re)->egl_config,
521                                    NULL,
522                                    context_attrs);
523      }
524    else
525      {
526         context = eglCreateContext(eng_get_ob(re)->egl_disp,
527                                    eng_get_ob(re)->egl_config,
528                                    eng_get_ob(re)->egl_context, // Evas' GL Context
529                                    context_attrs);
530      }
531 
532    if (!context)
533      {
534         int err = eglGetError();
535         ERR("Engine Context Creations Failed. Error: %#x.", err);
536         glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
537         return NULL;
538      }
539 
540    return (void*)context;
541 #else
542    GLXContext context = NULL;
543 
544    // Share context already assumes that it's sharing with evas' context
545    if (share_ctx)
546      {
547         context = glXCreateContext(eng_get_ob(re)->info->info.display,
548                                    eng_get_ob(re)->visualinfo,
549                                    (GLXContext)share_ctx,
550                                    1);
551      }
552    else
553      {
554         context = glXCreateContext(eng_get_ob(re)->info->info.display,
555                                    eng_get_ob(re)->visualinfo,
556                                    eng_get_ob(re)->context,      // Evas' GL Context
557                                    1);
558      }
559 
560    if (!context)
561      {
562         ERR("Internal Resource Context Creations Failed.");
563         if(!(eng_get_ob(re)->info->info.display)) glsym_evas_gl_common_error_set(EVAS_GL_BAD_DISPLAY);
564         if(!(eng_get_ob(re)->win)) glsym_evas_gl_common_error_set(EVAS_GL_BAD_NATIVE_WINDOW);
565         return NULL;
566      }
567 
568    return (void*)context;
569 #endif
570 
571 }
572 
573 static int
evgl_eng_context_destroy(void * data,void * context)574 evgl_eng_context_destroy(void *data, void *context)
575 {
576    Render_Engine *re = (Render_Engine *)data;
577 
578    /* EVGLINIT(re, 0); */
579    if ((!re) || (!context))
580      {
581         ERR("Invalid Render Input Data. Engine: %p, Context: %p", data, context);
582         if (!re) glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
583         if (!context) glsym_evas_gl_common_error_set(EVAS_GL_BAD_CONTEXT);
584         return 0;
585      }
586 
587 #ifdef GL_GLES
588    eglDestroyContext(eng_get_ob(re)->egl_disp, (EGLContext)context);
589 #else
590    glXDestroyContext(eng_get_ob(re)->info->info.display, (GLXContext)context);
591 #endif
592 
593    return 1;
594 }
595 
596 static const char *
evgl_eng_string_get(void * data)597 evgl_eng_string_get(void *data)
598 {
599    Render_Engine *re = (Render_Engine *)data;
600 
601    /* EVGLINIT(re, NULL); */
602    if (!re)
603      {
604         ERR("Invalid Render Engine Data!");
605         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
606         return NULL;
607      }
608 
609 #ifdef GL_GLES
610    return eglQueryString(eng_get_ob(re)->egl_disp, EGL_EXTENSIONS);
611 #else
612    return glXQueryExtensionsString(eng_get_ob(re)->info->info.display,
613                                    eng_get_ob(re)->info->info.screen);
614 #endif
615 }
616 
617 static void *
evgl_eng_proc_address_get(const char * name)618 evgl_eng_proc_address_get(const char *name)
619 {
620 #ifdef GL_GLES
621    if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
622    return dlsym(RTLD_DEFAULT, name);
623 #else
624    if (glsym_glXGetProcAddress) return glsym_glXGetProcAddress(name);
625    return dlsym(RTLD_DEFAULT, name);
626 #endif
627 }
628 
629 static int
evgl_eng_rotation_angle_get(void * data)630 evgl_eng_rotation_angle_get(void *data)
631 {
632    Render_Engine *re = (Render_Engine *)data;
633 
634    /* EVGLINIT(re, 0); */
635    if (!re)
636      {
637         ERR("Invalid Render Engine Data!");
638         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
639         return 0;
640      }
641 
642    if ((eng_get_ob(re)) && (eng_get_ob(re)->gl_context))
643      return eng_get_ob(re)->gl_context->rot;
644    else
645      {
646         ERR("Unable to retrieve rotation angle.");
647         glsym_evas_gl_common_error_set(EVAS_GL_BAD_CONTEXT);
648         return 0;
649      }
650 }
651 
652 static void *
evgl_eng_pbuffer_surface_create(void * data,EVGL_Surface * sfc,const int * attrib_list)653 evgl_eng_pbuffer_surface_create(void *data, EVGL_Surface *sfc,
654                                 const int *attrib_list)
655 {
656    Render_Output_GL_Generic *re = data;
657 
658    // TODO: Add support for surfaceless pbuffers (EGL_NO_TEXTURE)
659    // TODO: Add support for EGL_MIPMAP_TEXTURE??? (GLX doesn't support them)
660 
661    if (attrib_list)
662      WRN("This PBuffer implementation does not support extra attributes yet");
663 
664 #ifdef GL_GLES
665    Evas_Engine_GL_Context *evasglctx;
666    int config_attrs[20];
667    int surface_attrs[20];
668    EGLSurface egl_sfc;
669    EGLConfig egl_cfg;
670    int num_config, i = 0;
671    EGLDisplay disp;
672    EGLContext ctx;
673 
674    disp = re->window_egl_display_get(re->software.ob);
675    evasglctx = re->window_gl_context_get(re->software.ob);
676    ctx = evasglctx->eglctxt;
677 
678 #if 0
679    // Choose framebuffer configuration
680    // DISABLED FOR NOW
681    if (sfc->pbuffer.color_fmt != EVAS_GL_NO_FBO)
682      {
683         config_attrs[i++] = EGL_RED_SIZE;
684         config_attrs[i++] = 1;
685         config_attrs[i++] = EGL_GREEN_SIZE;
686         config_attrs[i++] = 1;
687         config_attrs[i++] = EGL_BLUE_SIZE;
688         config_attrs[i++] = 1;
689 
690         if (sfc->pbuffer.color_fmt == EVAS_GL_RGBA_8888)
691           {
692              config_attrs[i++] = EGL_ALPHA_SIZE;
693              config_attrs[i++] = 1;
694              //config_attrs[i++] = EGL_BIND_TO_TEXTURE_RGBA;
695              //config_attrs[i++] = EGL_TRUE;
696           }
697         else
698           {
699              //config_attrs[i++] = EGL_BIND_TO_TEXTURE_RGB;
700              //config_attrs[i++] = EGL_TRUE;
701           }
702      }
703 
704    if (sfc->depth_fmt || sfc->depth_stencil_fmt)
705      {
706         config_attrs[i++] = EGL_DEPTH_SIZE;
707         config_attrs[i++] = 1;
708      }
709 
710    if (sfc->stencil_fmt || sfc->depth_stencil_fmt)
711      {
712         config_attrs[i++] = EGL_STENCIL_SIZE;
713         config_attrs[i++] = 1;
714      }
715 
716    config_attrs[i++] = EGL_RENDERABLE_TYPE;
717    if (gles3_supported)
718      config_attrs[i++] = EGL_OPENGL_ES3_BIT_KHR;
719    else
720      config_attrs[i++] = EGL_OPENGL_ES2_BIT;
721    config_attrs[i++] = EGL_SURFACE_TYPE;
722    config_attrs[i++] = EGL_PBUFFER_BIT;
723    config_attrs[i++] = EGL_NONE;
724 #else
725    // It looks like evas_eglMakeCurrent might fail if we use a different config from
726    // the actual display surface. This is weird.
727    i = 0;
728    config_attrs[i++] = EGL_CONFIG_ID;
729    config_attrs[i++] = 0;
730    config_attrs[i++] = EGL_NONE;
731    eglQueryContext(disp, ctx, EGL_CONFIG_ID, &config_attrs[1]);
732 #endif
733 
734    if (!eglChooseConfig(disp, config_attrs, &egl_cfg, 1, &num_config)
735        || (num_config < 1))
736      {
737         int err = eglGetError();
738         glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
739         ERR("eglChooseConfig failed with error %x", err);
740         return NULL;
741      }
742 
743    // Now, choose the config for the PBuffer
744    i = 0;
745    surface_attrs[i++] = EGL_WIDTH;
746    surface_attrs[i++] = sfc->w;
747    surface_attrs[i++] = EGL_HEIGHT;
748    surface_attrs[i++] = sfc->h;
749 #if 0
750    // Adding these parameters will trigger EGL_BAD_ATTRIBUTE because
751    // the config also requires EGL_BIND_TO_TEXTURE_RGB[A]. But some drivers
752    // don't support those configs (eg. nvidia)
753    surface_attrs[i++] = EGL_TEXTURE_FORMAT;
754    if (sfc->pbuffer.color_fmt == EVAS_GL_RGB_888)
755      surface_attrs[i++] = EGL_TEXTURE_RGB;
756    else
757      surface_attrs[i++] = EGL_TEXTURE_RGBA;
758    surface_attrs[i++] = EGL_TEXTURE_TARGET;
759    surface_attrs[i++] = EGL_TEXTURE_2D;
760    surface_attrs[i++] = EGL_MIPMAP_TEXTURE;
761    surface_attrs[i++] = EINA_TRUE;
762 #endif
763    surface_attrs[i++] = EGL_NONE;
764 
765    egl_sfc = eglCreatePbufferSurface(disp, egl_cfg, surface_attrs);
766    if (!egl_sfc)
767      {
768         int err = eglGetError();
769         glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
770         ERR("eglCreatePbufferSurface failed with error %x", err);
771         return NULL;
772      }
773 
774    return egl_sfc;
775 #else
776    Evas_Engine_GL_Context *evasglctx;
777    GLXPbuffer pbuf;
778    GLXFBConfig *cfgs;
779    int config_attrs[20];
780    int surface_attrs[20];
781    int ncfg = 0, i;
782 
783    evasglctx = re->window_gl_context_get(re->software.ob);
784 
785 #ifndef GLX_VISUAL_ID
786 # define GLX_VISUAL_ID 0x800b
787 #endif
788 
789    i = 0;
790 #if 0
791    // DISABLED BECAUSE BadMatch HAPPENS
792    if (sfc->pbuffer.color_fmt != EVAS_GL_NO_FBO)
793      {
794         config_attrs[i++] = GLX_BUFFER_SIZE;
795         if (sfc->pbuffer.color_fmt == EVAS_GL_RGBA_8888)
796           {
797              config_attrs[i++] = 32;
798              //config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGBA_EXT;
799              //config_attrs[i++] = 1;
800           }
801         else
802           {
803              config_attrs[i++] = 24;
804              //config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGB_EXT;
805              //config_attrs[i++] = 1;
806           }
807      }
808    if (sfc->depth_fmt)
809      {
810         config_attrs[i++] = GLX_DEPTH_SIZE;
811         config_attrs[i++] = 24; // FIXME: This should depend on the requested bits
812      }
813    if (sfc->stencil_fmt)
814      {
815         config_attrs[i++] = GLX_STENCIL_SIZE;
816         config_attrs[i++] = 8; // FIXME: This should depend on the requested bits
817      }
818    //config_attrs[i++] = GLX_VISUAL_ID;
819    //config_attrs[i++] = XVisualIDFromVisual(vis);
820 #else
821    config_attrs[i++] = GLX_FBCONFIG_ID;
822    if (sfc->pbuffer.color_fmt == EVAS_GL_RGB_888)
823      config_attrs[i++] = evasglctx->glxcfg_rgb;
824    else
825      config_attrs[i++] = evasglctx->glxcfg_rgba;
826 #endif
827    config_attrs[i++] = 0;
828 
829    cfgs = glXChooseFBConfig(re->software.ob->disp, re->software.ob->screen,
830                             config_attrs, &ncfg);
831    if (!cfgs || !ncfg)
832      {
833         ERR("GLX failed to find a valid config for the pbuffer");
834         if (cfgs) XFree(cfgs);
835         return NULL;
836      }
837 
838    i = 0;
839    surface_attrs[i++] = GLX_LARGEST_PBUFFER;
840    surface_attrs[i++] = 0;
841    surface_attrs[i++] = GLX_PBUFFER_WIDTH;
842    surface_attrs[i++] = sfc->w;
843    surface_attrs[i++] = GLX_PBUFFER_HEIGHT;
844    surface_attrs[i++] = sfc->h;
845    surface_attrs[i++] = 0;
846    pbuf = glXCreatePbuffer(re->software.ob->disp, cfgs[0], surface_attrs);
847    XFree(cfgs);
848 
849    if (!pbuf)
850      {
851         ERR("GLX failed to create a pbuffer");
852         return NULL;
853      }
854 
855    return (void*)(intptr_t)pbuf;
856 #endif
857 }
858 
859 static int
evgl_eng_pbuffer_surface_destroy(void * data,void * surface)860 evgl_eng_pbuffer_surface_destroy(void *data, void *surface)
861 {
862    /* EVGLINIT(re, 0); */
863    if (!data)
864      {
865         ERR("Invalid Render Engine Data!");
866         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
867         return 0;
868      }
869 
870    if (!surface)
871      {
872         ERR("Invalid surface.");
873         glsym_evas_gl_common_error_set(EVAS_GL_BAD_SURFACE);
874         return 0;
875      }
876 
877 #ifdef GL_GLES
878    Render_Engine *re = data;
879 
880    eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)surface);
881 #else
882    Render_Output_GL_Generic *re = data;
883    GLXPbuffer pbuf = (GLXPbuffer)(intptr_t) surface;
884 
885    glXDestroyPbuffer(re->software.ob->disp, pbuf);
886 #endif
887 
888    return 1;
889 }
890 
891 // This function should create a surface that can be used for offscreen rendering
892 // and still be bindable to a texture in Evas main GL context.
893 // For now, this will create an X pixmap... Ideally it should be able to create
894 // a bindable pbuffer surface or just an FBO if that is supported and it can
895 // be shared with Evas.
896 // FIXME: Avoid passing evgl_engine around like that.
897 static void *
evgl_eng_indirect_surface_create(EVGL_Engine * evgl EINA_UNUSED,void * data,EVGL_Surface * evgl_sfc,Evas_GL_Config * cfg,int w,int h)898 evgl_eng_indirect_surface_create(EVGL_Engine *evgl EINA_UNUSED, void *data,
899                               EVGL_Surface *evgl_sfc,
900                               Evas_GL_Config *cfg, int w, int h)
901 {
902    Render_Engine *re = data;
903 #ifdef GL_GLES
904    Eina_Bool alpha = EINA_FALSE;
905 #endif
906    int colordepth;
907    Pixmap px;
908 
909    if (!re || !evgl_sfc || !cfg)
910      {
911         glsym_evas_gl_common_error_set(EVAS_GL_BAD_PARAMETER);
912         return NULL;
913      }
914 
915    if ((w < 1) || (h < 1))
916      {
917         ERR("Inconsistent parameters, not creating any surface!");
918         glsym_evas_gl_common_error_set(EVAS_GL_BAD_PARAMETER);
919         return NULL;
920      }
921 
922    /* Choose appropriate pixmap depth */
923    if (cfg->color_format == EVAS_GL_RGBA_8888)
924      {
925 #ifdef GL_GLES
926         alpha = EINA_TRUE;
927 #endif
928         colordepth = 32;
929      }
930    else if (cfg->color_format == EVAS_GL_RGB_888)
931      colordepth = 24;
932    else // this could also be XDefaultDepth but this case shouldn't happen
933      colordepth = 24;
934 
935    px = XCreatePixmap(eng_get_ob(re)->disp, eng_get_ob(re)->win, w, h, colordepth);
936    if (!px)
937      {
938         ERR("Failed to create XPixmap!");
939         glsym_evas_gl_common_error_set(EVAS_GL_BAD_ALLOC);
940         return NULL;
941      }
942 
943 #ifdef GL_GLES
944    EGLSurface egl_sfc;
945    EGLConfig egl_cfg;
946    int i, num = 0, best = -1;
947    EGLConfig configs[200];
948    int config_attrs[40];
949    Eina_Bool found = EINA_FALSE;
950    int msaa = 0, depth = 0, stencil = 0;
951    Visual *visual = NULL;
952    Eina_Bool retried = EINA_FALSE;
953    EGLint val = 0;
954 
955    /* Now we need to iterate over all EGL configurations to check the compatible
956     * ones and finally check their visual ID. */
957 
958    if ((cfg->depth_bits > EVAS_GL_DEPTH_NONE) &&
959        (cfg->depth_bits <= EVAS_GL_DEPTH_BIT_32))
960      depth = 8 * ((int) cfg->depth_bits);
961 
962    if ((cfg->stencil_bits > EVAS_GL_STENCIL_NONE) &&
963        (cfg->stencil_bits <= EVAS_GL_STENCIL_BIT_16))
964      stencil = 1 << ((int) cfg->stencil_bits - 1);
965 
966    if ((cfg->multisample_bits > EVAS_GL_MULTISAMPLE_NONE) &&
967        (cfg->multisample_bits <= EVAS_GL_MULTISAMPLE_HIGH))
968      msaa = evgl->caps.msaa_samples[(int) cfg->multisample_bits - 1];
969 
970 try_again:
971    i = 0;
972    config_attrs[i++] = EGL_SURFACE_TYPE;
973    config_attrs[i++] = EGL_PIXMAP_BIT;
974    config_attrs[i++] = EGL_RENDERABLE_TYPE;
975    if (cfg->gles_version == EVAS_GL_GLES_3_X)
976      config_attrs[i++] = EGL_OPENGL_ES3_BIT;
977    else if (cfg->gles_version == EVAS_GL_GLES_2_X)
978      config_attrs[i++] = EGL_OPENGL_ES2_BIT;
979    else
980      config_attrs[i++] = EGL_OPENGL_ES_BIT;
981    if (alpha)
982      {
983         config_attrs[i++] = EGL_ALPHA_SIZE;
984         config_attrs[i++] = 1; // should it be 8?
985         DBG("Requesting RGBA pixmap");
986      }
987    else
988      {
989         config_attrs[i++] = EGL_ALPHA_SIZE;
990         config_attrs[i++] = 0;
991      }
992    if (depth)
993      {
994         depth = 8 * ((int) cfg->depth_bits);
995         config_attrs[i++] = EGL_DEPTH_SIZE;
996         config_attrs[i++] = depth;
997         DBG("Requesting depth buffer size %d", depth);
998      }
999    if (stencil)
1000      {
1001         stencil = 1 << ((int) cfg->stencil_bits - 1);
1002         config_attrs[i++] = EGL_STENCIL_SIZE;
1003         config_attrs[i++] = stencil;
1004         DBG("Requesting stencil buffer size %d", stencil);
1005      }
1006    if (msaa)
1007      {
1008         msaa = evgl->caps.msaa_samples[(int) cfg->multisample_bits - 1];
1009         config_attrs[i++] = EGL_SAMPLE_BUFFERS;
1010         config_attrs[i++] = 1;
1011         config_attrs[i++] = EGL_SAMPLES;
1012         config_attrs[i++] = msaa;
1013         DBG("Requesting MSAA buffer with %d samples", msaa);
1014      }
1015    config_attrs[i++] = EGL_NONE;
1016    config_attrs[i++] = 0;
1017 
1018    if (!eglChooseConfig(eng_get_ob(re)->egl_disp, config_attrs, configs, 200, &num) || !num)
1019      {
1020         int err = eglGetError();
1021         ERR("eglChooseConfig() can't find any configs, error: %x", err);
1022         glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
1023         XFreePixmap(eng_get_ob(re)->disp, px);
1024         return NULL;
1025      }
1026 
1027    DBG("Found %d potential configurations", num);
1028    for (i = 0; (i < num) && !found; i++)
1029      {
1030         VisualID visid = 0;
1031         XVisualInfo *xvi, vi_in;
1032         XRenderPictFormat *fmt;
1033         int nvi = 0, j;
1034 
1035         if (!eglGetConfigAttrib(eng_get_ob(re)->egl_disp, configs[i],
1036                                 EGL_NATIVE_VISUAL_ID, &val))
1037           continue;
1038 
1039         // Find matching visuals. Only alpha & depth are really valid here.
1040         visid = val;
1041         vi_in.screen = eng_get_ob(re)->screen;
1042         vi_in.visualid = visid;
1043         xvi = XGetVisualInfo(eng_get_ob(re)->disp,
1044                              VisualScreenMask | VisualIDMask,
1045                              &vi_in, &nvi);
1046         if (xvi)
1047           {
1048              for (j = 0; (j < nvi) && !found; j++)
1049                {
1050                   if (xvi[j].depth >= colordepth)
1051                     {
1052                        if (best < 0) best = i;
1053                        if (alpha)
1054                          {
1055                             fmt = XRenderFindVisualFormat(eng_get_ob(re)->disp, xvi[j].visual);
1056                             if (fmt && (fmt->direct.alphaMask))
1057                               found = EINA_TRUE;
1058                          }
1059                        else found = EINA_TRUE;
1060                     }
1061                }
1062              if (found)
1063                {
1064                   egl_cfg = configs[i];
1065                   visual = xvi[j].visual;
1066                   XFree(xvi);
1067                   break;
1068                }
1069              XFree(xvi);
1070           }
1071      }
1072 
1073    if (!found)
1074      {
1075         if (num && (best >= 0))
1076           {
1077              ERR("No matching config found. Trying with EGL config #%d", best);
1078              egl_cfg = configs[best];
1079           }
1080         else if (msaa && !retried)
1081           {
1082              ERR("Trying again without MSAA.");
1083              msaa = 0;
1084              retried = EINA_TRUE;
1085              goto try_again;
1086           }
1087         else
1088           {
1089              // This config will probably not work, but we try anyways.
1090              // NOTE: Maybe it would be safer to just return NULL here, leaving
1091              // the app responsible for changing its config.
1092              ERR("XGetVisualInfo failed. Trying with the window's EGL config.");
1093              egl_cfg = eng_get_ob(re)->egl_config;
1094           }
1095      }
1096 
1097    egl_sfc = eglCreatePixmapSurface(eng_get_ob(re)->egl_disp, egl_cfg, px, NULL);
1098    if (!egl_sfc)
1099      {
1100         int err = eglGetError();
1101         ERR("eglCreatePixmapSurface failed with error: %x", err);
1102         glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
1103         XFreePixmap(eng_get_ob(re)->disp, px);
1104         return NULL;
1105      }
1106 
1107    if (extn_have_y_inverted &&
1108        eglGetConfigAttrib(eng_get_ob(re)->egl_disp, egl_cfg,
1109                           EGL_Y_INVERTED_NOK, &val))
1110      evgl_sfc->yinvert = val;
1111    else
1112      evgl_sfc->yinvert = 1;
1113 
1114    evgl_sfc->indirect = EINA_TRUE;
1115    evgl_sfc->indirect_sfc = egl_sfc;
1116    evgl_sfc->indirect_sfc_native = (void *)(intptr_t) px;
1117    evgl_sfc->indirect_sfc_visual = visual;
1118    evgl_sfc->indirect_sfc_config = egl_cfg;
1119    DBG("Successfully created indirect surface: Pixmap %lu EGLSurface %p", px, egl_sfc);
1120    return evgl_sfc;
1121 
1122 #else
1123    // TODO/FIXME: do the same as with EGL above...
1124    ERR("GLX support is not fully implemented for indirect surface");
1125 
1126    evgl_sfc->indirect = EINA_TRUE;
1127    evgl_sfc->indirect_sfc_native = (void *)(intptr_t) px;
1128    evgl_sfc->indirect_sfc = (void *)(intptr_t) px;
1129    evgl_sfc->indirect_sfc_visual = eng_get_ob(re)->info->info.visual; // FIXME: Check this!
1130    return evgl_sfc;
1131 #endif
1132 }
1133 
1134 // This function should destroy the indirect surface as well as the X pixmap
1135 static int
evgl_eng_indirect_surface_destroy(void * data,EVGL_Surface * evgl_sfc)1136 evgl_eng_indirect_surface_destroy(void *data, EVGL_Surface *evgl_sfc)
1137 {
1138    Render_Engine *re = (Render_Engine *)data;
1139 
1140    if (!re)
1141      {
1142         ERR("Invalid Render Engine Data!");
1143         glsym_evas_gl_common_error_set(EVAS_GL_NOT_INITIALIZED);
1144         return 0;
1145      }
1146 
1147 #ifdef GL_GLES
1148    if ((!evgl_sfc) || (!evgl_sfc->indirect_sfc))
1149      {
1150         ERR("Invalid surface");
1151         glsym_evas_gl_common_error_set(EVAS_GL_BAD_SURFACE);
1152         return 0;
1153      }
1154 
1155    eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)evgl_sfc->indirect_sfc);
1156 #endif
1157 
1158    if (!evgl_sfc->indirect_sfc_native)
1159      {
1160         ERR("Inconsistent parameters, not freeing XPixmap for indirect surface!");
1161         glsym_evas_gl_common_error_set(EVAS_GL_BAD_PARAMETER);
1162         return 0;
1163      }
1164 
1165    XFreePixmap(eng_get_ob(re)->disp, (Pixmap)evgl_sfc->indirect_sfc_native);
1166 
1167    return 1;
1168 }
1169 
1170 static void *
evgl_eng_gles_context_create(void * data,EVGL_Context * share_ctx,EVGL_Surface * sfc)1171 evgl_eng_gles_context_create(void *data,
1172                               EVGL_Context *share_ctx, EVGL_Surface *sfc)
1173 {
1174    Render_Engine *re = data;
1175    if (!re) return NULL;
1176 
1177 #ifdef GL_GLES
1178    EGLContext context = EGL_NO_CONTEXT;
1179    int context_attrs[3];
1180    EGLConfig config;
1181 
1182    if (!share_ctx)
1183      {
1184         ERR("Share context not set, Unable to retrieve GLES version");
1185         return NULL;
1186      }
1187 
1188    context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
1189    context_attrs[1] = share_ctx->version;
1190    context_attrs[2] = EGL_NONE;
1191 
1192    if (!sfc || !sfc->indirect_sfc_config)
1193      {
1194         ERR("Surface is not set! Creating context anyways but evas_eglMakeCurrent "
1195             "might very well fail with EGL_BAD_MATCH (0x3009)");
1196         config = eng_get_ob(re)->egl_config;
1197      }
1198    else config = sfc->indirect_sfc_config;
1199 
1200    context = eglCreateContext(eng_get_ob(re)->egl_disp, config,
1201                               share_ctx->context,
1202                               context_attrs);
1203    if (!context)
1204      {
1205         int err = eglGetError();
1206         ERR("eglCreateContext failed with error 0x%x", err);
1207         glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
1208         return NULL;
1209      }
1210 
1211    DBG("Successfully created context for indirect rendering.");
1212    return context;
1213 #else
1214    CRI("Support for indirect rendering contexts is not implemented for GLX");
1215    (void) share_ctx; (void) sfc;
1216    return NULL;
1217 #endif
1218 }
1219 
1220 static void
evgl_eng_native_win_surface_config_get(void * data,int * win_depth,int * win_stencil,int * win_msaa)1221 evgl_eng_native_win_surface_config_get(void *data, int *win_depth,
1222                                          int *win_stencil, int *win_msaa)
1223 {
1224    Render_Engine *re = data;
1225    if (!re) return;
1226 
1227    if (win_depth)
1228      *win_depth = eng_get_ob(re)->detected.depth_buffer_size;
1229    if (win_stencil)
1230      *win_stencil = eng_get_ob(re)->detected.stencil_buffer_size;
1231    if (win_msaa)
1232      *win_msaa = eng_get_ob(re)->detected.msaa;
1233 
1234    DBG("Window config(depth %d, stencil %d, msaa %d)",
1235        eng_get_ob(re)->detected.depth_buffer_size,
1236        eng_get_ob(re)->detected.stencil_buffer_size,
1237        eng_get_ob(re)->detected.msaa);
1238 }
1239 
1240 static const EVGL_Interface evgl_funcs =
1241 {
1242    evgl_eng_display_get,
1243    evgl_eng_evas_surface_get,
1244    evgl_eng_native_window_create,
1245    evgl_eng_native_window_destroy,
1246    evgl_eng_window_surface_create,
1247    evgl_eng_window_surface_destroy,
1248    evgl_eng_context_create,
1249    evgl_eng_context_destroy,
1250    evgl_eng_make_current,
1251    evgl_eng_proc_address_get,
1252    evgl_eng_string_get,
1253    evgl_eng_rotation_angle_get,
1254    evgl_eng_pbuffer_surface_create,
1255    evgl_eng_pbuffer_surface_destroy,
1256    evgl_eng_indirect_surface_create,
1257    evgl_eng_indirect_surface_destroy,
1258    evgl_eng_gles_context_create,
1259    evgl_eng_native_win_surface_config_get,
1260 };
1261 
1262 //----------------------------------------------------------//
1263 
1264 static inline int
_has_ext(const char * exts,const char * ext)1265 _has_ext(const char *exts, const char *ext)
1266 {
1267    if (!exts || !ext) return EINA_FALSE;
1268    return strstr(exts, ext) != NULL;
1269 }
1270 
1271 static void
gl_symbols(void)1272 gl_symbols(void)
1273 {
1274    static int done = 0;
1275 
1276    if (done) return;
1277 
1278 #define LINK2GENERIC(sym) \
1279    glsym_##sym = dlsym(RTLD_DEFAULT, #sym); \
1280    if (!glsym_##sym) ERR("Could not find function '%s'", #sym);
1281 
1282    // Get function pointer to evas_gl_common that is now provided through the link of GL_Generic.
1283    LINK2GENERIC(evas_gl_common_image_all_unload);
1284    LINK2GENERIC(evas_gl_common_image_ref);
1285    LINK2GENERIC(evas_gl_common_image_unref);
1286    LINK2GENERIC(evas_gl_common_image_new_from_data);
1287    LINK2GENERIC(evas_gl_common_image_native_disable);
1288    LINK2GENERIC(evas_gl_common_image_free);
1289    LINK2GENERIC(evas_gl_common_image_native_enable);
1290    LINK2GENERIC(evas_gl_common_context_new);
1291    LINK2GENERIC(evas_gl_common_context_flush);
1292    LINK2GENERIC(evas_gl_common_context_free);
1293    LINK2GENERIC(evas_gl_common_context_use);
1294    LINK2GENERIC(evas_gl_common_context_newframe);
1295    LINK2GENERIC(evas_gl_common_context_done);
1296    LINK2GENERIC(evas_gl_common_context_resize);
1297    LINK2GENERIC(evas_gl_common_buffer_dump);
1298    LINK2GENERIC(evas_gl_preload_render_lock);
1299    LINK2GENERIC(evas_gl_preload_render_unlock);
1300    LINK2GENERIC(evas_gl_preload_render_relax);
1301    LINK2GENERIC(evas_gl_preload_init);
1302    LINK2GENERIC(evas_gl_preload_shutdown);
1303    LINK2GENERIC(evgl_engine_shutdown);
1304    LINK2GENERIC(evgl_native_surface_buffer_get);
1305    LINK2GENERIC(evgl_native_surface_yinvert_get);
1306    LINK2GENERIC(evgl_current_native_context_get);
1307    LINK2GENERIC(evas_gl_symbols);
1308    LINK2GENERIC(evas_gl_common_error_get);
1309    LINK2GENERIC(evas_gl_common_error_set);
1310    LINK2GENERIC(evas_gl_common_current_context_get);
1311    LINK2GENERIC(evas_gl_common_shaders_flush);
1312 
1313 #define FINDSYM(dst, sym, typ) if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym);
1314 #ifdef GL_GLES
1315 
1316    FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
1317    FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
1318    FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
1319    FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
1320 
1321 #else
1322 
1323    FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressEXT", glsym_func_eng_fn);
1324    FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddressARB", glsym_func_eng_fn);
1325    FINDSYM(glsym_glXGetProcAddress, "glXGetProcAddress", glsym_func_eng_fn);
1326 
1327 #endif
1328 #undef FINDSYM
1329 
1330    done = 1;
1331 }
1332 
1333 void
eng_gl_symbols(Outbuf * ob)1334 eng_gl_symbols(Outbuf *ob)
1335 {
1336    static int done = 0;
1337    const char *exts;
1338 
1339    if (done) return;
1340 
1341    /* GetProcAddress() may not return NULL, even if the extension is not
1342     * supported. Nvidia drivers since version 360 never return NULL, thus
1343     * we need to always match the function name with their full extension
1344     * name. Other drivers tend to return NULL for glX/egl prefixed names, but
1345     * this could change in the future.
1346     *
1347     * -- jpeg, 2016/08/04
1348     */
1349 
1350 #ifdef GL_GLES
1351 #define FINDSYM(dst, sym, ext, typ) do { \
1352    if (!dst) { \
1353       if (_has_ext(exts, ext) && glsym_eglGetProcAddress) \
1354         dst = (typ) glsym_eglGetProcAddress(sym); \
1355       if (!dst) \
1356         dst = (typ) dlsym(RTLD_DEFAULT, sym); \
1357    }} while (0)
1358 
1359    // Find EGL extensions
1360    exts = eglQueryString(ob->egl_disp, EGL_EXTENSIONS);
1361 
1362    // Find GL extensions
1363    glsym_evas_gl_symbols((void*)glsym_eglGetProcAddress, exts);
1364 
1365    LINK2GENERIC(evas_gl_common_eglCreateImage);
1366    LINK2GENERIC(evas_gl_common_eglDestroyImage);
1367 
1368    FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage", NULL, glsym_func_uint);
1369    FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageEXT", "EGL_EXT_swap_buffers_with_damage", glsym_func_uint);
1370    FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageKHR", "EGL_KHR_swap_buffers_with_damage", glsym_func_uint);
1371    FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageINTEL", "EGL_INTEL_swap_buffers_with_damage", glsym_func_uint);
1372 
1373    FINDSYM(glsym_eglSetDamageRegionKHR, "eglSetDamageRegionKHR", "EGL_KHR_partial_update", glsym_func_uint);
1374 
1375    FINDSYM(glsym_eglQueryWaylandBufferWL, "eglQueryWaylandBufferWL", "EGL_WL_bind_wayland_display", glsym_func_uint);
1376 
1377    // This is a GL extension
1378    exts = (const char *) glGetString(GL_EXTENSIONS);
1379    FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", "GL_OES_EGL_image", glsym_func_void);
1380    FINDSYM(glsym_glEGLImageTargetTexture2DOES, "glEGLImageTargetTexture2DOES", "GL_OES_EGL_image_external", glsym_func_void);
1381 
1382 #else
1383 
1384 #define FINDSYM(dst, sym, ext, typ) do { \
1385    if (!dst) { \
1386       if (_has_ext(exts, ext) && glsym_glXGetProcAddress) \
1387         dst = (typ) glsym_glXGetProcAddress(sym); \
1388       if (!dst) \
1389         dst = (typ) dlsym(RTLD_DEFAULT, sym); \
1390    }} while (0)
1391 
1392    // Find GLX extensions
1393    exts = glXQueryExtensionsString((Display *) ob->disp, ob->screen);
1394 
1395    // Find GL extensions
1396    glsym_evas_gl_symbols((void*)glsym_glXGetProcAddress, exts);
1397 
1398    FINDSYM(glsym_glXBindTexImage, "glXBindTexImage", NULL, glsym_func_void);
1399    FINDSYM(glsym_glXBindTexImage, "glXBindTexImageEXT", "GLX_EXT_texture_from_pixmap", glsym_func_void);
1400    FINDSYM(glsym_glXBindTexImage, "glXBindTexImageARB", "GLX_ARB_render_texture", glsym_func_void);
1401 
1402    FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImage", NULL, glsym_func_void);
1403    FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageEXT", "GLX_EXT_texture_from_pixmap", glsym_func_void);
1404    FINDSYM(glsym_glXReleaseTexImage, "glXReleaseTexImageARB", "GLX_ARB_render_texture", glsym_func_void);
1405 
1406    FINDSYM(glsym_glXGetVideoSync, "glXGetVideoSyncSGI", "GLX_SGI_video_sync", glsym_func_int);
1407    FINDSYM(glsym_glXWaitVideoSync, "glXWaitVideoSyncSGI", "GLX_SGI_video_sync", glsym_func_int);
1408 
1409    // GLX 1.3
1410    FINDSYM(glsym_glXCreatePixmap, "glXCreatePixmap", NULL, glsym_func_xid);
1411    FINDSYM(glsym_glXDestroyPixmap, "glXDestroyPixmap", NULL, glsym_func_void);
1412    FINDSYM(glsym_glXQueryDrawable, "glXQueryDrawable", NULL, glsym_func_void);
1413 
1414    // swap interval: MESA and SGI take (interval)
1415    FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalMESA", "GLX_MESA_swap_control", glsym_func_int);
1416    FINDSYM(glsym_glXSwapIntervalSGI, "glXSwapIntervalSGI", "GLX_SGI_swap_control", glsym_func_int);
1417 
1418    // swap interval: EXT takes (dpy, drawable, interval)
1419    FINDSYM(glsym_glXSwapIntervalEXT, "glXSwapIntervalEXT", "GLX_EXT_swap_control", glsym_func_void);
1420 
1421    FINDSYM(glsym_glXReleaseBuffersMESA, "glXReleaseBuffersMESA", "GLX_MESA_release_buffers", glsym_func_void);
1422 
1423 #endif
1424 #undef FINDSYM
1425 
1426    done = 1;
1427 }
1428 
1429 static void
gl_extn_veto(Render_Engine * re)1430 gl_extn_veto(Render_Engine *re)
1431 {
1432    const char *str = NULL;
1433 #ifdef GL_GLES
1434    str = eglQueryString(eng_get_ob(re)->egl_disp, EGL_EXTENSIONS);
1435    if (str)
1436      {
1437         const char *s;
1438         if (getenv("EVAS_GL_INFO"))
1439           printf("EGL EXTN:\n%s\n", str);
1440         // Disable Partial Rendering
1441         if ((s = getenv("EVAS_GL_PARTIAL_DISABLE")) && atoi(s))
1442           {
1443              extn_have_buffer_age = 0;
1444              glsym_eglSwapBuffersWithDamage = NULL;
1445              glsym_eglSetDamageRegionKHR = NULL;
1446           }
1447         if (!strstr(str, "EGL_EXT_buffer_age"))
1448           {
1449              if (!strstr(str, "EGL_KHR_partial_update"))
1450                extn_have_buffer_age = 0;
1451           }
1452         if (!strstr(str, "EGL_KHR_partial_update"))
1453           {
1454              glsym_eglSetDamageRegionKHR = NULL;
1455           }
1456         if (!strstr(str, "EGL_NOK_texture_from_pixmap"))
1457           {
1458              extn_have_y_inverted = 0;
1459           }
1460         else
1461           {
1462              const GLubyte *vendor, *renderer;
1463 
1464              vendor = glGetString(GL_VENDOR);
1465              renderer = glGetString(GL_RENDERER);
1466              // XXX: workaround mesa bug!
1467              // looking for mesa and intel build which is known to
1468              // advertise the EGL_NOK_texture_from_pixmap extension
1469              // but not set it correctly. guessing vendor/renderer
1470              // strings will be like the following:
1471              // OpenGL vendor string: Intel Open Source Technology Center
1472              // OpenGL renderer string: Mesa DRI Intel(R) Sandybridge Desktop
1473              if (((vendor) && (strstr((const char *)vendor, "Intel"))) &&
1474                  ((renderer) && (strstr((const char *)renderer, "Mesa"))) &&
1475                  ((renderer) && (strstr((const char *)renderer, "Intel")))
1476                 )
1477                extn_have_y_inverted = 0;
1478           }
1479         if ((!strstr(str, "EGL_EXT_swap_buffers_with_damage")) &&
1480             (!strstr(str, "EGL_KHR_swap_buffers_with_damage")))
1481           {
1482              glsym_eglSwapBuffersWithDamage = NULL;
1483           }
1484         if (strstr(str, "EGL_TIZEN_image_native_surface"))
1485           {
1486              eng_get_ob(re)->gl_context->shared->info.egl_tbm_ext = 1;
1487           }
1488      }
1489    else
1490      {
1491         if (getenv("EVAS_GL_INFO"))
1492           printf("NO EGL EXTN!\n");
1493         extn_have_buffer_age = 0;
1494      }
1495 #else
1496    str = glXQueryExtensionsString(eng_get_ob(re)->info->info.display,
1497                                   eng_get_ob(re)->info->info.screen);
1498    if (str)
1499      {
1500         const char *str2;
1501         char *tmpstr;
1502         size_t sz = 0;
1503 
1504         sz = strlen(str);
1505         str2 = glXGetClientString(eng_get_ob(re)->info->info.display,
1506                                  GLX_EXTENSIONS);
1507         if (str2) sz += 1 + strlen(str2);
1508         tmpstr = alloca(sz + 1);
1509         strcpy(tmpstr, str);
1510         if (str2)
1511           {
1512              strcat(tmpstr, " ");
1513              if (str2) strcat(tmpstr, str2);
1514           }
1515         if (getenv("EVAS_GL_INFO"))
1516           printf("GLX EXTN:\n%s\n", tmpstr);
1517         if (!strstr(tmpstr, "_texture_from_pixmap"))
1518           {
1519              glsym_glXBindTexImage = NULL;
1520              glsym_glXReleaseTexImage = NULL;
1521           }
1522         if (!strstr(tmpstr, "GLX_SGI_video_sync"))
1523           {
1524              glsym_glXGetVideoSync = NULL;
1525              glsym_glXWaitVideoSync = NULL;
1526           }
1527         if (!strstr(tmpstr, "GLX_EXT_buffer_age"))
1528           {
1529              extn_have_buffer_age = 0;
1530           }
1531         if (!strstr(tmpstr, "GLX_EXT_swap_control"))
1532           {
1533              glsym_glXSwapIntervalEXT = NULL;
1534           }
1535         if (!strstr(tmpstr, "GLX_SGI_swap_control"))
1536           {
1537              glsym_glXSwapIntervalSGI = NULL;
1538           }
1539         if (!strstr(tmpstr, "GLX_MESA_release_buffers"))
1540           {
1541              glsym_glXReleaseBuffersMESA = NULL;
1542           }
1543      }
1544    else
1545      {
1546         if (getenv("EVAS_GL_INFO"))
1547           printf("NO GLX EXTN!\n");
1548         glsym_glXBindTexImage = NULL;
1549         glsym_glXReleaseTexImage = NULL;
1550         glsym_glXGetVideoSync = NULL;
1551         glsym_glXWaitVideoSync = NULL;
1552         extn_have_buffer_age = 0;
1553         glsym_glXSwapIntervalEXT = NULL;
1554         glsym_glXSwapIntervalSGI = NULL;
1555         glsym_glXReleaseBuffersMESA = NULL;
1556      }
1557 #endif
1558 }
1559 
1560 int _evas_engine_GL_X11_log_dom = -1;
1561 /* function tables - filled in later (func and parent func) */
1562 static Evas_Func func, pfunc;
1563 
1564 static void
eng_output_info_setup(void * info)1565 eng_output_info_setup(void *info)
1566 {
1567    Evas_Engine_Info_GL_X11 *einfo = info;
1568 
1569    einfo->func.best_visual_get = eng_best_visual_get;
1570    einfo->func.best_colormap_get = eng_best_colormap_get;
1571    einfo->func.best_depth_get = eng_best_depth_get;
1572    einfo->render_mode = EVAS_RENDER_MODE_BLOCKING;
1573 }
1574 
1575 static void
eng_outbuf_idle_flush(Outbuf * ob)1576 eng_outbuf_idle_flush(Outbuf *ob)
1577 {
1578    if (glsym_evas_gl_common_shaders_flush)
1579      glsym_evas_gl_common_shaders_flush(ob->gl_context->shared);
1580 }
1581 
1582 static void
_re_winfree(Render_Engine * re)1583 _re_winfree(Render_Engine *re)
1584 {
1585    if (!eng_get_ob(re)->surf) return;
1586    glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
1587    eng_window_unsurf(eng_get_ob(re));
1588 }
1589 
1590 static void *
eng_output_setup(void * engine,void * in,unsigned int w,unsigned int h)1591 eng_output_setup(void *engine, void *in, unsigned int w, unsigned int h)
1592 {
1593    Evas_Engine_Info_GL_X11 *info = in;
1594    Render_Engine *re = NULL;
1595    Outbuf *ob = NULL;
1596    Render_Output_Swap_Mode swap_mode;
1597 
1598    swap_mode = evas_render_engine_gl_swap_mode_get(info->swap_mode);
1599 
1600    // Set this env var to dump files every frame
1601    // Or set the global var in gdb to 1|0 to turn it on and off
1602    if (getenv("EVAS_GL_SWAP_BUFFER_DEBUG_ALWAYS"))
1603      swap_buffer_debug = 1;
1604 
1605    if (swap_buffer_debug_mode == -1)
1606      {
1607         if (
1608 #if defined(HAVE_GETUID) && defined(HAVE_GETEUID)
1609             (getuid() == geteuid()) &&
1610 #endif
1611             ((debug_dir = getenv("EVAS_GL_SWAP_BUFFER_DEBUG_DIR"))))
1612           {
1613              int stat;
1614              // Create a directory with 0775 permission
1615              stat = mkdir(debug_dir, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH);
1616              if ((!stat) || errno == EEXIST) swap_buffer_debug_mode = 1;
1617           }
1618         else
1619            swap_buffer_debug_mode = 0;
1620      }
1621 
1622 
1623    if (!initted)
1624      {
1625         glsym_evas_gl_preload_init();
1626      }
1627 
1628 #ifdef GL_GLES
1629 #else
1630    int eb, evb;
1631 
1632    if (!glXQueryExtension(info->info.display, &eb, &evb)) return 0;
1633 #endif
1634    re = calloc(1, sizeof(Render_Engine));
1635    if (!re) return NULL;
1636 
1637    ob = eng_window_new(info,
1638                        info->info.display,
1639                        info->info.drawable,
1640                        info->info.screen,
1641                        info->info.visual,
1642                        info->info.colormap,
1643                        info->info.depth,
1644                        w, h,
1645                        info->indirect,
1646                        info->info.destination_alpha,
1647                        info->info.rotation,
1648                        swap_mode,
1649                        info->depth_bits,
1650                        info->stencil_bits,
1651                        info->msaa_bits);
1652    if (!ob) goto on_error;
1653 
1654    if (!evas_render_engine_gl_generic_init(engine, &re->generic, ob,
1655                                            eng_outbuf_swap_mode,
1656                                            eng_outbuf_get_rot,
1657                                            eng_outbuf_reconfigure,
1658                                            eng_outbuf_region_first_rect,
1659 #ifdef GL_GLES
1660                                            eng_outbuf_damage_region_set,
1661 #else
1662                                            NULL,
1663 #endif
1664                                            eng_outbuf_new_region_for_update,
1665                                            eng_outbuf_push_updated_region,
1666                                            NULL,
1667                                            eng_outbuf_idle_flush,
1668                                            eng_outbuf_flush,
1669                                            NULL,
1670                                            eng_window_free,
1671                                            eng_window_use,
1672                                            eng_outbuf_gl_context_get,
1673                                            eng_outbuf_egl_display_get,
1674                                            eng_gl_context_new,
1675                                            eng_gl_context_use,
1676                                            &evgl_funcs,
1677                                            w, h))
1678      goto on_error;
1679 
1680    gl_wins++;
1681 
1682    evas_render_engine_software_generic_merge_mode_set(&re->generic.software);
1683 
1684    if (!initted)
1685      {
1686         gl_extn_veto(re);
1687         //             evgl_engine_init(re, &evgl_funcs);
1688         initted = 1;
1689      }
1690 
1691    eng_window_use(eng_get_ob(re));
1692 
1693    return re;
1694 
1695  on_error:
1696    if (ob) eng_window_free(ob);
1697    free(re);
1698    return NULL;
1699 }
1700 
1701 static int
eng_output_update(void * engine EINA_UNUSED,void * data,void * in,unsigned int w,unsigned int h)1702 eng_output_update(void *engine EINA_UNUSED, void *data, void *in, unsigned int w, unsigned int h)
1703 {
1704    Evas_Engine_Info_GL_X11 *info = in;
1705    Render_Engine *re = data;
1706    Render_Output_Swap_Mode swap_mode;
1707 
1708    swap_mode = evas_render_engine_gl_swap_mode_get(info->swap_mode);
1709 
1710    if (eng_get_ob(re) && _re_wincheck(eng_get_ob(re)))
1711      {
1712         if ((info->info.display != eng_get_ob(re)->disp) ||
1713             (info->info.drawable != eng_get_ob(re)->win) ||
1714             (info->info.screen != eng_get_ob(re)->screen) ||
1715             (info->info.visual != eng_get_ob(re)->visual) ||
1716             (info->info.colormap != eng_get_ob(re)->colormap) ||
1717             (info->info.depth != eng_get_ob(re)->depth) ||
1718             (info->depth_bits != eng_get_ob(re)->depth_bits) ||
1719             (info->stencil_bits != eng_get_ob(re)->stencil_bits) ||
1720             (info->msaa_bits != eng_get_ob(re)->msaa_bits) ||
1721             (info->info.destination_alpha != eng_get_ob(re)->alpha))
1722           {
1723              Outbuf *ob;
1724 
1725              gl_wins--;
1726 
1727              ob = eng_window_new(info,
1728                                  info->info.display,
1729                                  info->info.drawable,
1730                                  info->info.screen,
1731                                  info->info.visual,
1732                                  info->info.colormap,
1733                                  info->info.depth,
1734                                  w, h,
1735                                  info->indirect,
1736                                  info->info.destination_alpha,
1737                                  info->info.rotation,
1738                                  swap_mode,
1739                                  info->depth_bits,
1740                                  info->stencil_bits,
1741                                  info->msaa_bits);
1742              if (!ob) return 0;
1743 
1744              eng_window_use(ob);
1745              evas_render_engine_software_generic_update(&re->generic.software,
1746                                                         ob, w, h);
1747              gl_wins++;
1748           }
1749         else if ((eng_get_ob(re)->w != w) ||
1750                  (eng_get_ob(re)->h != h) ||
1751                  (eng_get_ob(re)->info->info.rotation != eng_get_ob(re)->rot))
1752           {
1753              eng_outbuf_reconfigure(eng_get_ob(re), w, h, eng_get_ob(re)->info->info.rotation, 0);
1754              evas_render_engine_software_generic_update(&re->generic.software,
1755                                                         re->generic.software.ob,
1756                                                         w, h);
1757           }
1758      }
1759 
1760    eng_window_use(eng_get_ob(re));
1761 
1762    return 1;
1763 }
1764 
1765 static void
eng_output_free(void * engine,void * data)1766 eng_output_free(void *engine, void *data)
1767 {
1768    Render_Engine *re;
1769 
1770    re = (Render_Engine *)data;
1771 
1772    if (re)
1773      {
1774 #ifndef GL_GLES
1775         Display *disp = eng_get_ob(re)->disp;
1776         Window win = eng_get_ob(re)->win;
1777 #endif
1778 
1779         glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
1780 
1781 #if 0
1782 #ifdef GL_GLES
1783         // Destroy the resource surface
1784         // Only required for EGL case
1785         if (re->surface)
1786            eglDestroySurface(eng_get_ob(re)->egl_disp, re->surface);
1787 #endif
1788 
1789         // Destroy the resource context
1790         _destroy_internal_context(re, context);
1791 #endif
1792 
1793         if (gl_wins == 1) glsym_evgl_engine_shutdown(re);
1794 
1795         evas_render_engine_software_generic_clean(engine, &re->generic.software);
1796 
1797 #ifndef GL_GLES
1798         if (glsym_glXReleaseBuffersMESA)
1799           glsym_glXReleaseBuffersMESA(disp, win);
1800 #endif
1801         gl_wins--;
1802 
1803         free(re);
1804      }
1805    if ((initted == 1) && (gl_wins == 0))
1806      {
1807         glsym_evas_gl_preload_shutdown();
1808         initted = 0;
1809      }
1810 }
1811 
1812 /* vsync games - not for now though */
1813 #define VSYNC_TO_SCREEN 1
1814 
1815 Eina_Bool
eng_preload_make_current(void * data,void * doit)1816 eng_preload_make_current(void *data, void *doit)
1817 {
1818    Outbuf *ob = data;
1819 
1820    if (doit)
1821      {
1822 #ifdef GL_GLES
1823         if (!evas_eglMakeCurrent(ob->egl_disp, ob->egl_surface, ob->egl_surface, ob->egl_context))
1824           return EINA_FALSE;
1825 #else
1826         if (!__glXMakeContextCurrent(ob->info->info.display, ob->glxwin, ob->context))
1827           {
1828              ERR("glXMakeContextCurrent(%p, %p, %p) failed",
1829                  ob->info->info.display, (void *)ob->win, (void *)ob->context);
1830              GLERRV("__glXMakeContextCurrent");
1831              return EINA_FALSE;
1832           }
1833 #endif
1834      }
1835    else
1836      {
1837 #ifdef GL_GLES
1838         if (!evas_eglMakeCurrent(ob->egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT))
1839           return EINA_FALSE;
1840 #else
1841         if (!__glXMakeContextCurrent(ob->info->info.display, 0, NULL))
1842           {
1843              ERR("glXMakeContextCurrent(%p, None, NULL) failed",
1844                  ob->info->info.display);
1845              GLERRV("__glXMakeContextCurrent");
1846              return EINA_FALSE;
1847           }
1848 #endif
1849      }
1850    return EINA_TRUE;
1851 }
1852 
1853 static Eina_Bool
eng_canvas_alpha_get(void * engine)1854 eng_canvas_alpha_get(void *engine)
1855 {
1856    Render_Engine *re = (Render_Engine *)engine;
1857    return re->generic.software.ob->alpha;
1858 }
1859 
1860 static void
eng_output_dump(void * engine,void * data)1861 eng_output_dump(void *engine, void *data)
1862 {
1863    Render_Engine *re = data;
1864    Render_Engine_GL_Generic *e = engine;
1865 
1866    eng_window_use(eng_get_ob(re));
1867    generic_cache_dump(e->software.surface_cache);
1868    evas_common_image_image_all_unload();
1869    evas_common_font_font_all_unload();
1870    glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);
1871    _re_winfree(re);
1872 }
1873 
1874 static void *
eng_gl_current_context_get(void * engine EINA_UNUSED)1875 eng_gl_current_context_get(void *engine EINA_UNUSED)
1876 {
1877    EVGL_Context *ctx;
1878    EVGLNative_Context context;
1879 
1880    ctx = glsym_evas_gl_common_current_context_get();
1881    if (!ctx)
1882      return NULL;
1883 
1884    context = glsym_evgl_current_native_context_get(ctx);
1885 
1886 #ifdef GL_GLES
1887    if (evas_eglGetCurrentContext() == context)
1888      return ctx;
1889 #else
1890    if (glXGetCurrentContext() == context)
1891      return ctx;
1892 #endif
1893 
1894    return NULL;
1895 }
1896 
1897 static int
eng_gl_error_get(void * engine)1898 eng_gl_error_get(void *engine)
1899 {
1900    int err;
1901 
1902    if ((err = glsym_evas_gl_common_error_get(engine)) != EVAS_GL_SUCCESS)
1903      goto end;
1904 
1905 #ifdef GL_GLES
1906    err = eglGetError() - EGL_SUCCESS;
1907 #else
1908    Render_Engine *re = engine;
1909 
1910    if (!eng_get_ob(re)->win)
1911      err = EVAS_GL_BAD_DISPLAY;
1912    else if (!eng_get_ob(re)->info)
1913      err = EVAS_GL_BAD_SURFACE;
1914 #endif
1915 
1916 end:
1917    glsym_evas_gl_common_error_set(EVAS_GL_SUCCESS);
1918    return err;
1919 }
1920 
1921 /////////////////////////////////////////////////////////////////////////
1922 //
1923 //
1924 // FIXME: this is enabled so updates happen - but its SLOOOOOOOOOOOOOOOW
1925 // (i am sure this is the reason)  not to mention seemingly superfluous. but
1926 // i need to enable it for it to work on fglrx at least. havent tried nvidia.
1927 //
1928 // why is this the case? does anyone know? has anyone tried it on other gfx
1929 // drivers?
1930 //
1931 //#define GLX_TEX_PIXMAP_RECREATE 1
1932 
1933 static void
_native_bind_cb(void * image)1934 _native_bind_cb(void *image)
1935 {
1936    Evas_GL_Image *im = image;
1937    Native *n = im->native.data;
1938 
1939   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
1940     {
1941 #ifdef GL_GLES
1942        if (n->ns_data.x11.surface)
1943          {
1944             if (n->ns_data.x11.multiple_buffer)
1945               {
1946                  EGLint err;
1947                  if (!glsym_evas_gl_common_eglDestroyImage)
1948                    {
1949                       ERR("Try eglDestroyImage()/eglCreateImage() on EGL with no support");
1950                       return;
1951                    }
1952 
1953                  glsym_evas_gl_common_eglDestroyImage(im->native.disp,
1954                                                       n->ns_data.x11.surface);
1955                  if ((err = eglGetError()) != EGL_SUCCESS)
1956                    {
1957                       ERR("eglDestroyImage() failed.");
1958                       glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
1959                    }
1960 
1961                  n->ns_data.x11.surface = glsym_evas_gl_common_eglCreateImage(im->native.disp,
1962                                                           EGL_NO_CONTEXT,
1963                                                           EGL_NATIVE_PIXMAP_KHR,
1964                                                           (void *)n->ns_data.x11.pixmap,
1965                                                           NULL);
1966                  if (!n->ns_data.x11.surface)
1967                    WRN("eglCreateImage() for Pixmap 0x%#lx failed: %#x", n->ns_data.x11.pixmap, eglGetError());
1968 
1969               }
1970             if (glsym_glEGLImageTargetTexture2DOES)
1971               {
1972                  glsym_glEGLImageTargetTexture2DOES(im->native.target, n->ns_data.x11.surface);
1973                  GLERRV("glsym_glEGLImageTargetTexture2DOES");
1974               }
1975             else
1976               ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
1977          }
1978 #else
1979 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
1980 
1981        if (glsym_glXBindTexImage)
1982          {
1983             glsym_glXBindTexImage(im->native.disp, (XID)n->ns_data.x11.surface,
1984                                   GLX_FRONT_LEFT_EXT, NULL);
1985             GLERRV("glsym_glXBindTexImage");
1986          }
1987        else
1988          ERR("Try glXBindTexImage on GLX with no support");
1989 # endif
1990 #endif
1991     }
1992   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
1993     {
1994        glBindTexture(im->native.target, n->ns.data.opengl.texture_id);
1995     }
1996   else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
1997     {
1998 #ifdef GL_GLES
1999        if (n->ns_data.tbm.surface)
2000          {
2001             if (glsym_glEGLImageTargetTexture2DOES)
2002               {
2003                  glsym_glEGLImageTargetTexture2DOES(im->native.target, n->ns_data.tbm.surface);
2004                  GLERRV("glsym_glEGLImageTargetTexture2DOES");
2005               }
2006              else
2007                ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
2008          }
2009 #endif
2010     }
2011   else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
2012     {
2013        if (n->ns_data.evasgl.surface)
2014          {
2015              Eina_Bool is_egl_image = EINA_FALSE;
2016              void *surface = NULL;
2017 
2018              if (glsym_evgl_native_surface_buffer_get)
2019                surface = glsym_evgl_native_surface_buffer_get(n->ns_data.evasgl.surface, &is_egl_image);
2020             if (is_egl_image)
2021               {
2022 #ifdef GL_GLES
2023                  if (glsym_glEGLImageTargetTexture2DOES)
2024                    {
2025                       glsym_glEGLImageTargetTexture2DOES(im->native.target, surface);
2026                       GLERRV("glsym_glEGLImageTargetTexture2DOES");
2027                    }
2028                  else
2029 #endif
2030                    ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
2031               }
2032             else
2033               {
2034                  glBindTexture(GL_TEXTURE_2D, (GLuint)(uintptr_t)surface);
2035               }
2036          }
2037     }
2038   else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
2039      {
2040 #ifdef GL_GLES
2041 # ifdef HAVE_WAYLAND
2042         if (n->ns_data.wl_surface.surface)
2043           {
2044              if (glsym_glEGLImageTargetTexture2DOES)
2045                {
2046                   glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->ns_data.wl_surface.surface);
2047                   GLERRV("glsym_glEGLImageTargetTexture2DOES");
2048                }
2049              else
2050                ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
2051           }
2052 # endif
2053 #endif
2054      }
2055 }
2056 
2057 static void
_native_unbind_cb(void * image)2058 _native_unbind_cb(void *image)
2059 {
2060    Evas_GL_Image *im = image;
2061    Native *n = im->native.data;
2062 
2063    if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
2064      {
2065 #ifdef GL_GLES
2066         // nothing
2067 #else
2068 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
2069 
2070         if (glsym_glXReleaseTexImage)
2071           {
2072              glsym_glXReleaseTexImage(im->native.disp, (XID)(n->ns_data.x11.surface),
2073                                       GLX_FRONT_LEFT_EXT);
2074           }
2075         else
2076           ERR("Try glXReleaseTexImage on GLX with no support");
2077 # endif
2078 #endif
2079      }
2080    else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
2081      {
2082         glBindTexture(im->native.target, 0);
2083      }
2084    else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
2085      {
2086         // nothing
2087      }
2088    else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
2089      {
2090 #ifdef GL_GLES
2091         // nothing
2092 #else
2093         glBindTexture(GL_TEXTURE_2D, 0);
2094 #endif
2095      }
2096 }
2097 
2098 static void
_native_free_cb(void * image)2099 _native_free_cb(void *image)
2100 {
2101   Evas_GL_Image *im = image;
2102   Native *n = im->native.data;
2103   uint32_t pmid, texid;
2104 #ifdef GL_GLES
2105 # ifdef HAVE_WAYLAND
2106   void *wlid;
2107 # endif
2108 #endif
2109 
2110   if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
2111     {
2112        pmid = n->ns_data.x11.pixmap;
2113        eina_hash_del(im->native.shared->native_pm_hash, &pmid, im);
2114 #ifdef GL_GLES
2115        if (n->ns_data.x11.surface)
2116          {
2117             int err;
2118             if (glsym_evas_gl_common_eglDestroyImage)
2119               {
2120                  glsym_evas_gl_common_eglDestroyImage(im->native.disp,
2121                                                       n->ns_data.x11.surface);
2122                  if ((err = eglGetError()) != EGL_SUCCESS)
2123                    {
2124                       ERR("eglDestroyImage() failed.");
2125                       glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
2126                    }
2127               }
2128             else
2129               ERR("Try eglDestroyImage on EGL with no support");
2130          }
2131 #else
2132 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
2133        if (n->ns_data.x11.surface)
2134          {
2135             if (im->native.loose)
2136               {
2137                  if (glsym_glXReleaseTexImage)
2138                    {
2139                      glsym_glXReleaseTexImage(im->native.disp, (XID)n->ns_data.x11.surface,
2140                                               GLX_FRONT_LEFT_EXT);
2141                    }
2142                  else
2143                    ERR("Try glXReleaseTexImage on GLX with no support");
2144               }
2145             if (glsym_glXDestroyPixmap)
2146               {
2147                  glsym_glXDestroyPixmap(im->native.disp, (XID)n->ns_data.x11.surface);
2148                  GLERRV("glsym_glXDestroyPixmap");
2149               }
2150             else
2151               ERR("Try glXDestroyPixmap on GLX with no support");
2152             n->ns_data.x11.surface = 0;
2153          }
2154 # endif
2155 #endif
2156     }
2157   else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
2158     {
2159        texid = n->ns.data.opengl.texture_id;
2160        eina_hash_del(im->native.shared->native_tex_hash, &texid, im);
2161     }
2162   else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
2163     {
2164        eina_hash_del(im->native.shared->native_tbm_hash, &n->ns_data.tbm.buffer, im);
2165 #ifdef GL_GLES
2166        if (n->ns_data.tbm.surface)
2167          {
2168             int err;
2169             if (glsym_evas_gl_common_eglDestroyImage)
2170               {
2171                  glsym_evas_gl_common_eglDestroyImage(im->native.disp,
2172                                                       n->ns_data.tbm.surface);
2173                  if ((err = eglGetError()) != EGL_SUCCESS)
2174                    {
2175                       ERR("eglDestroyImage() failed.");
2176                       glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
2177                    }
2178               }
2179             else
2180               ERR("Try eglDestroyImage on EGL with no support");
2181          }
2182 #endif
2183     }
2184   else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
2185     {
2186        eina_hash_del(im->native.shared->native_evasgl_hash, &n->ns.data.evasgl.surface, im);
2187     }
2188   else if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
2189      {
2190 #ifdef GL_GLES
2191 # ifdef HAVE_WAYLAND
2192         wlid = (void*)n->ns_data.wl_surface.wl_buf;
2193         eina_hash_del(im->native.shared->native_wl_hash, &wlid, image);
2194         if (n->ns_data.wl_surface.surface)
2195           {
2196              if (glsym_evas_gl_common_eglDestroyImage)
2197                {
2198                   glsym_evas_gl_common_eglDestroyImage(im->native.disp,
2199                                                        n->ns_data.wl_surface.surface);
2200                   if (eglGetError() != EGL_SUCCESS)
2201                     ERR("eglDestroyImage() failed.");
2202                }
2203              else
2204                ERR("Try eglDestroyImage on EGL with  no support");
2205           }
2206 # endif
2207 #endif
2208      }
2209   im->native.data        = NULL;
2210   im->native.func.bind   = NULL;
2211   im->native.func.unbind = NULL;
2212   im->native.func.free   = NULL;
2213   free(n);
2214 }
2215 
2216 static int
_native_yinvert_cb(void * image)2217 _native_yinvert_cb(void *image)
2218 {
2219    Evas_GL_Image *im = image;
2220    Native *n = im->native.data;
2221    int yinvert = 0, val;
2222 
2223    // Yinvert callback should only be used for EVAS_NATIVE_SURFACE_EVASGL type now,
2224    // as yinvert value is not changed for other types.
2225    if (n->ns.type == EVAS_NATIVE_SURFACE_X11)
2226      {
2227 #if GL_GLES
2228         if (extn_have_y_inverted &&
2229             eglGetConfigAttrib(im->native.disp, n->ns_data.x11.config,
2230                                EGL_Y_INVERTED_NOK, &val))
2231           yinvert = val;
2232 #else
2233         glXGetFBConfigAttrib(im->native.disp, n->ns_data.x11.config,
2234                              GLX_Y_INVERTED_EXT, &val);
2235         if (val) yinvert = 1;
2236 #endif
2237      }
2238    else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
2239      {
2240         yinvert = 0;
2241      }
2242    else if (n->ns.type == EVAS_NATIVE_SURFACE_TBM)
2243      {
2244         yinvert = 1;
2245      }
2246    else if (n->ns.type == EVAS_NATIVE_SURFACE_EVASGL)
2247      {
2248         yinvert = glsym_evgl_native_surface_yinvert_get(n->ns_data.evasgl.surface);
2249      }
2250 
2251    return yinvert;
2252 }
2253 
2254 static int
eng_image_native_init(void * engine EINA_UNUSED,Evas_Native_Surface_Type type)2255 eng_image_native_init(void *engine EINA_UNUSED, Evas_Native_Surface_Type type)
2256 {
2257    switch (type)
2258      {
2259 #ifdef GL_GLES
2260       case EVAS_NATIVE_SURFACE_TBM:
2261         return _evas_native_tbm_init();
2262 #endif
2263       case EVAS_NATIVE_SURFACE_X11:
2264       case EVAS_NATIVE_SURFACE_OPENGL:
2265       case EVAS_NATIVE_SURFACE_EVASGL:
2266         return 1;
2267 #if defined(GL_GLES) && defined(HAVE_WAYLAND)
2268       case EVAS_NATIVE_SURFACE_WL:
2269         return (glsym_eglQueryWaylandBufferWL != NULL) ? 1 : 0;
2270 #endif
2271       default:
2272         ERR("Native surface type %d not supported!", type);
2273         return 0;
2274      }
2275 }
2276 
2277 static void
eng_image_native_shutdown(void * engine EINA_UNUSED,Evas_Native_Surface_Type type)2278 eng_image_native_shutdown(void *engine EINA_UNUSED, Evas_Native_Surface_Type type)
2279 {
2280    switch (type)
2281      {
2282 #ifdef GL_GLES
2283       case EVAS_NATIVE_SURFACE_TBM:
2284         _evas_native_tbm_shutdown();
2285         return;
2286 #endif
2287       case EVAS_NATIVE_SURFACE_X11:
2288       case EVAS_NATIVE_SURFACE_OPENGL:
2289       case EVAS_NATIVE_SURFACE_EVASGL:
2290 #if defined(GL_GLES) && defined(HAVE_WAYLAND)
2291       case EVAS_NATIVE_SURFACE_WL:
2292 #endif
2293         return;
2294       default:
2295         ERR("Native surface type %d not supported!", type);
2296         return;
2297      }
2298 }
2299 
2300 static void *
eng_image_native_set(void * engine,void * image,void * native)2301 eng_image_native_set(void *engine, void *image, void *native)
2302 {
2303   const Evas_Native_Surface *ns = native;
2304   Evas_Engine_GL_Context *gl_context;
2305   Evas_GL_Image *im = image, *im2 = NULL;
2306   Visual *vis = NULL;
2307   Pixmap pm = 0;
2308   Native *n = NULL;
2309   uint32_t pmid, texid;
2310   unsigned int tex = 0;
2311   unsigned int fbo = 0;
2312   void *buffer = NULL;
2313   Outbuf *ob;
2314 #ifdef GL_GLES
2315 # ifdef HAVE_WAYLAND
2316   void *wlid, *wl_buf = NULL;
2317 # endif
2318 #endif
2319 
2320   gl_context = gl_generic_context_find(engine, 1);
2321   ob = gl_generic_any_output_get(engine);
2322   if (!im)
2323     {
2324        if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
2325          {
2326             im = glsym_evas_gl_common_image_new_from_data(gl_context,
2327                                                     ns->data.opengl.w,
2328                                                     ns->data.opengl.h,
2329                                                     NULL, 1,
2330                                                     EVAS_COLORSPACE_ARGB8888);
2331          }
2332        else
2333          return NULL;
2334     }
2335 
2336   if (ns)
2337     {
2338        if (ns->type == EVAS_NATIVE_SURFACE_X11)
2339          {
2340             vis = ns->data.x11.visual;
2341             pm = ns->data.x11.pixmap;
2342             if (im->native.data)
2343               {
2344                  Evas_Native_Surface *ens = im->native.data;
2345                  if ((ens->data.x11.visual == vis) &&
2346                      (ens->data.x11.pixmap == pm))
2347                    return im;
2348               }
2349          }
2350        else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
2351          {
2352             tex = ns->data.opengl.texture_id;
2353             fbo = ns->data.opengl.framebuffer_id;
2354             if (im->native.data)
2355               {
2356                  Evas_Native_Surface *ens = im->native.data;
2357                  if ((ens->data.opengl.texture_id == tex) &&
2358                      (ens->data.opengl.framebuffer_id == fbo))
2359                    return im;
2360               }
2361          }
2362        else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
2363          {
2364             buffer = ns->data.tbm.buffer;
2365             if (im->native.data)
2366               {
2367                  Evas_Native_Surface *ens = im->native.data;
2368                  if (ens->data.tbm.buffer == buffer)
2369                    return im;
2370               }
2371          }
2372        else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
2373          {
2374             buffer = ns->data.evasgl.surface;
2375             if (im->native.data)
2376               {
2377                  Evas_Native_Surface *ens = im->native.data;
2378                  if (ens->data.evasgl.surface == buffer)
2379                    return im;
2380               }
2381          }
2382        else if (ns->type == EVAS_NATIVE_SURFACE_WL)
2383           {
2384 #ifdef GL_GLES
2385 # ifdef HAVE_WAYLAND
2386              wl_buf = ns->data.wl.legacy_buffer;
2387              if (im->native.data)
2388                {
2389                   Evas_Native_Surface *ens;
2390 
2391                   ens = im->native.data;
2392                   if (ens->data.wl.legacy_buffer == wl_buf)
2393                     return im;
2394                }
2395 # endif
2396 #endif
2397           }
2398     }
2399    if (!ns)
2400      {
2401         glsym_evas_gl_common_image_free(im);
2402         return NULL;
2403      }
2404 
2405 
2406   if (ns->type == EVAS_NATIVE_SURFACE_X11)
2407     {
2408        pmid = pm;
2409        im2 = eina_hash_find(gl_context->shared->native_pm_hash, &pmid);
2410        if (im2 == im) return im;
2411        if (im2)
2412          {
2413             n = im2->native.data;
2414             if (n)
2415               {
2416                  glsym_evas_gl_common_image_ref(im2);
2417                  glsym_evas_gl_common_image_free(im);
2418                  return im2;
2419               }
2420          }
2421     }
2422   else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
2423     {
2424        texid = tex;
2425        im2 = eina_hash_find(gl_context->shared->native_tex_hash, &texid);
2426        if (im2 == im) return im;
2427        if (im2)
2428          {
2429             n = im2->native.data;
2430             if (n)
2431               {
2432                  glsym_evas_gl_common_image_ref(im2);
2433                  glsym_evas_gl_common_image_free(im);
2434                  return im2;
2435               }
2436          }
2437     }
2438   else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
2439     {
2440        im2 = eina_hash_find(gl_context->shared->native_tbm_hash, &buffer);
2441        if (im2 == im) return im;
2442        if (im2)
2443          {
2444             n = im2->native.data;
2445             if (n)
2446              {
2447                 glsym_evas_gl_common_image_ref(im2);
2448                 glsym_evas_gl_common_image_free(im);
2449                 return im2;
2450              }
2451          }
2452     }
2453   else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
2454     {
2455        im2 = eina_hash_find(gl_context->shared->native_evasgl_hash, &buffer);
2456        if (im2 == im) return im;
2457        if (im2)
2458          {
2459             n = im2->native.data;
2460             if (n)
2461               {
2462                  glsym_evas_gl_common_image_ref(im2);
2463                  glsym_evas_gl_common_image_free(im);
2464                  return im2;
2465               }
2466          }
2467     }
2468   else if (ns->type == EVAS_NATIVE_SURFACE_WL)
2469      {
2470 #ifdef GL_GLES
2471 # ifdef HAVE_WAYLAND
2472         wlid = wl_buf;
2473         im2 = eina_hash_find(gl_context->shared->native_wl_hash, &wlid);
2474         if (im2 == im) return im;
2475         if (im2)
2476           {
2477              if((n = im2->native.data))
2478                {
2479                   glsym_evas_gl_common_image_ref(im2);
2480                   glsym_evas_gl_common_image_free(im);
2481                   return im2;
2482                }
2483           }
2484 # endif
2485 #endif
2486      }
2487   im2 = glsym_evas_gl_common_image_new_from_data(gl_context,
2488                                                  im->w, im->h, NULL, im->alpha,
2489                                                  EVAS_COLORSPACE_ARGB8888);
2490   glsym_evas_gl_common_image_free(im);
2491   im = im2;
2492   if (!im) return NULL;
2493   if (ns->type == EVAS_NATIVE_SURFACE_X11)
2494     {
2495 #ifdef GL_GLES
2496        if (native)
2497          {
2498             if (!glsym_evas_gl_common_eglDestroyImage)
2499               {
2500                  ERR("Try eglCreateImage on EGL with no support");
2501                  return NULL;
2502               }
2503             n = calloc(1, sizeof(Native));
2504             if (n)
2505               {
2506                  EGLConfig egl_config;
2507                  int config_attrs[20];
2508                  int num_config, i = 0;
2509                  int yinvert = 1;
2510 
2511                  // assume 32bit pixmap! :)
2512                  config_attrs[i++] = EGL_RED_SIZE;
2513                  config_attrs[i++] = 8;
2514                  config_attrs[i++] = EGL_GREEN_SIZE;
2515                  config_attrs[i++] = 8;
2516                  config_attrs[i++] = EGL_BLUE_SIZE;
2517                  config_attrs[i++] = 8;
2518                  config_attrs[i++] = EGL_ALPHA_SIZE;
2519                  config_attrs[i++] = 8;
2520                  config_attrs[i++] = EGL_DEPTH_SIZE;
2521                  config_attrs[i++] = 0;
2522                  config_attrs[i++] = EGL_STENCIL_SIZE;
2523                  config_attrs[i++] = 0;
2524                  config_attrs[i++] = EGL_RENDERABLE_TYPE;
2525                  if (gles3_supported)
2526                    config_attrs[i++] = EGL_OPENGL_ES3_BIT_KHR;
2527                  else
2528                    config_attrs[i++] = EGL_OPENGL_ES2_BIT;
2529                  config_attrs[i++] = EGL_SURFACE_TYPE;
2530                  config_attrs[i++] = EGL_PIXMAP_BIT;
2531                  config_attrs[i++] = EGL_NONE;
2532 
2533                  if (!eglChooseConfig(ob->egl_disp, config_attrs,
2534                                       &egl_config, 1, &num_config))
2535                    {
2536                       int err = eglGetError();
2537                       ERR("eglChooseConfig() failed for pixmap %#lx, "
2538                           "num_config = %i with error %d", pm, num_config, err);
2539                       glsym_evas_gl_common_error_set(err - EGL_SUCCESS);
2540                       free(n);
2541                       return NULL;
2542                    }
2543                  else
2544                    {
2545                       int val;
2546                       if (extn_have_y_inverted &&
2547                           eglGetConfigAttrib(ob->egl_disp, egl_config,
2548                                              EGL_Y_INVERTED_NOK, &val))
2549                             yinvert = val;
2550                    }
2551 
2552                  memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
2553                  n->ns_data.x11.pixmap = pm;
2554                  n->ns_data.x11.visual = vis;
2555                  n->ns_data.x11.surface = glsym_evas_gl_common_eglCreateImage(ob->egl_disp,
2556                                                           EGL_NO_CONTEXT,
2557                                                           EGL_NATIVE_PIXMAP_KHR,
2558                                                           (void *)pm, NULL);
2559 
2560                  if ((ns->version < 4) ||
2561                      ((ns->version == 4) && !(ns->data.x11.multiple_buffer == 1)))
2562                    n->ns_data.x11.multiple_buffer = 0;
2563                  else
2564                    n->ns_data.x11.multiple_buffer = 1;
2565                  if (ob->detected.no_multi_buffer_native)
2566                    n->ns_data.x11.multiple_buffer = 0;
2567 
2568                  if (!n->ns_data.x11.surface)
2569                    {
2570                       WRN("eglCreateImage() for Pixmap %#lx failed: %#x", pm, eglGetError());
2571                       free(n);
2572                       return NULL;
2573                    }
2574                  n->ns_data.x11.config = (void *)egl_config;
2575                  im->native.yinvert     = yinvert;
2576                  im->native.loose       = 0;
2577                  im->native.disp        = ob->egl_disp;
2578                  im->native.shared      = gl_context->shared;
2579                  im->native.data        = n;
2580                  im->native.func.bind   = _native_bind_cb;
2581                  im->native.func.unbind = _native_unbind_cb;
2582                  im->native.func.free   = _native_free_cb;
2583                  im->native.target      = GL_TEXTURE_2D;
2584                  im->native.mipmap      = 0;
2585                  eina_hash_add(ob->gl_context->shared->native_pm_hash, &pmid, im);
2586                  glsym_evas_gl_common_image_native_enable(im);
2587              }
2588          }
2589 #else
2590 # ifdef GLX_BIND_TO_TEXTURE_TARGETS_EXT
2591        if (native)
2592          {
2593             int dummy;
2594             unsigned int w, h, depth = 32, border;
2595             Window wdummy;
2596 
2597             // fixme: round trip :(
2598             XGetGeometry(ob->disp, pm, &wdummy, &dummy, &dummy,
2599                          &w, &h, &border, &depth);
2600             if (depth <= 32)
2601               {
2602                  n = calloc(1, sizeof(Native));
2603                  if (n)
2604                    {
2605                       int pixmap_att[20], i;
2606                       int config_attrs[40], num = 0;
2607                       int tex_format = 0, tex_target = 0, yinvert = 0, mipmap = 0;
2608                       unsigned int target = 0;
2609                       GLXFBConfig *configs;
2610 
2611                       i = 0;
2612                       config_attrs[i++] = GLX_BUFFER_SIZE;
2613                       config_attrs[i++] = depth;
2614                       if (depth == 32)
2615                         {
2616                            config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGBA_EXT;
2617                            config_attrs[i++] = 1;
2618                         }
2619                       else
2620                         {
2621                            config_attrs[i++] = GLX_BIND_TO_TEXTURE_RGB_EXT;
2622                            config_attrs[i++] = 1;
2623                         }
2624 
2625 #ifndef GLX_VISUAL_ID
2626 # define GLX_VISUAL_ID 0x800b
2627 #endif
2628                       config_attrs[i++] = GLX_VISUAL_ID;
2629                       config_attrs[i++] = XVisualIDFromVisual(vis);
2630 #ifndef GLX_SAMPLE_BUFFERS
2631 # define GLX_SAMPLE_BUFFERS 0x186a0
2632 #endif
2633                       config_attrs[i++] = GLX_SAMPLE_BUFFERS;
2634                       config_attrs[i++] = 0;
2635                       config_attrs[i++] = GLX_DEPTH_SIZE;
2636                       config_attrs[i++] = 0;
2637                       config_attrs[i++] = GLX_STENCIL_SIZE;
2638                       config_attrs[i++] = 0;
2639                       config_attrs[i++] = GLX_AUX_BUFFERS;
2640                       config_attrs[i++] = 0;
2641                       config_attrs[i++] = GLX_STEREO;
2642                       config_attrs[i++] = 0;
2643 
2644                       config_attrs[i++] = 0;
2645 
2646                       configs = glXChooseFBConfig(ob->disp,
2647                                                   ob->screen,
2648                                                   config_attrs,
2649                                                   &num);
2650                       if (configs)
2651                         {
2652                            int j = 0, val = 0, found = 0;
2653 
2654                            try_again:
2655                            for (j = 0; j < num; j++)
2656                              {
2657                                 if (found == 0)
2658                                   {
2659                                      XVisualInfo *vi;
2660 
2661                                      vi = glXGetVisualFromFBConfig(ob->disp, configs[j]);
2662                                      if (!vi) continue;
2663                                      if (vi->depth != (int)depth) continue;
2664                                      XFree(vi);
2665 
2666                                      glXGetFBConfigAttrib(ob->disp, configs[j],
2667                                                           GLX_BUFFER_SIZE, &val);
2668                                      if (val != (int) depth) continue;
2669                                   }
2670                                 glXGetFBConfigAttrib(ob->disp, configs[j],
2671                                                      GLX_DRAWABLE_TYPE, &val);
2672                                 if (!(val & GLX_PIXMAP_BIT)) continue;
2673                                 tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
2674                                 glXGetFBConfigAttrib(ob->disp, configs[j],
2675                                                      GLX_ALPHA_SIZE, &val);
2676                                 if ((depth == 32) && (!val)) continue;
2677                                 if (val > 0)
2678                                   {
2679                                      glXGetFBConfigAttrib(ob->disp, configs[j],
2680                                                           GLX_BIND_TO_TEXTURE_RGBA_EXT, &val);
2681                                      if (val) tex_format = GLX_TEXTURE_FORMAT_RGBA_EXT;
2682                                   }
2683                                 else
2684                                   {
2685                                      glXGetFBConfigAttrib(ob->disp, configs[j],
2686                                                           GLX_BIND_TO_TEXTURE_RGB_EXT, &val);
2687                                      if (val) tex_format = GLX_TEXTURE_FORMAT_RGB_EXT;
2688                                   }
2689                                 glXGetFBConfigAttrib(ob->disp, configs[j],
2690                                                      GLX_Y_INVERTED_EXT, &val);
2691                                 if (val) yinvert = 1;
2692                                 glXGetFBConfigAttrib(ob->disp, configs[j],
2693                                                      GLX_BIND_TO_TEXTURE_TARGETS_EXT,
2694                                                      &val);
2695                                 tex_target = val;
2696                                 glXGetFBConfigAttrib(ob->disp, configs[j],
2697                                                      GLX_BIND_TO_MIPMAP_TEXTURE_EXT, &val);
2698                                 mipmap = val;
2699                                 n->ns_data.x11.config = configs[j];
2700                                 found = 1;
2701                                 break;
2702                              }
2703                            if (found == 0)
2704                              {
2705                                 found = -1;
2706                                 goto try_again;
2707                              }
2708                            XFree(configs);
2709                         }
2710 
2711                       eina_hash_add(gl_context->shared->native_pm_hash, &pmid, im);
2712                       if ((tex_target & GLX_TEXTURE_2D_BIT_EXT))
2713                         target = GLX_TEXTURE_2D_EXT;
2714                       else if ((tex_target & GLX_TEXTURE_RECTANGLE_BIT_EXT))
2715                         {
2716                            ERR("rect!!! (not handled)");
2717                            target = GLX_TEXTURE_RECTANGLE_EXT;
2718                         }
2719                       if (!target)
2720                         {
2721                            ERR("broken tex-from-pixmap");
2722                            if (!(tex_target & GLX_TEXTURE_2D_BIT_EXT))
2723                              target = GLX_TEXTURE_RECTANGLE_EXT;
2724                            else if (!(tex_target & GLX_TEXTURE_RECTANGLE_BIT_EXT))
2725                              target = GLX_TEXTURE_2D_EXT;
2726                         }
2727 
2728                       i = 0;
2729                       pixmap_att[i++] = GLX_TEXTURE_FORMAT_EXT;
2730                       pixmap_att[i++] = tex_format;
2731                       pixmap_att[i++] = GLX_MIPMAP_TEXTURE_EXT;
2732                       pixmap_att[i++] = mipmap;
2733                       if (target)
2734                         {
2735                            pixmap_att[i++] = GLX_TEXTURE_TARGET_EXT;
2736                            pixmap_att[i++] = target;
2737                         }
2738                       pixmap_att[i++] = 0;
2739 
2740                       memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
2741                       n->ns_data.x11.pixmap = pm;
2742                       n->ns_data.x11.visual = vis;
2743                       if (glsym_glXCreatePixmap)
2744                         n->ns_data.x11.surface = (void *)glsym_glXCreatePixmap(ob->disp,
2745                                                                    n->ns_data.x11.config,
2746                                                                    n->ns_data.x11.pixmap,
2747                                                                    pixmap_att);
2748                       else
2749                         ERR("Try glXCreatePixmap on GLX with no support");
2750                       if (n->ns_data.x11.surface)
2751                         {
2752 //                          printf("%p: new native texture for %x | %4i x %4i @ %2i = %p\n",
2753 //                                  n, pm, w, h, depth, n->surface);
2754                            if (!target)
2755                              {
2756                                 ERR("no target :(");
2757                                 if (glsym_glXQueryDrawable)
2758                                   glsym_glXQueryDrawable(ob->disp,
2759                                                          n->ns_data.x11.pixmap,
2760                                                          GLX_TEXTURE_TARGET_EXT,
2761                                                          &target);
2762                              }
2763                            if (target == GLX_TEXTURE_2D_EXT)
2764                              {
2765                                 im->native.target = GL_TEXTURE_2D;
2766                                 im->native.mipmap = mipmap;
2767                              }
2768 #  ifdef GL_TEXTURE_RECTANGLE_ARB
2769                            else if (target == GLX_TEXTURE_RECTANGLE_EXT)
2770                              {
2771                                 im->native.target = GL_TEXTURE_RECTANGLE_ARB;
2772                                 im->native.mipmap = 0;
2773                              }
2774 #  endif
2775                            else
2776                              {
2777                                 im->native.target = GL_TEXTURE_2D;
2778                                 im->native.mipmap = 0;
2779                                 ERR("still unknown target");
2780                              }
2781                         }
2782                       else
2783                         ERR("GLX Pixmap create fail");
2784                       im->native.yinvert     = yinvert;
2785                       im->native.loose       = ob->detected.loose_binding;
2786                       im->native.disp        = ob->disp;
2787                       im->native.shared      = gl_context->shared;
2788                       im->native.data        = n;
2789                       im->native.func.bind   = _native_bind_cb;
2790                       im->native.func.unbind = _native_unbind_cb;
2791                       im->native.func.free   = _native_free_cb;
2792 
2793                       glsym_evas_gl_common_image_native_enable(im);
2794                    }
2795               }
2796          }
2797 # endif
2798 #endif
2799     }
2800   else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
2801     {
2802        if (native)
2803          {
2804             n = calloc(1, sizeof(Native));
2805             if (n)
2806               {
2807                  memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
2808 
2809                  eina_hash_add(gl_context->shared->native_tex_hash, &texid, im);
2810 
2811                  n->ns_data.opengl.surface = 0;
2812 
2813                  im->native.yinvert     = 0;
2814                  im->native.loose       = 0;
2815 #ifdef GL_GLES
2816                  im->native.disp        = ob->egl_disp;
2817 #else
2818                  im->native.disp        = ob->disp;
2819 #endif
2820                  im->native.shared      = gl_context->shared;
2821                  im->native.data        = n;
2822                  im->native.func.bind   = _native_bind_cb;
2823                  im->native.func.unbind = _native_unbind_cb;
2824                  im->native.func.free   = _native_free_cb;
2825                  im->native.target      = GL_TEXTURE_2D;
2826                  im->native.mipmap      = 0;
2827 
2828                  // FIXME: need to implement mapping sub texture regions
2829                  // x, y, w, h for possible texture atlasing
2830 
2831                  glsym_evas_gl_common_image_native_enable(im);
2832               }
2833          }
2834     }
2835   else if (ns->type == EVAS_NATIVE_SURFACE_TBM)
2836     {
2837 #ifdef GL_GLES
2838        if (native)
2839          {
2840             n = calloc(1, sizeof(Native));
2841             if (n)
2842               {
2843                  eina_hash_add(gl_context->shared->native_tbm_hash, &buffer, im);
2844 
2845                  memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
2846                  n->ns_data.tbm.buffer = buffer;
2847                  if (glsym_evas_gl_common_eglDestroyImage)
2848                    n->ns_data.tbm.surface =
2849                      glsym_evas_gl_common_eglCreateImage(ob->egl_disp,
2850                                                          EGL_NO_CONTEXT,
2851                                                          EGL_NATIVE_SURFACE_TIZEN,
2852                                                          (void *)buffer,
2853                                                          NULL);
2854                  else
2855                    ERR("Try eglCreateImage on EGL with no support");
2856                  if (!n->ns_data.tbm.surface)
2857                    WRN("eglCreateImage() for %p failed", buffer);
2858                  im->native.yinvert     = 1;
2859                  im->native.loose       = 0;
2860                  im->native.disp        = ob->egl_disp;
2861                  im->native.shared      = gl_context->shared;
2862                  im->native.data        = n;
2863                  im->native.func.bind   = _native_bind_cb;
2864                  im->native.func.unbind = _native_unbind_cb;
2865                  im->native.func.free   = _native_free_cb;
2866                  im->native.target      = GL_TEXTURE_EXTERNAL_OES;
2867                  im->native.mipmap      = 0;
2868                  glsym_evas_gl_common_image_native_enable(im);
2869               }
2870          }
2871 #endif
2872     }
2873   else if (ns->type == EVAS_NATIVE_SURFACE_EVASGL)
2874     {
2875        if (native)
2876          {
2877             n = calloc(1, sizeof(Native));
2878             if (n)
2879               {
2880                  memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
2881 
2882                  eina_hash_add(gl_context->shared->native_evasgl_hash, &buffer, im);
2883 
2884                  n->ns_data.evasgl.surface = ns->data.evasgl.surface;
2885 
2886                  im->native.yinvert      = 0;
2887                  im->native.loose        = 0;
2888 #ifdef GL_GLES
2889                  im->native.disp        = ob->egl_disp;
2890 #else
2891                  im->native.disp        = ob->disp;
2892 #endif
2893                  im->native.shared      = gl_context->shared;
2894                  im->native.data         = n;
2895                  im->native.func.bind    = _native_bind_cb;
2896                  im->native.func.unbind  = _native_unbind_cb;
2897                  im->native.func.free    = _native_free_cb;
2898                  im->native.func.yinvert = _native_yinvert_cb;
2899                  im->native.target       = GL_TEXTURE_2D;
2900                  im->native.mipmap       = 0;
2901 
2902                  // FIXME: need to implement mapping sub texture regions
2903                  // x, y, w, h for possible texture atlasing
2904 
2905                  glsym_evas_gl_common_image_native_enable(im);
2906               }
2907          }
2908     }
2909    else if (ns->type == EVAS_NATIVE_SURFACE_WL)
2910      {
2911 #ifdef GL_GLES
2912 # ifdef HAVE_WAYLAND
2913         if (native)
2914           {
2915              if ((n = calloc(1, sizeof(Native))))
2916                {
2917                   EGLAttrib attribs[3];
2918                   int format, yinvert = 1;
2919 
2920                   glsym_eglQueryWaylandBufferWL(ob->egl_disp, wl_buf,
2921                                                 EGL_TEXTURE_FORMAT, &format);
2922                   if ((format != EGL_TEXTURE_RGB) &&
2923                       (format != EGL_TEXTURE_RGBA))
2924                     {
2925                        ERR("eglQueryWaylandBufferWL() %d format is not supported ", format);
2926                        glsym_evas_gl_common_image_free(im);
2927                        free(n);
2928                        return NULL;
2929                     }
2930 
2931 #  ifndef EGL_WAYLAND_PLANE_WL
2932 #   define EGL_WAYLAND_PLANE_WL 0x31D6
2933 #  endif
2934 #  ifndef EGL_WAYLAND_BUFFER_WL
2935 #   define EGL_WAYLAND_BUFFER_WL 0x31D5
2936 #  endif
2937                   attribs[0] = EGL_WAYLAND_PLANE_WL;
2938                   attribs[1] = 0; //if plane is 1 then 0, if plane is 2 then 1
2939                   attribs[2] = EGL_NONE;
2940 
2941                   memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
2942                   if (glsym_eglQueryWaylandBufferWL(ob->egl_disp, wl_buf,
2943                                                     EGL_WAYLAND_Y_INVERTED_WL,
2944                                                     &yinvert) == EGL_FALSE)
2945                     yinvert = 1;
2946                   eina_hash_add(gl_context->shared->native_wl_hash,
2947                                 &wlid, im);
2948 
2949                   n->ns_data.wl_surface.wl_buf = wl_buf;
2950                   if (glsym_evas_gl_common_eglDestroyImage)
2951                     n->ns_data.wl_surface.surface =
2952                       glsym_evas_gl_common_eglCreateImage(ob->egl_disp,
2953                                                           NULL,
2954                                                           EGL_WAYLAND_BUFFER_WL,
2955                                                           wl_buf, attribs);
2956                   else
2957                     {
2958                        ERR("Try eglCreateImage on EGL with no support");
2959                        eina_hash_del(gl_context->shared->native_wl_hash,
2960                                      &wlid, im);
2961                        glsym_evas_gl_common_image_free(im);
2962                        free(n);
2963                        return NULL;
2964                     }
2965 
2966                   if (!n->ns_data.wl_surface.surface)
2967                     {
2968                        WRN("eglCreatePixmapSurface() for %p failed", wl_buf);
2969                        eina_hash_del(gl_context->shared->native_wl_hash,
2970                                      &wlid, im);
2971                        glsym_evas_gl_common_image_free(im);
2972                        free(n);
2973                        return NULL;
2974                     }
2975 
2976                   //XXX: workaround for mesa-10.2.8
2977                   // mesa's eglQueryWaylandBufferWL() with EGL_WAYLAND_Y_INVERTED_WL works incorrect.
2978                   //im->native.yinvert = yinvert;
2979                   im->native.yinvert = 1;
2980                   im->native.loose = 0;
2981                   im->native.disp        = ob->egl_disp;
2982                   im->native.shared      = gl_context->shared;
2983                   im->native.data = n;
2984                   im->native.func.bind = _native_bind_cb;
2985                   im->native.func.unbind = _native_unbind_cb;
2986                   im->native.func.free = _native_free_cb;
2987                   im->native.target = GL_TEXTURE_2D;
2988                   im->native.mipmap = 0;
2989 
2990                   glsym_evas_gl_common_image_native_enable(im);
2991                }
2992           }
2993 # endif
2994 #endif
2995      }
2996    return im;
2997 }
2998 
2999 static int
module_open(Evas_Module * em)3000 module_open(Evas_Module *em)
3001 {
3002    static Eina_Bool xrm_inited = EINA_FALSE;
3003    const char *platform_env = NULL;
3004    if (!xrm_inited)
3005      {
3006         xrm_inited = EINA_TRUE;
3007         XrmInitialize();
3008      }
3009    if (!em) return 0;
3010    /* get whatever engine module we inherit from */
3011    if (!_evas_module_engine_inherit(&pfunc, "gl_generic", sizeof (Evas_Engine_Info_GL_X11))) return 0;
3012    if (_evas_engine_GL_X11_log_dom < 0)
3013      _evas_engine_GL_X11_log_dom = eina_log_domain_register
3014        ("evas-gl_x11", EVAS_DEFAULT_LOG_COLOR);
3015    if (_evas_engine_GL_X11_log_dom < 0)
3016      {
3017         EINA_LOG_ERR("Can not create a module log domain.");
3018         return 0;
3019      }
3020 
3021    if (partial_render_debug == -1)
3022      {
3023         if (getenv("EVAS_GL_PARTIAL_DEBUG")) partial_render_debug = 1;
3024         else partial_render_debug = 0;
3025      }
3026 //   partial_render_debug = 1;
3027 
3028    /* store it for later use */
3029    func = pfunc;
3030    /* now to override methods */
3031    #define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_)
3032    ORD(output_info_setup);
3033    ORD(output_setup);
3034    ORD(output_update);
3035    ORD(canvas_alpha_get);
3036    ORD(output_free);
3037    ORD(output_dump);
3038 
3039    ORD(image_native_init);
3040    ORD(image_native_shutdown);
3041    ORD(image_native_set);
3042 
3043    ORD(gl_error_get);
3044    // gl_current_surface_get is in gl generic
3045    ORD(gl_current_context_get);
3046 
3047    if (!(platform_env = getenv("EGL_PLATFORM")))
3048       setenv("EGL_PLATFORM", "x11", 0);
3049 
3050    gl_symbols();
3051 
3052    if (!platform_env)
3053       unsetenv("EGL_PLATFORM");
3054 
3055    /* now advertise out own api */
3056    em->functions = (void *)(&func);
3057    return 1;
3058 }
3059 
3060 static void
module_close(Evas_Module * em EINA_UNUSED)3061 module_close(Evas_Module *em EINA_UNUSED)
3062 {
3063    if (_evas_engine_GL_X11_log_dom >= 0)
3064      {
3065         eina_log_domain_unregister(_evas_engine_GL_X11_log_dom);
3066         _evas_engine_GL_X11_log_dom = -1;
3067      }
3068 }
3069 
3070 static Evas_Module_Api evas_modapi =
3071 {
3072    EVAS_MODULE_API_VERSION,
3073    "gl_x11",
3074    "none",
3075    {
3076      module_open,
3077      module_close
3078    }
3079 };
3080 
3081 EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, gl_x11);
3082 
3083 #ifndef EVAS_STATIC_BUILD_GL_XLIB
3084 EVAS_EINA_MODULE_DEFINE(engine, gl_x11);
3085 #endif
3086 
3087 /* vim:set ts=8 sw=3 sts=3 expandtab cino=>5n-2f0^-2{2(0W1st0 :*/
3088