summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Aguirre <aguirre.nicolas@gmail.com>2015-08-03 14:34:56 +0200
committerNicolas Aguirre <aguirre.nicolas@gmail.com>2015-08-03 14:34:56 +0200
commitc1a483f2af687d3d3e6e3df6fa190b887c1b1a39 (patch)
treed53d614a80a129ff9bb8057ecaa755cbf7994745
parent3594b230affeca3e940e19b2811b1d27ca9d6f85 (diff)
Revert "evas: Adds an eglfs module"
This reverts commit 270215889d5ba4e93f9ec05cfa9a9510a345c96c.
-rw-r--r--src/modules/evas/engines/eglfs/Evas_Engine_Eglfs.h45
-rw-r--r--src/modules/evas/engines/eglfs/evas_engine.c1245
-rw-r--r--src/modules/evas/engines/eglfs/evas_engine.h129
-rw-r--r--src/modules/evas/engines/eglfs/evas_outbuf.c509
4 files changed, 0 insertions, 1928 deletions
diff --git a/src/modules/evas/engines/eglfs/Evas_Engine_Eglfs.h b/src/modules/evas/engines/eglfs/Evas_Engine_Eglfs.h
deleted file mode 100644
index 8746e41549..0000000000
--- a/src/modules/evas/engines/eglfs/Evas_Engine_Eglfs.h
+++ /dev/null
@@ -1,45 +0,0 @@
1#ifndef _EVAS_ENGINE_EGLFS_H
2# define _EVAS_ENGINE_EGLFS_H
3
4typedef enum _Evas_Engine_Info_Eglfs_Swap_Mode
5{
6 EVAS_ENGINE_EGLFS_SWAP_MODE_AUTO = 0,
7 EVAS_ENGINE_EGLFS_SWAP_MODE_FULL = 1,
8 EVAS_ENGINE_EGLFS_SWAP_MODE_COPY = 2,
9 EVAS_ENGINE_EGLFS_SWAP_MODE_DOUBLE = 3,
10 EVAS_ENGINE_EGLFS_SWAP_MODE_TRIPLE = 4,
11 EVAS_ENGINE_EGLFS_SWAP_MODE_QUADRUPLE = 5
12} Evas_Engine_Info_Eglfs_Swap_Mode;
13
14typedef struct _Evas_Engine_Info_Eglfs Evas_Engine_Info_Eglfs;
15
16struct _Evas_Engine_Info_Eglfs
17{
18 /* PRIVATE - don't mess with this baby or evas will poke its tongue out */
19 /* at you and make nasty noises */
20 Evas_Engine_Info magic;
21
22 struct
23 {
24 unsigned int rotation, depth;
25 unsigned int crtc_id, conn_id, buffer_id;
26 unsigned int format, flags;
27
28 Eina_Bool destination_alpha : 1;
29 Eina_Bool vsync : 1;
30 Eina_Bool indirect : 1;
31 unsigned char swap_mode : 4;
32 } info;
33
34 struct
35 {
36 void (*pre_swap)(void *data, Evas *evas);
37 void (*post_swap)(void *data, Evas *evas);
38 void *data;
39 } callback;
40
41 /* non-blocking or blocking mode */
42 Evas_Engine_Render_Mode render_mode;
43};
44
45#endif
diff --git a/src/modules/evas/engines/eglfs/evas_engine.c b/src/modules/evas/engines/eglfs/evas_engine.c
deleted file mode 100644
index 7c59f6f7ef..0000000000
--- a/src/modules/evas/engines/eglfs/evas_engine.c
+++ /dev/null
@@ -1,1245 +0,0 @@
1#include "config.h"
2#include "evas_engine.h"
3#include <wayland-client.h>
4
5#ifdef HAVE_DLSYM
6# include <dlfcn.h> /* dlopen,dlclose,etc */
7#else
8# error eglfs should not get compiled if dlsym is not found on the system!
9#endif
10
11#ifdef EVAS_CSERVE2
12# include "evas_cs2_private.h"
13#endif
14
15#define EVAS_GL_NO_GL_H_CHECK 1
16#include "Evas_GL.h"
17
18#define EVAS_GL_UPDATE_TILE_SIZE 16
19
20#ifndef EGL_NATIVE_PIXMAP_KHR
21# define EGL_NATIVE_PIXMAP_KHR 0x30b0
22#endif
23
24/* external variables */
25int _evas_engine_eglfs_log_dom = -1;
26int _extn_have_buffer_age = 1;
27
28/* local variables */
29static Eina_Bool initted = EINA_FALSE;
30static int gl_wins = 0;
31
32/* local structures */
33typedef struct _Render_Engine Render_Engine;
34struct _Render_Engine
35{
36 Render_Engine_GL_Generic generic;
37};
38
39typedef struct _Native Native;
40struct _Native
41{
42 Evas_Native_Surface ns;
43 struct wl_buffer *wl_buf;
44 void *egl_surface;
45};
46
47/* local function prototype types */
48typedef void (*_eng_fn)(void);
49typedef _eng_fn (*glsym_func_eng_fn)();
50typedef void (*glsym_func_void)();
51typedef void *(*glsym_func_void_ptr)();
52typedef int (*glsym_func_int)();
53typedef unsigned int (*glsym_func_uint)();
54typedef const char *(*glsym_func_const_char_ptr)();
55
56/* external dynamic loaded Evas_GL function pointers */
57Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL;
58Evas_GL_Common_Image_Call glsym_evas_gl_common_image_unref = NULL;
59Evas_GL_Common_Image_Call glsym_evas_gl_common_image_free = NULL;
60Evas_GL_Common_Image_Call glsym_evas_gl_common_image_native_disable = NULL;
61Evas_GL_Common_Image_Call glsym_evas_gl_common_image_native_enable = NULL;
62Evas_GL_Common_Image_New_From_Data glsym_evas_gl_common_image_new_from_data = NULL;
63Evas_GL_Common_Context_Call glsym_evas_gl_common_image_all_unload = NULL;
64Evas_GL_Preload glsym_evas_gl_preload_init = NULL;
65Evas_GL_Preload glsym_evas_gl_preload_shutdown = NULL;
66EVGL_Engine_Call glsym_evgl_engine_shutdown = NULL;
67EVGL_Current_Native_Context_Get_Call glsym_evgl_current_native_context_get = NULL;
68Evas_Gl_Symbols glsym_evas_gl_symbols = NULL;
69
70Evas_GL_Common_Context_New glsym_evas_gl_common_context_new = NULL;
71Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush = NULL;
72Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free = NULL;
73Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use = NULL;
74Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe = NULL;
75Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done = NULL;
76Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize = NULL;
77Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump = NULL;
78Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock = NULL;
79Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL;
80Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL;
81
82glsym_func_void_ptr glsym_evas_gl_common_current_context_get = NULL;
83
84/* dynamic loaded local egl function pointers */
85_eng_fn (*glsym_eglGetProcAddress)(const char *a) = NULL;
86void *(*glsym_eglCreateImage)(EGLDisplay a, EGLContext b, EGLenum c, EGLClientBuffer d, const int *e) = NULL;
87void (*glsym_eglDestroyImage)(EGLDisplay a, void *b) = NULL;
88void (*glsym_glEGLImageTargetTexture2DOES)(int a, void *b) = NULL;
89unsigned int (*glsym_eglSwapBuffersWithDamage)(EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL;
90unsigned int (*glsym_eglQueryWaylandBufferWL)(EGLDisplay a, struct wl_resource *b, EGLint c, EGLint *d) = NULL;
91
92/* local function prototypes */
93static void gl_symbols(void);
94static void gl_extn_veto(Render_Engine *re);
95
96static void *evgl_eng_display_get(void *data);
97static void *evgl_eng_evas_surface_get(void *data);
98static int evgl_eng_make_current(void *data, void *surface, void *context, int flush);
99static void *evgl_eng_native_window_create(void *data);
100static int evgl_eng_native_window_destroy(void *data, void *native_window);
101static void *evgl_eng_window_surface_create(void *data, void *native_window);
102static int evgl_eng_window_surface_destroy(void *data, void *surface);
103static void *evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version);
104static int evgl_eng_context_destroy(void *data, void *context);
105static const char *evgl_eng_string_get(void *data);
106static void *evgl_eng_proc_address_get(const char *name);
107static int evgl_eng_rotation_angle_get(void *data);
108
109/* function tables - filled in later (func and parent func) */
110static Evas_Func func, pfunc;
111static const EVGL_Interface evgl_funcs =
112{
113 evgl_eng_display_get,
114 evgl_eng_evas_surface_get,
115 evgl_eng_native_window_create,
116 evgl_eng_native_window_destroy,
117 evgl_eng_window_surface_create,
118 evgl_eng_window_surface_destroy,
119 evgl_eng_context_create,
120 evgl_eng_context_destroy,
121 evgl_eng_make_current,
122 evgl_eng_proc_address_get,
123 evgl_eng_string_get,
124 evgl_eng_rotation_angle_get,
125 NULL, // PBuffer
126 NULL, // PBuffer
127 NULL, // OpenGL-ES 1
128 NULL, // OpenGL-ES 1
129 NULL, // OpenGL-ES 1
130 NULL, // native_win_surface_config_get
131};
132
133/* local inline functions */
134static inline Outbuf *
135eng_get_ob(Render_Engine *re)
136{
137 return re->generic.software.ob;
138}
139
140/* local functions */
141static void
142gl_symbols(void)
143{
144 static Eina_Bool done = EINA_FALSE;
145
146 if (done) return;
147
148#define LINK2GENERIC(sym) \
149 glsym_##sym = dlsym(RTLD_DEFAULT, #sym);
150
151 // Get function pointer to evas_gl_common that is now provided through the link of GL_Generic.
152 LINK2GENERIC(evas_gl_common_image_all_unload);
153 LINK2GENERIC(evas_gl_common_image_ref);
154 LINK2GENERIC(evas_gl_common_image_unref);
155 LINK2GENERIC(evas_gl_common_image_new_from_data);
156 LINK2GENERIC(evas_gl_common_image_native_disable);
157 LINK2GENERIC(evas_gl_common_image_free);
158 LINK2GENERIC(evas_gl_common_image_native_enable);
159 LINK2GENERIC(evas_gl_common_context_new);
160 LINK2GENERIC(evas_gl_common_context_flush);
161 LINK2GENERIC(evas_gl_common_context_free);
162 LINK2GENERIC(evas_gl_common_context_use);
163 LINK2GENERIC(evas_gl_common_context_newframe);
164 LINK2GENERIC(evas_gl_common_context_done);
165 LINK2GENERIC(evas_gl_common_context_resize);
166 LINK2GENERIC(evas_gl_common_buffer_dump);
167 LINK2GENERIC(evas_gl_preload_render_lock);
168 LINK2GENERIC(evas_gl_preload_render_unlock);
169 LINK2GENERIC(evas_gl_preload_render_relax);
170 LINK2GENERIC(evas_gl_preload_init);
171 LINK2GENERIC(evas_gl_preload_shutdown);
172 LINK2GENERIC(evgl_engine_shutdown);
173 LINK2GENERIC(evas_gl_symbols);
174
175#define FINDSYM(dst, sym, typ) \
176 if (glsym_eglGetProcAddress) { \
177 if (!dst) dst = (typ)glsym_eglGetProcAddress(sym); \
178 } else { \
179 if (!dst) dst = (typ)dlsym(RTLD_DEFAULT, sym); \
180 }
181
182 FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressKHR", glsym_func_eng_fn);
183 FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressEXT", glsym_func_eng_fn);
184 FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddressARB", glsym_func_eng_fn);
185 FINDSYM(glsym_eglGetProcAddress, "eglGetProcAddress", glsym_func_eng_fn);
186
187 glsym_evas_gl_symbols((void*)glsym_eglGetProcAddress);
188
189 FINDSYM(glsym_eglCreateImage, "eglCreateImageKHR", glsym_func_void_ptr);
190 FINDSYM(glsym_eglCreateImage, "eglCreateImageEXT", glsym_func_void_ptr);
191 FINDSYM(glsym_eglCreateImage, "eglCreateImageARB", glsym_func_void_ptr);
192 FINDSYM(glsym_eglCreateImage, "eglCreateImage", glsym_func_void_ptr);
193
194 FINDSYM(glsym_eglDestroyImage, "eglDestroyImageKHR", glsym_func_void);
195 FINDSYM(glsym_eglDestroyImage, "eglDestroyImageEXT", glsym_func_void);
196 FINDSYM(glsym_eglDestroyImage, "eglDestroyImageARB", glsym_func_void);
197 FINDSYM(glsym_eglDestroyImage, "eglDestroyImage", glsym_func_void);
198
199 FINDSYM(glsym_glEGLImageTargetTexture2DOES,
200 "glEGLImageTargetTexture2DOES", glsym_func_void);
201
202 FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageEXT",
203 glsym_func_uint);
204 FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamageINTEL",
205 glsym_func_uint);
206 FINDSYM(glsym_eglSwapBuffersWithDamage, "eglSwapBuffersWithDamage",
207 glsym_func_uint);
208
209 FINDSYM(glsym_eglQueryWaylandBufferWL, "eglQueryWaylandBufferWL",
210 glsym_func_uint);
211
212 done = EINA_TRUE;
213}
214
215static void
216gl_extn_veto(Render_Engine *re)
217{
218 const char *str = NULL;
219
220 str = eglQueryString(eng_get_ob(re)->egl.disp, EGL_EXTENSIONS);
221 if (str)
222 {
223 const char *s = NULL;
224
225 if (getenv("EVAS_GL_INFO")) printf("EGL EXTN:\n%s\n", str);
226
227 // Disable Partial Rendering
228 s = getenv("EVAS_GL_PARTIAL_DISABLE");
229 if ((s) && (atoi(s)))
230 {
231 _extn_have_buffer_age = 0;
232 glsym_eglSwapBuffersWithDamage = NULL;
233 }
234 if (!strstr(str, "EGL_EXT_buffer_age")) _extn_have_buffer_age = 0;
235 if (!strstr(str, "EGL_EXT_swap_buffers_with_damage"))
236 glsym_eglSwapBuffersWithDamage = NULL;
237 }
238 else
239 {
240 if (getenv("EVAS_GL_INFO")) printf("NO EGL EXTN!\n");
241 _extn_have_buffer_age = 0;
242 }
243}
244
245static void *
246evgl_eng_display_get(void *data)
247{
248 Render_Engine *re;
249
250 re = (Render_Engine *)data;
251 if (!re)
252 {
253 ERR("Invalid Render Engine Data!");
254 return NULL;
255 }
256
257 if (eng_get_ob(re))
258 return (void *)eng_get_ob(re)->egl.disp;
259 else
260 return NULL;
261}
262
263static void *
264evgl_eng_evas_surface_get(void *data)
265{
266 Render_Engine *re;
267
268 re = (Render_Engine *)data;
269 if (!re)
270 {
271 ERR("Invalid Render Engine Data!");
272 return NULL;
273 }
274
275 if (eng_get_ob(re))
276 return (void *)eng_get_ob(re)->egl.surface[0];
277 else
278 return NULL;
279}
280
281static int
282evgl_eng_make_current(void *data, void *surface, void *context, int flush)
283{
284 Render_Engine *re;
285 EGLContext ctx;
286 EGLSurface sfc;
287 EGLDisplay dpy;
288 int ret = 0;
289
290 re = (Render_Engine *)data;
291 if (!re)
292 {
293 ERR("Invalid Render Engine Data!");
294 return 0;
295 }
296
297 dpy = eng_get_ob(re)->egl.disp;
298 ctx = (EGLContext)context;
299 sfc = (EGLSurface)surface;
300
301 if ((!context) && (!surface))
302 {
303 ret = eglMakeCurrent(dpy, EGL_NO_SURFACE,
304 EGL_NO_SURFACE, EGL_NO_CONTEXT);
305 if (!ret)
306 {
307 ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
308 return 0;
309 }
310
311 return 1;
312 }
313
314 if ((eglGetCurrentContext() != ctx) ||
315 (eglGetCurrentSurface(EGL_READ) != sfc) ||
316 (eglGetCurrentSurface(EGL_DRAW) != sfc) )
317 {
318 if (flush) evas_outbuf_use(NULL);
319
320 ret = eglMakeCurrent(dpy, sfc, sfc, ctx);
321 if (!ret)
322 {
323 ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
324 return 0;
325 }
326 }
327
328 return 1;
329}
330
331static void *
332evgl_eng_native_window_create(void *data)
333{
334 Render_Engine *re;
335 Evas_Engine_Info_Eglfs *info;
336
337 re = (Render_Engine *)data;
338 if (!re)
339 {
340 ERR("Invalid Render Engine Data!");
341 return NULL;
342 }
343
344 info = eng_get_ob(re)->info;
345 if (!info)
346 {
347 ERR("Invalid Evas Engine Eglfs Info!");
348 return NULL;
349 }
350
351 return NULL;
352}
353
354static int
355evgl_eng_native_window_destroy(void *data, void *native_window)
356{
357 Render_Engine *re = (Render_Engine *)data;
358
359 if (!re)
360 {
361 ERR("Invalid Render Engine Data!");
362 return 0;
363 }
364
365 if (!native_window)
366 {
367 ERR("Invalid native surface.");
368 return 0;
369 }
370
371 native_window = NULL;
372
373 return 1;
374}
375
376static void *
377evgl_eng_window_surface_create(void *data, void *native_window)
378{
379 Render_Engine *re;
380 EGLSurface surface = EGL_NO_SURFACE;
381
382 re = (Render_Engine *)data;
383 if (!re)
384 {
385 ERR("Invalid Render Engine Data!");
386 return NULL;
387 }
388
389 // Create resource surface for EGL
390 surface = eglCreateWindowSurface(eng_get_ob(re)->egl.disp,
391 eng_get_ob(re)->egl.config,
392 (EGLNativeWindowType)native_window,
393 NULL);
394 if (!surface)
395 {
396 ERR("Creating window surface failed. Error: %#x.", eglGetError());
397 return NULL;
398 }
399
400 return (void *)surface;
401}
402
403static int
404evgl_eng_window_surface_destroy(void *data, void *surface)
405{
406 Render_Engine *re;
407 EGLBoolean ret = EGL_FALSE;
408
409 re = (Render_Engine *)data;
410 if (!re)
411 {
412 ERR("Invalid Render Engine Data!");
413 return 0;
414 }
415
416 if (!surface)
417 {
418 ERR("Invalid surface.");
419 return 0;
420 }
421
422 ret = eglDestroySurface(eng_get_ob(re)->egl.disp, (EGLSurface)surface);
423 if (ret == EGL_TRUE) return 1;
424
425 return 0;
426}
427
428static void *
429evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version)
430{
431 Render_Engine *re;
432 EGLContext context = EGL_NO_CONTEXT;
433 int context_attrs[3];
434
435 re = (Render_Engine *)data;
436 if (!re)
437 {
438 ERR("Invalid Render Engine Data!");
439 return NULL;
440 }
441
442 if (version != EVAS_GL_GLES_2_X)
443 {
444 ERR("This engine only supports OpenGL-ES 2.0 contexts for now!");
445 return NULL;
446 }
447
448 context_attrs[0] = EGL_CONTEXT_CLIENT_VERSION;
449 context_attrs[1] = 2;
450 context_attrs[2] = EGL_NONE;
451
452 // Share context already assumes that it's sharing with evas' context
453 if (share_ctx)
454 {
455 context = eglCreateContext(eng_get_ob(re)->egl.disp,
456 eng_get_ob(re)->egl.config,
457 (EGLContext)share_ctx,
458 context_attrs);
459 }
460 else
461 {
462 context = eglCreateContext(eng_get_ob(re)->egl.disp,
463 eng_get_ob(re)->egl.config,
464 eng_get_ob(re)->egl.context[0], // Evas' GL Context
465 context_attrs);
466 }
467
468 if (!context)
469 {
470 ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
471 return NULL;
472 }
473
474 return (void *)context;
475}
476
477static int
478evgl_eng_context_destroy(void *data, void *context)
479{
480 Render_Engine *re;
481 EGLBoolean ret = EGL_FALSE;
482
483 re = (Render_Engine *)data;
484 if ((!re) || (!context))
485 {
486 ERR("Invalid Render Input Data. Engine: %p, Context: %p",
487 data, context);
488 return 0;
489 }
490
491 ret = eglDestroyContext(eng_get_ob(re)->egl.disp, (EGLContext)context);
492 if (ret == EGL_TRUE) return 1;
493
494 return 0;
495}
496
497static const char *
498evgl_eng_string_get(void *data)
499{
500 Render_Engine *re;
501
502 re = (Render_Engine *)data;
503 if (!re)
504 {
505 ERR("Invalid Render Engine Data!");
506 return NULL;
507 }
508
509 return eglQueryString(eng_get_ob(re)->egl.disp, EGL_EXTENSIONS);
510}
511
512static void *
513evgl_eng_proc_address_get(const char *name)
514{
515 if (glsym_eglGetProcAddress) return glsym_eglGetProcAddress(name);
516 return dlsym(RTLD_DEFAULT, name);
517}
518
519static int
520evgl_eng_rotation_angle_get(void *data)
521{
522 Render_Engine *re;
523
524 re = (Render_Engine *)data;
525 if (!re)
526 {
527 ERR("Invalid Render Engine Data!");
528 return 0;
529 }
530
531 if ((eng_get_ob(re)) && (eng_get_ob(re)->gl_context))
532 return eng_get_ob(re)->gl_context->rot;
533 else
534 {
535 ERR("Unable to retrieve rotation angle.");
536 return 0;
537 }
538}
539
540static Eina_Bool
541eng_preload_make_current(void *data, void *doit)
542{
543 Outbuf *ob;
544
545 ob = (Outbuf *)data;
546 if (!ob) return EINA_FALSE;
547
548 if (doit)
549 {
550 if (!eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
551 ob->egl.surface[0], ob->egl.context[0]))
552 return EINA_FALSE;
553 }
554 else
555 {
556 if (!eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE,
557 EGL_NO_SURFACE, EGL_NO_CONTEXT))
558 return EINA_FALSE;
559 }
560
561 return EINA_TRUE;
562}
563
564static void
565_re_winfree(Render_Engine *re)
566{
567 if (!re) return;
568 if (!eng_get_ob(re)->surf) return;
569 glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
570 evas_outbuf_unsurf(eng_get_ob(re));
571}
572
573static void
574_native_cb_bind(void *data EINA_UNUSED, void *image)
575{
576 Evas_GL_Image *img;
577 Native *n;
578
579 if (!(img = image)) return;
580 if (!(n = img->native.data)) return;
581
582 if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
583 {
584 if (n->egl_surface)
585 {
586 if (glsym_glEGLImageTargetTexture2DOES)
587 {
588 glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
589 if (eglGetError() != EGL_SUCCESS)
590 ERR("glEGLImageTargetTexture2DOES() failed.");
591 }
592 else
593 ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
594 }
595 }
596 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
597 glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
598
599 /* TODO: NATIVE_SURFACE_TBM and NATIVE_SURFACE_EVASGL */
600}
601
602static void
603_native_cb_unbind(void *data EINA_UNUSED, void *image)
604{
605 Evas_GL_Image *img;
606 Native *n;
607
608 if (!(img = image)) return;
609 if (!(n = img->native.data)) return;
610
611 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
612 glBindTexture(GL_TEXTURE_2D, 0);
613
614 /* TODO: NATIVE_SURFACE_TBM and NATIVE_SURFACE_EVASGL */
615}
616
617static void
618_native_cb_free(void *data, void *image)
619{
620 Render_Engine *re;
621 Outbuf *ob;
622 Evas_GL_Image *img;
623 Native *n;
624 uint32_t texid;
625 void *wlid;
626
627 if (!(re = (Render_Engine *)data)) return;
628 if (!(img = image)) return;
629 if (!(n = img->native.data)) return;
630 if (!(ob = eng_get_ob(re))) return;
631
632 if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
633 {
634 wlid = (void*)n->wl_buf;
635 eina_hash_del(ob->gl_context->shared->native_wl_hash, &wlid, img);
636 if (n->egl_surface)
637 {
638 if (glsym_eglDestroyImage)
639 {
640 glsym_eglDestroyImage(ob->egl.disp, n->egl_surface);
641 if (eglGetError() != EGL_SUCCESS)
642 ERR("eglDestroyImage() failed.");
643 }
644 else
645 ERR("Try eglDestroyImage on EGL with no support");
646 }
647 }
648 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
649 {
650 texid = n->ns.data.opengl.texture_id;
651 eina_hash_del(ob->gl_context->shared->native_tex_hash, &texid, img);
652 }
653
654 img->native.data = NULL;
655 img->native.func.data = NULL;
656 img->native.func.bind = NULL;
657 img->native.func.unbind = NULL;
658 img->native.func.free = NULL;
659
660 free(n);
661}
662
663/* engine specific override functions */
664static void *
665eng_info(Evas *eo_e EINA_UNUSED)
666{
667 Evas_Engine_Info_Eglfs *info;
668
669 /* try to allocate space for our engine info */
670 if (!(info = calloc(1, sizeof(Evas_Engine_Info_Eglfs))))
671 return NULL;
672
673 info->magic.magic = rand();
674 info->render_mode = EVAS_RENDER_MODE_BLOCKING;
675
676 return info;
677}
678
679static void
680eng_info_free(Evas *eo_e EINA_UNUSED, void *in)
681{
682 Evas_Engine_Info_Eglfs *info;
683
684 if ((info = (Evas_Engine_Info_Eglfs *)in))
685 free(info);
686}
687
688static int
689eng_setup(Evas *evas, void *in)
690{
691 Evas_Engine_Info_Eglfs *info;
692 Evas_Public_Data *epd;
693 Render_Engine *re;
694 Render_Engine_Swap_Mode swap_mode = MODE_FULL;
695 const char *s = NULL;
696
697 /* try to cast to our engine info structure */
698 if (!(info = (Evas_Engine_Info_Eglfs *)in)) return 0;
699
700 /* try to get the evas public data */
701 if (!(epd = eo_data_scope_get(evas, EVAS_CANVAS_CLASS))) return 0;
702
703 s = getenv("EVAS_GL_SWAP_MODE");
704 if (s)
705 {
706 if ((!strcasecmp(s, "full")) || (!strcasecmp(s, "f")))
707 swap_mode = MODE_FULL;
708 else if ((!strcasecmp(s, "copy")) || (!strcasecmp(s, "c")))
709 swap_mode = MODE_COPY;
710 else if ((!strcasecmp(s, "double")) ||
711 (!strcasecmp(s, "d")) || (!strcasecmp(s, "2")))
712 swap_mode = MODE_DOUBLE;
713 else if ((!strcasecmp(s, "triple")) ||
714 (!strcasecmp(s, "t")) || (!strcasecmp(s, "3")))
715 swap_mode = MODE_TRIPLE;
716 else if ((!strcasecmp(s, "quadruple")) ||
717 (!strcasecmp(s, "q")) || (!strcasecmp(s, "4")))
718 swap_mode = MODE_QUADRUPLE;
719 }
720 else
721 {
722// in most gl implementations - egl and glx here that we care about the TEND
723// to either swap or copy backbuffer and front buffer, but strictly that is
724// not true. technically backbuffer content is totally undefined after a swap
725// and thus you MUST re-render all of it, thus MODE_FULL
726 swap_mode = MODE_FULL;
727// BUT... reality is that lmost every implementation copies or swaps so
728// triple buffer mode can be used as it is a superset of double buffer and
729// copy (though using those explicitly is more efficient). so let's play with
730// triple buffer mdoe as a default and see.
731// re->mode = MODE_TRIPLE;
732// XXX: note - the above seems to break on some older intel chipsets and
733// drivers. it seems we CANT depend on backbuffer staying around. bugger!
734 switch (info->info.swap_mode)
735 {
736 case EVAS_ENGINE_EGLFS_SWAP_MODE_FULL:
737 swap_mode = MODE_FULL;
738 break;
739 case EVAS_ENGINE_EGLFS_SWAP_MODE_COPY:
740 swap_mode = MODE_COPY;
741 break;
742 case EVAS_ENGINE_EGLFS_SWAP_MODE_DOUBLE:
743 swap_mode = MODE_DOUBLE;
744 break;
745 case EVAS_ENGINE_EGLFS_SWAP_MODE_TRIPLE:
746 swap_mode = MODE_TRIPLE;
747 break;
748 case EVAS_ENGINE_EGLFS_SWAP_MODE_QUADRUPLE:
749 swap_mode = MODE_QUADRUPLE;
750 break;
751 default:
752 swap_mode = MODE_AUTO;
753 break;
754 }
755 }
756
757 if (!(re = epd->engine.data.output))
758 {
759 Outbuf *ob;
760 Render_Engine_Merge_Mode merge_mode = MERGE_BOUNDING;
761
762 if (!initted)
763 {
764 evas_common_init();
765 glsym_evas_gl_preload_init();
766 }
767
768 if (!(re = calloc(1, sizeof(Render_Engine)))) return 0;
769
770 /* try to create new outbuf */
771 ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode);
772 if (!ob)
773 {
774 free(re);
775 return 0;
776 }
777
778 ob->evas = evas;
779
780 if (!evas_render_engine_gl_generic_init(&re->generic, ob,
781 evas_outbuf_buffer_state_get,
782 evas_outbuf_rot_get,
783 evas_outbuf_reconfigure,
784 evas_outbuf_update_region_first_rect,
785 evas_outbuf_update_region_new,
786 evas_outbuf_update_region_push,
787 evas_outbuf_update_region_free,
788 NULL,
789 evas_outbuf_flush,
790 evas_outbuf_free,
791 evas_outbuf_use,
792 evas_outbuf_gl_context_get,
793 evas_outbuf_egl_display_get,
794 evas_outbuf_gl_context_new,
795 evas_outbuf_gl_context_use,
796 &evgl_funcs, ob->w, ob->h))
797 {
798 /* free outbuf */
799
800 evas_outbuf_free(ob);
801 free(re);
802 return 0;
803 }
804
805 epd->engine.data.output = re;
806 gl_wins++;
807
808 s = getenv("EVAS_GL_PARTIAL_MERGE");
809 if (s)
810 {
811 if ((!strcmp(s, "bounding")) || (!strcmp(s, "b")))
812 merge_mode = MERGE_BOUNDING;
813 else if ((!strcmp(s, "full")) || (!strcmp(s, "f")))
814 merge_mode = MERGE_FULL;
815 }
816
817 evas_render_engine_software_generic_merge_mode_set(&re->generic.software, merge_mode);
818
819 if (!initted)
820 {
821 gl_extn_veto(re);
822 initted = EINA_TRUE;
823 }
824 }
825 else
826 {
827 if (eng_get_ob(re) && _re_wincheck(eng_get_ob(re)))
828 {
829 if ((info->info.depth != eng_get_ob(re)->depth) ||
830 (info->info.destination_alpha != eng_get_ob(re)->destination_alpha))
831 {
832 Outbuf *ob, *ob_old;
833
834 ob_old = re->generic.software.ob;
835 re->generic.software.ob = NULL;
836 gl_wins--;
837
838 ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode);
839 if (!ob)
840 {
841 if (ob_old) evas_outbuf_free(ob_old);
842 free(re);
843 return 0;
844 }
845
846 evas_outbuf_use(ob);
847 if (ob_old) evas_outbuf_free(ob_old);
848
849 ob->evas = evas;
850
851 evas_render_engine_software_generic_update(&re->generic.software, ob,
852 epd->output.w, epd->output.h);
853
854 gl_wins++;
855 }
856 else if ((eng_get_ob(re)->w != epd->output.w) ||
857 (eng_get_ob(re)->h != epd->output.h) ||
858 (info->info.rotation != eng_get_ob(re)->rotation))
859 {
860 evas_outbuf_reconfigure(eng_get_ob(re),
861 epd->output.w, epd->output.h,
862 info->info.rotation,
863 info->info.depth);
864 }
865 }
866 }
867
868 if (!eng_get_ob(re))
869 {
870 free(re);
871 return 0;
872 }
873
874 if (!epd->engine.data.output)
875 {
876 if (eng_get_ob(re))
877 {
878 evas_outbuf_free(eng_get_ob(re));
879 gl_wins--;
880 }
881 free(re);
882 return 0;
883 }
884
885 if (re->generic.software.tb)
886 evas_common_tilebuf_free(re->generic.software.tb);
887 re->generic.software.tb =
888 evas_common_tilebuf_new(epd->output.w, epd->output.h);
889 if (re->generic.software.tb)
890 evas_common_tilebuf_set_tile_size(re->generic.software.tb,
891 TILESIZE, TILESIZE);
892
893 if (re->generic.software.tb)
894 evas_render_engine_software_generic_tile_strict_set(&re->generic.software, EINA_TRUE);
895
896 if (!epd->engine.data.context)
897 {
898 epd->engine.data.context =
899 epd->engine.func->context_new(epd->engine.data.output);
900 }
901
902 evas_outbuf_use(eng_get_ob(re));
903
904 return 1;
905}
906
907static void
908eng_output_free(void *data)
909{
910 Render_Engine *re;
911
912 re = (Render_Engine *)data;
913 if (re)
914 {
915 glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
916
917 if (gl_wins == 1) glsym_evgl_engine_shutdown(re);
918
919 /* NB: evas_render_engine_software_generic_clean() frees ob */
920 evas_render_engine_software_generic_clean(&re->generic.software);
921
922 gl_wins--;
923
924 free(re);
925 }
926
927 if ((initted == EINA_TRUE) && (gl_wins == 0))
928 {
929 glsym_evas_gl_preload_shutdown();
930 evas_common_shutdown();
931 initted = EINA_FALSE;
932 }
933}
934
935static Eina_Bool
936eng_canvas_alpha_get(void *data, void *info EINA_UNUSED)
937{
938 Render_Engine *re;
939
940 re = (Render_Engine *)data;
941 if (!re) return EINA_FALSE;
942
943 return eng_get_ob(re)->destination_alpha;
944}
945
946static void
947eng_output_dump(void *data)
948{
949 Render_Engine *re;
950
951 re = (Render_Engine *)data;
952 if (!re) return;
953
954 evas_common_image_image_all_unload();
955 evas_common_font_font_all_unload();
956 glsym_evas_gl_common_image_all_unload(eng_get_ob(re)->gl_context);
957 _re_winfree(re);
958}
959
960static void *
961eng_image_native_set(void *data, void *image, void *native)
962{
963 Render_Engine *re;
964 Outbuf *ob;
965 Native *n;
966 Evas_Native_Surface *ns;
967 Evas_GL_Image *img, *img2;
968 unsigned int tex = 0, fbo = 0;
969 uint32_t texid;
970 void *wlid, *wl_buf = NULL;
971
972 re = (Render_Engine *)data;
973 if (!re) return NULL;
974
975 ob = eng_get_ob(re);
976 if (!ob) return NULL;
977
978 ns = native;
979
980 if (!(img = image))
981 {
982 if ((ns) && (ns->type == EVAS_NATIVE_SURFACE_OPENGL))
983 {
984 img =
985 glsym_evas_gl_common_image_new_from_data(ob->gl_context,
986 ns->data.opengl.w,
987 ns->data.opengl.h,
988 NULL, 1,
989 EVAS_COLORSPACE_ARGB8888);
990 }
991 else
992 return NULL;
993 }
994
995 if (ns)
996 {
997 if (ns->type == EVAS_NATIVE_SURFACE_WL)
998 {
999 wl_buf = ns->data.wl.legacy_buffer;
1000 if (img->native.data)
1001 {
1002 Evas_Native_Surface *ens;
1003
1004 ens = img->native.data;
1005 if (ens->data.wl.legacy_buffer == wl_buf)
1006 return img;
1007 }
1008 }
1009 else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1010 {
1011 tex = ns->data.opengl.texture_id;
1012 fbo = ns->data.opengl.framebuffer_id;
1013 if (img->native.data)
1014 {
1015 Evas_Native_Surface *ens;
1016
1017 ens = img->native.data;
1018 if ((ens->data.opengl.texture_id == tex) &&
1019 (ens->data.opengl.framebuffer_id == fbo))
1020 return img;
1021 }
1022 }
1023 }
1024
1025 if ((!ns) && (!img->native.data)) return img;
1026
1027 evas_outbuf_use(ob);
1028
1029 if (img->native.data)
1030 {
1031 if (img->native.func.free)
1032 img->native.func.free(img->native.func.data, img);
1033 glsym_evas_gl_common_image_native_disable(img);
1034 }
1035
1036 if (!ns) return img;
1037
1038 if (ns->type == EVAS_NATIVE_SURFACE_WL)
1039 {
1040 wlid = wl_buf;
1041 img2 = eina_hash_find(ob->gl_context->shared->native_wl_hash, &wlid);
1042 if (img2 == img) return img;
1043 if (img2)
1044 {
1045 if((n = img2->native.data))
1046 {
1047 glsym_evas_gl_common_image_ref(img2);
1048 glsym_evas_gl_common_image_free(img);
1049 return img2;
1050 }
1051 }
1052 }
1053 else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1054 {
1055 texid = tex;
1056 img2 = eina_hash_find(ob->gl_context->shared->native_tex_hash, &texid);
1057 if (img2 == img) return img;
1058 if (img2)
1059 {
1060 if ((n = img2->native.data))
1061 {
1062 glsym_evas_gl_common_image_ref(img2);
1063 glsym_evas_gl_common_image_free(img);
1064 return img2;
1065 }
1066 }
1067 }
1068
1069 img2 = glsym_evas_gl_common_image_new_from_data(ob->gl_context, img->w,
1070 img->h, NULL, img->alpha,
1071 EVAS_COLORSPACE_ARGB8888);
1072 glsym_evas_gl_common_image_free(img);
1073
1074 if (!(img = img2)) return NULL;
1075
1076 if (ns->type == EVAS_NATIVE_SURFACE_WL)
1077 {
1078 if (native)
1079 {
1080 if ((n = calloc(1, sizeof(Native))))
1081 {
1082 EGLint attribs[3];
1083 int format, yinvert = 1;
1084
1085 glsym_eglQueryWaylandBufferWL(ob->egl.disp, wl_buf,
1086 EGL_TEXTURE_FORMAT, &format);
1087 if ((format != EGL_TEXTURE_RGB) &&
1088 (format != EGL_TEXTURE_RGBA))
1089 {
1090 ERR("eglQueryWaylandBufferWL() %d format is not supported ", format);
1091 glsym_evas_gl_common_image_free(img);
1092 free(n);
1093 return NULL;
1094 }
1095
1096 attribs[0] = EGL_WAYLAND_PLANE_WL;
1097 attribs[1] = 0; //if plane is 1 then 0, if plane is 2 then 1
1098 attribs[2] = EGL_NONE;
1099
1100 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1101 glsym_eglQueryWaylandBufferWL(ob->egl.disp, wl_buf,
1102 EGL_WAYLAND_Y_INVERTED_WL,
1103 &yinvert);
1104 eina_hash_add(ob->gl_context->shared->native_wl_hash,
1105 &wlid, img);
1106
1107 n->wl_buf = wl_buf;
1108 if (glsym_eglCreateImage)
1109 n->egl_surface = glsym_eglCreateImage(ob->egl.disp,
1110 NULL,
1111 EGL_WAYLAND_BUFFER_WL,
1112 wl_buf, attribs);
1113 else
1114 {
1115 ERR("Try eglCreateImage on EGL with no support");
1116 eina_hash_del(ob->gl_context->shared->native_wl_hash,
1117 &wlid, img);
1118 glsym_evas_gl_common_image_free(img);
1119 free(n);
1120 return NULL;
1121 }
1122
1123 if (!n->egl_surface)
1124 {
1125 ERR("eglCreatePixmapSurface() for %p failed", wl_buf);
1126 eina_hash_del(ob->gl_context->shared->native_wl_hash,
1127 &wlid, img);
1128 glsym_evas_gl_common_image_free(img);
1129 free(n);
1130 return NULL;
1131 }
1132
1133 //XXX: workaround for mesa-10.2.8
1134 // mesa's eglQueryWaylandBufferWL() with EGL_WAYLAND_Y_INVERTED_WL works incorrect.
1135 //img->native.yinvert = yinvert;
1136 img->native.yinvert = 1;
1137 img->native.loose = 0;
1138 img->native.data = n;
1139 img->native.func.data = re;
1140 img->native.func.bind = _native_cb_bind;
1141 img->native.func.unbind = _native_cb_unbind;
1142 img->native.func.free = _native_cb_free;
1143 img->native.target = GL_TEXTURE_2D;
1144 img->native.mipmap = 0;
1145
1146 glsym_evas_gl_common_image_native_enable(img);
1147 }
1148 }
1149 }
1150 else if (ns->type == EVAS_NATIVE_SURFACE_OPENGL)
1151 {
1152 if (native)
1153 {
1154 if ((n = calloc(1, sizeof(Native))))
1155 {
1156 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1157 eina_hash_add(ob->gl_context->shared->native_tex_hash,
1158 &texid, img);
1159
1160 n->egl_surface = 0;
1161
1162 img->native.yinvert = 0;
1163 img->native.loose = 0;
1164 img->native.data = n;
1165 img->native.func.data = re;
1166 img->native.func.bind = _native_cb_bind;
1167 img->native.func.unbind = _native_cb_unbind;
1168 img->native.func.free = _native_cb_free;
1169 img->native.target = GL_TEXTURE_2D;
1170 img->native.mipmap = 0;
1171
1172 glsym_evas_gl_common_image_native_enable(img);
1173 }
1174 }
1175 }
1176
1177 /* TODO: NATIVE_SURFACE_TBM and NATIVE_SURFACE_EVASGL */
1178
1179 return img;
1180}
1181
1182/* module api functions */
1183static int
1184module_open(Evas_Module *em)
1185{
1186 /* check for valid evas module */
1187 if (!em) return 0;
1188
1189 /* get whatever engine module we inherit from */
1190 if (!_evas_module_engine_inherit(&pfunc, "gl_generic")) return 0;
1191
1192 /* try to create eina logging domain */
1193 if (_evas_engine_eglfs_log_dom < 0)
1194 {
1195 _evas_engine_eglfs_log_dom =
1196 eina_log_domain_register("evas-eglfs", EVAS_DEFAULT_LOG_COLOR);
1197 }
1198
1199 /* if we could not create a logging domain, error out */
1200 if (_evas_engine_eglfs_log_dom < 0)
1201 {
1202 EINA_LOG_ERR("Can not create a module log domain.");
1203 return 0;
1204 }
1205
1206 /* store it for later use */
1207 func = pfunc;
1208
1209 /* now to override methods */
1210 EVAS_API_OVERRIDE(info, &func, eng_);
1211 EVAS_API_OVERRIDE(info_free, &func, eng_);
1212 EVAS_API_OVERRIDE(setup, &func, eng_);
1213 EVAS_API_OVERRIDE(canvas_alpha_get, &func, eng_);
1214 EVAS_API_OVERRIDE(output_free, &func, eng_);
1215 EVAS_API_OVERRIDE(output_dump, &func, eng_);
1216 EVAS_API_OVERRIDE(image_native_set, &func, eng_);
1217
1218 setenv("EGL_PLATFORM", "fbdev", 1);
1219
1220 gl_symbols();
1221
1222 /* now advertise out own api */
1223 em->functions = (void *)(&func);
1224
1225 return 1;
1226}
1227
1228static void
1229module_close(Evas_Module *em EINA_UNUSED)
1230{
1231 /* unregister the eina log domain for this engine */
1232 eina_log_domain_unregister(_evas_engine_eglfs_log_dom);
1233 _evas_engine_eglfs_log_dom = -1;
1234}
1235
1236static Evas_Module_Api evas_modapi =
1237{
1238 EVAS_MODULE_API_VERSION, "eglfs", "none", { module_open, module_close }
1239};
1240
1241EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_ENGINE, engine, eglfs);
1242
1243#ifndef EVAS_STATIC_BUILD_EGLFS
1244EVAS_EINA_MODULE_DEFINE(engine, eglfs);
1245#endif
diff --git a/src/modules/evas/engines/eglfs/evas_engine.h b/src/modules/evas/engines/eglfs/evas_engine.h
deleted file mode 100644
index 461f330ecd..0000000000
--- a/src/modules/evas/engines/eglfs/evas_engine.h
+++ /dev/null
@@ -1,129 +0,0 @@
1#ifndef EVAS_ENGINE_H
2# define EVAS_ENGINE_H
3
4# include "evas_common_private.h"
5# include "evas_macros.h"
6# include "evas_private.h"
7# include "Evas.h"
8# include "Evas_Engine_Eglfs.h"
9
10# define EGL_EGLEXT_PROTOTYPES
11# define GL_GLEXT_PROTOTYPES
12
13# include <EGL/egl.h>
14# include <EGL/eglext.h>
15# include <EGL/eglmesaext.h>
16# include <GLES2/gl2.h>
17# include <GLES2/gl2ext.h>
18# include "../gl_generic/Evas_Engine_GL_Generic.h"
19
20extern int _evas_engine_eglfs_log_dom;
21extern int _extn_have_buffer_age;
22
23# ifdef ERR
24# undef ERR
25# endif
26# define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_eglfs_log_dom, __VA_ARGS__)
27
28# ifdef DBG
29# undef DBG
30# endif
31# define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_eglfs_log_dom, __VA_ARGS__)
32
33# ifdef INF
34# undef INF
35# endif
36# define INF(...) EINA_LOG_DOM_INFO(_evas_engine_eglfs_log_dom, __VA_ARGS__)
37
38# ifdef WRN
39# undef WRN
40# endif
41# define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_eglfs_log_dom, __VA_ARGS__)
42
43# ifdef CRI
44# undef CRI
45# endif
46# define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_eglfs_log_dom, __VA_ARGS__)
47
48extern Evas_GL_Common_Context_New glsym_evas_gl_common_context_new;
49extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush;
50extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free;
51extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use;
52extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe;
53extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done;
54extern Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize;
55extern Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump;
56extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock;
57extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock;
58
59struct _Context_3D
60{
61 EGLDisplay display;
62 EGLContext context;
63 EGLSurface surface;
64};
65
66struct _Outbuf
67{
68 Evas_Engine_Info_Eglfs *info;
69 Evas_Engine_GL_Context *gl_context;
70
71 Evas *evas; // used for pre_swap, post_swap
72
73 int w, h;
74 unsigned int rotation, depth;
75 Render_Engine_Swap_Mode swap_mode;
76
77 struct
78 {
79 EGLContext context[1];
80 EGLSurface surface[1];
81 EGLConfig config;
82 EGLDisplay disp;
83 } egl;
84
85 struct
86 {
87 int prev_age, frame_cnt;
88 int curr, last, num;
89 Eina_List *pending_writes;
90 } priv;
91
92 Eina_Bool destination_alpha : 1;
93 Eina_Bool vsync : 1;
94 Eina_Bool lost_back : 1;
95 Eina_Bool surf : 1;
96 Eina_Bool drew : 1;
97};
98
99Outbuf *evas_outbuf_new(Evas_Engine_Info_Eglfs *info, int w, int h, Render_Engine_Swap_Mode swap_mode);
100void evas_outbuf_free(Outbuf *ob);
101void evas_outbuf_use(Outbuf *ob);
102void evas_outbuf_resurf(Outbuf *ob);
103void evas_outbuf_unsurf(Outbuf *ob);
104void evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
105Render_Engine_Swap_Mode evas_outbuf_buffer_state_get(Outbuf *ob);
106int evas_outbuf_rot_get(Outbuf *ob);
107Eina_Bool evas_outbuf_update_region_first_rect(Outbuf *ob);
108void *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
109void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
110void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update);
111void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode);
112Evas_Engine_GL_Context* evas_outbuf_gl_context_get(Outbuf *ob);
113void *evas_outbuf_egl_display_get(Outbuf *ob);
114Context_3D *evas_outbuf_gl_context_new(Outbuf *ob);
115void evas_outbuf_gl_context_use(Context_3D *ctx);
116
117static inline Eina_Bool
118_re_wincheck(Outbuf *ob)
119{
120 if (ob->surf) return EINA_TRUE;
121 evas_outbuf_resurf(ob);
122 ob->lost_back = 1;
123 if (!ob->surf) ERR("GL engine can't re-create window surface!");
124 return EINA_FALSE;
125}
126
127extern unsigned int (*glsym_eglSwapBuffersWithDamage)(EGLDisplay a, void *b, const EGLint *d, EGLint c);
128
129#endif
diff --git a/src/modules/evas/engines/eglfs/evas_outbuf.c b/src/modules/evas/engines/eglfs/evas_outbuf.c
deleted file mode 100644
index d2ee1e5617..0000000000
--- a/src/modules/evas/engines/eglfs/evas_outbuf.c
+++ /dev/null
@@ -1,509 +0,0 @@
1#include "evas_engine.h"
2
3/* local variables */
4static Outbuf *_evas_eglfs_window = NULL;
5static EGLContext context = EGL_NO_CONTEXT;
6static int win_count = 0;
7
8static Eina_Bool
9_evas_outbuf_make_current(void *data, void *doit)
10{
11 Outbuf *ob;
12
13 if (!(ob = data)) return EINA_FALSE;
14
15 if (doit)
16 {
17 if (!eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
18 ob->egl.surface[0], ob->egl.context[0]))
19 return EINA_FALSE;
20 }
21 else
22 {
23 if (!eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE,
24 EGL_NO_SURFACE, EGL_NO_CONTEXT))
25 return EINA_FALSE;
26 }
27
28 return EINA_TRUE;
29}
30
31static Eina_Bool
32_evas_outbuf_egl_setup(Outbuf *ob)
33{
34 int ctx_attr[3];
35 int cfg_attr[40];
36 int maj = 0, min = 0, n = 0, i = 0;
37 EGLint ncfg;
38 EGLConfig *cfgs;
39 const GLubyte *vendor, *renderer, *version, *glslversion;
40 Eina_Bool blacklist = EINA_FALSE;
41
42 /* setup egl surface */
43 ctx_attr[0] = EGL_CONTEXT_CLIENT_VERSION;
44 ctx_attr[1] = 2;
45 ctx_attr[2] = EGL_NONE;
46
47 cfg_attr[n++] = EGL_BUFFER_SIZE;
48 cfg_attr[n++] = 32;
49 cfg_attr[n++] = EGL_DEPTH_SIZE;
50 cfg_attr[n++] = EGL_DONT_CARE;
51 cfg_attr[n++] = EGL_STENCIL_SIZE;
52 cfg_attr[n++] = EGL_DONT_CARE;
53 cfg_attr[n++] = EGL_RENDERABLE_TYPE;
54 cfg_attr[n++] = EGL_OPENGL_ES2_BIT;
55 cfg_attr[n++] = EGL_SURFACE_TYPE;
56 cfg_attr[n++] = EGL_WINDOW_BIT;
57
58 cfg_attr[n++] = EGL_ALPHA_SIZE;
59 if (ob->destination_alpha) cfg_attr[n++] = 1;
60 else cfg_attr[n++] = 0;
61 cfg_attr[n++] = EGL_NONE;
62
63 ob->egl.disp = eglGetDisplay(NULL);
64 if (ob->egl.disp == EGL_NO_DISPLAY)
65 {
66 ERR("eglGetDisplay() fail. code=%#x", eglGetError());
67 return EINA_FALSE;
68 }
69
70 if (!eglInitialize(ob->egl.disp, &maj, &min))
71 {
72 ERR("eglInitialize() fail. code=%#x", eglGetError());
73 return EINA_FALSE;
74 }
75
76 eglBindAPI(EGL_OPENGL_ES_API);
77 if (eglGetError() != EGL_SUCCESS)
78 {
79 ERR("eglBindAPI() fail. code=%#x", eglGetError());
80 return EINA_FALSE;
81 }
82
83 if (!eglGetConfigs(ob->egl.disp, NULL, 0, &ncfg) || (ncfg == 0))
84 {
85 ERR("eglGetConfigs() fail. code=%#x", eglGetError());
86 return EINA_FALSE;
87 }
88
89 cfgs = malloc(ncfg * sizeof(EGLConfig));
90 if (!cfgs)
91 {
92 ERR("Failed to malloc space for egl configs");
93 return EINA_FALSE;
94 }
95
96 if (!eglChooseConfig(ob->egl.disp, cfg_attr, cfgs,
97 ncfg, &ncfg) || (ncfg == 0))
98 {
99 ERR("eglChooseConfig() fail. code=%#x", eglGetError());
100 return EINA_FALSE;
101 }
102
103 // First is always best...
104 ob->egl.config = cfgs[0];
105
106 ob->egl.surface[0] =
107 eglCreateWindowSurface(ob->egl.disp, ob->egl.config,
108 (EGLNativeWindowType)NULL, NULL);
109 if (ob->egl.surface[0] == EGL_NO_SURFACE)
110 {
111 ERR("eglCreateWindowSurface() fail for %p. code=%#x",
112 NULL, eglGetError());
113 return EINA_FALSE;
114 }
115
116 ob->egl.context[0] =
117 eglCreateContext(ob->egl.disp, ob->egl.config, EGL_NO_CONTEXT, ctx_attr);
118 if (ob->egl.context[0] == EGL_NO_CONTEXT)
119 {
120 ERR("eglCreateContext() fail. code=%#x", eglGetError());
121 return EINA_FALSE;
122 }
123
124 if (context == EGL_NO_CONTEXT) context = ob->egl.context[0];
125
126 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
127 ob->egl.surface[0], ob->egl.context[0]) == EGL_FALSE)
128 {
129 ERR("eglMakeCurrent() fail. code=%#x", eglGetError());
130 return EINA_FALSE;
131 }
132
133 vendor = glGetString(GL_VENDOR);
134 renderer = glGetString(GL_RENDERER);
135 version = glGetString(GL_VERSION);
136 glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
137 if (!vendor) vendor = (unsigned char *)"-UNKNOWN-";
138 if (!renderer) renderer = (unsigned char *)"-UNKNOWN-";
139 if (!version) version = (unsigned char *)"-UNKNOWN-";
140 if (!glslversion) glslversion = (unsigned char *)"-UNKNOWN-";
141 if (getenv("EVAS_GL_INFO"))
142 {
143 fprintf(stderr, "vendor : %s\n", vendor);
144 fprintf(stderr, "renderer: %s\n", renderer);
145 fprintf(stderr, "version : %s\n", version);
146 fprintf(stderr, "glsl ver: %s\n", glslversion);
147 }
148
149 if (strstr((const char *)vendor, "Mesa Project"))
150 {
151 if (strstr((const char *)renderer, "Software Rasterizer"))
152 blacklist = EINA_TRUE;
153 }
154 if (strstr((const char *)renderer, "softpipe"))
155 blacklist = EINA_TRUE;
156 if (strstr((const char *)renderer, "llvmpipe"))
157 blacklist = EINA_TRUE;
158
159 if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST")))
160 {
161 ERR("OpenGL Driver blacklisted:");
162 ERR("Vendor: %s", (const char *)vendor);
163 ERR("Renderer: %s", (const char *)renderer);
164 ERR("Version: %s", (const char *)version);
165 return EINA_FALSE;
166 }
167
168 ob->gl_context = glsym_evas_gl_common_context_new();
169 if (!ob->gl_context) return EINA_FALSE;
170
171#ifdef GL_GLES
172 ob->gl_context->egldisp = ob->egl.disp;
173 ob->gl_context->eglctxt = ob->egl.context[0];
174#endif
175
176 evas_outbuf_use(ob);
177 glsym_evas_gl_common_context_resize(ob->gl_context,
178 ob->w, ob->h, ob->rotation);
179
180 ob->surf = EINA_TRUE;
181
182 return EINA_TRUE;
183}
184
185Outbuf *
186evas_outbuf_new(Evas_Engine_Info_Eglfs *info, int w, int h, Render_Engine_Swap_Mode swap_mode)
187{
188 Outbuf *ob;
189 char *num;
190
191 if (!info) return NULL;
192
193 /* try to allocate space for outbuf */
194 if (!(ob = calloc(1, sizeof(Outbuf)))) return NULL;
195
196 win_count++;
197
198 ob->w = w;
199 ob->h = h;
200 ob->info = info;
201 ob->depth = info->info.depth;
202 ob->rotation = info->info.rotation;
203 ob->destination_alpha = info->info.destination_alpha;
204 ob->swap_mode = swap_mode;
205 ob->priv.num = 2;
206
207 if ((num = getenv("EVAS_EGLFS_BUFFERS")))
208 {
209 ob->priv.num = atoi(num);
210 if (ob->priv.num <= 0) ob->priv.num = 1;
211 else if (ob->priv.num > 4) ob->priv.num = 4;
212 }
213
214 if ((num = getenv("EVAS_EGLFS_VSYNC")))
215 ob->vsync = atoi(num);
216
217 if (!_evas_outbuf_egl_setup(ob))
218 {
219 evas_outbuf_free(ob);
220 return NULL;
221 }
222
223 return ob;
224}
225
226void
227evas_outbuf_free(Outbuf *ob)
228{
229 int ref = 0;
230
231 win_count--;
232 evas_outbuf_use(ob);
233
234 if (ob == _evas_eglfs_window) _evas_eglfs_window = NULL;
235
236 if (ob->gl_context)
237 {
238 ref = ob->gl_context->references - 1;
239 glsym_evas_gl_common_context_free(ob->gl_context);
240 }
241
242 eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
243
244 if (ob->egl.context[0] != context)
245 eglDestroyContext(ob->egl.disp, ob->egl.context[0]);
246
247 if (ob->egl.surface[0] != EGL_NO_SURFACE)
248 eglDestroySurface(ob->egl.disp, ob->egl.surface[0]);
249
250 if (ref == 0)
251 {
252 if (context) eglDestroyContext(ob->egl.disp, context);
253 eglTerminate(ob->egl.disp);
254 eglReleaseThread();
255 context = EGL_NO_CONTEXT;
256 }
257
258 free(ob);
259}
260
261void
262evas_outbuf_use(Outbuf *ob)
263{
264 Eina_Bool force = EINA_FALSE;
265
266 glsym_evas_gl_preload_render_lock(_evas_outbuf_make_current, ob);
267
268 if (_evas_eglfs_window)
269 {
270 if (eglGetCurrentContext() != _evas_eglfs_window->egl.context[0])
271 force = EINA_TRUE;
272 }
273
274 if ((_evas_eglfs_window != ob) || (force))
275 {
276 if (_evas_eglfs_window)
277 {
278 glsym_evas_gl_common_context_use(_evas_eglfs_window->gl_context);
279 glsym_evas_gl_common_context_flush(_evas_eglfs_window->gl_context);
280 }
281
282 _evas_eglfs_window = ob;
283
284 if (ob)
285 {
286 if (ob->egl.surface[0] != EGL_NO_SURFACE)
287 {
288 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
289 ob->egl.surface[0],
290 ob->egl.context[0]) == EGL_FALSE)
291 ERR("eglMakeCurrent() failed!");
292 }
293 }
294 }
295
296 if (ob) glsym_evas_gl_common_context_use(ob->gl_context);
297}
298
299void
300evas_outbuf_resurf(Outbuf *ob)
301{
302 if (ob->surf) return;
303 if (getenv("EVAS_GL_INFO")) printf("resurf %p\n", ob);
304
305 ob->egl.surface[0] =
306 eglCreateWindowSurface(ob->egl.disp, ob->egl.config,
307 (EGLNativeWindowType)NULL, NULL);
308
309 if (ob->egl.surface[0] == EGL_NO_SURFACE)
310 {
311 ERR("eglCreateWindowSurface() fail for %p. code=%#x",
312 NULL, eglGetError());
313 return;
314 }
315
316 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0], ob->egl.surface[0],
317 ob->egl.context[0]) == EGL_FALSE)
318 ERR("eglMakeCurrent() failed!");
319
320 ob->surf = EINA_TRUE;
321}
322
323void
324evas_outbuf_unsurf(Outbuf *ob)
325{
326 if (!ob->surf) return;
327 if (!getenv("EVAS_GL_WIN_RESURF")) return;
328 if (getenv("EVAS_GL_INFO")) printf("unsurf %p\n", ob);
329
330 if (_evas_eglfs_window)
331 glsym_evas_gl_common_context_flush(_evas_eglfs_window->gl_context);
332 if (_evas_eglfs_window == ob)
333 {
334 eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE,
335 EGL_NO_SURFACE, EGL_NO_CONTEXT);
336 if (ob->egl.surface[0] != EGL_NO_SURFACE)
337 eglDestroySurface(ob->egl.disp, ob->egl.surface[0]);
338 ob->egl.surface[0] = EGL_NO_SURFACE;
339
340 _evas_eglfs_window = NULL;
341 }
342
343 ob->surf = EINA_FALSE;
344}
345
346void
347evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth)
348{
349 if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth;
350
351 ob->w = w;
352 ob->h = h;
353 ob->depth = depth;
354 ob->rotation = rot;
355
356 evas_outbuf_use(ob);
357 glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot);
358}
359
360Render_Engine_Swap_Mode
361evas_outbuf_buffer_state_get(Outbuf *ob)
362{
363 return MODE_FULL;
364 // Forces re-rendering all the screen, that is bad for performance. However
365 // partial rendering makes black area. We should try to find a better solution.
366}
367
368int
369evas_outbuf_rot_get(Outbuf *ob)
370{
371 return ob->rotation;
372}
373
374Eina_Bool
375evas_outbuf_update_region_first_rect(Outbuf *ob)
376{
377 glsym_evas_gl_preload_render_lock(_evas_outbuf_make_current, ob);
378 evas_outbuf_use(ob);
379
380 if (!_re_wincheck(ob)) return EINA_TRUE;
381
382 glsym_evas_gl_common_context_flush(ob->gl_context);
383 glsym_evas_gl_common_context_newframe(ob->gl_context);
384
385 return EINA_FALSE;
386}
387
388void *
389evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx EINA_UNUSED, int *cy EINA_UNUSED, int *cw EINA_UNUSED, int *ch EINA_UNUSED)
390{
391 if ((w == ob->w) && (h == ob->h))
392 ob->gl_context->master_clip.enabled = EINA_FALSE;
393 else
394 {
395 ob->gl_context->master_clip.enabled = EINA_TRUE;
396 ob->gl_context->master_clip.x = x;
397 ob->gl_context->master_clip.y = y;
398 ob->gl_context->master_clip.w = w;
399 ob->gl_context->master_clip.h = h;
400 }
401
402 return ob->gl_context->def_surface;
403}
404
405void
406evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update EINA_UNUSED, int x EINA_UNUSED, int y EINA_UNUSED, int w EINA_UNUSED, int h EINA_UNUSED)
407{
408 /* Is it really necessary to flush per region ? Shouldn't we be able to
409 still do that for the full canvas when doing partial update */
410 if (!_re_wincheck(ob)) return;
411 ob->drew = EINA_TRUE;
412 glsym_evas_gl_common_context_flush(ob->gl_context);
413}
414
415void
416evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
417{
418 /* Nothing to do here as we don't really create an image per area */
419}
420
421void
422evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode)
423{
424 if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end;
425
426 if (!_re_wincheck(ob)) goto end;
427 if (!ob->drew) goto end;
428
429 ob->drew = EINA_FALSE;
430 evas_outbuf_use(ob);
431 glsym_evas_gl_common_context_done(ob->gl_context);
432
433 if (!ob->vsync)
434 {
435 if (ob->info->info.vsync) eglSwapInterval(ob->egl.disp, 1);
436 else eglSwapInterval(ob->egl.disp, 0);
437 ob->vsync = 1;
438 }
439
440 if (ob->info->callback.pre_swap)
441 ob->info->callback.pre_swap(ob->info->callback.data, ob->evas);
442
443 eglSwapBuffers(ob->egl.disp, ob->egl.surface[0]);
444
445 if (ob->info->callback.post_swap)
446 ob->info->callback.post_swap(ob->info->callback.data, ob->evas);
447
448 ob->priv.frame_cnt++;
449
450end:
451 glsym_evas_gl_preload_render_unlock(_evas_outbuf_make_current, ob);
452}
453
454Evas_Engine_GL_Context *
455evas_outbuf_gl_context_get(Outbuf *ob)
456{
457 return ob->gl_context;
458}
459
460void *
461evas_outbuf_egl_display_get(Outbuf *ob)
462{
463 return ob->egl.disp;
464}
465
466Context_3D *
467evas_outbuf_gl_context_new(Outbuf *ob)
468{
469 Context_3D *ctx;
470 int context_attrs[3] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
471
472 if (!ob) return NULL;
473
474 ctx = calloc(1, sizeof(Context_3D));
475 if (!ctx) return NULL;
476
477 ctx->context = eglCreateContext(ob->egl.disp, ob->egl.config,
478 ob->egl.context[0], context_attrs);
479
480 if (!ctx->context)
481 {
482 ERR("EGL context creation failed.");
483 goto error;
484 }
485
486 ctx->display = ob->egl.disp;
487 ctx->surface = ob->egl.surface[0];
488
489 return ctx;
490
491error:
492 free(ctx);
493 return NULL;
494}
495
496void
497evas_outbuf_gl_context_free(Context_3D *ctx)
498{
499 eglDestroyContext(ctx->display, ctx->context);
500 free(ctx);
501}
502
503void
504evas_outbuf_gl_context_use(Context_3D *ctx)
505{
506 if (eglMakeCurrent(ctx->display, ctx->surface,
507 ctx->surface, ctx->context) == EGL_FALSE)
508 ERR("eglMakeCurrent() failed.");
509}