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