summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChris Michael <cp.michael@samsung.com>2015-06-03 12:56:35 -0400
committerChris Michael <cp.michael@samsung.com>2015-06-05 10:00:44 -0400
commitee593050f1674f29a99156f135c92f43cb5897e2 (patch)
tree2b9640cee9900f7700f789887f28df679cb00f32 /src
parent58dbb63ba4bbc235477793b016ba31d2bf17d1fb (diff)
evas-gl-drm: Rework gl_drm engine to function again
Summary: Previous gl_drm evas engine code did not work properly (or at all really). This reworks/refactors the gl_drm engine code to work again with the changes made to ecore_drm. @fix Signed-off-by: Chris Michael <cp.michael@samsung.com>
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Evas.am3
-rw-r--r--src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h36
-rw-r--r--src/modules/evas/engines/gl_drm/evas_engine.c668
-rw-r--r--src/modules/evas/engines/gl_drm/evas_engine.h128
-rw-r--r--src/modules/evas/engines/gl_drm/evas_outbuf.c656
5 files changed, 1171 insertions, 320 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index e5b771d8da..de4626ba62 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -1199,8 +1199,7 @@ endif
1199if BUILD_ENGINE_GL_DRM 1199if BUILD_ENGINE_GL_DRM
1200dist_installed_evasmainheaders_DATA += modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h 1200dist_installed_evasmainheaders_DATA += modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h
1201GL_DRM_SOURCES = \ 1201GL_DRM_SOURCES = \
1202modules/evas/engines/gl_drm/evas_drm.c \ 1202modules/evas/engines/gl_drm/evas_outbuf.c \
1203modules/evas/engines/gl_drm/evas_drm_main.c \
1204modules/evas/engines/gl_drm/evas_engine.c \ 1203modules/evas/engines/gl_drm/evas_engine.c \
1205modules/evas/engines/gl_drm/evas_engine.h \ 1204modules/evas/engines/gl_drm/evas_engine.h \
1206modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h 1205modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h
diff --git a/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h b/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h
new file mode 100644
index 0000000000..6cb7923d70
--- /dev/null
+++ b/src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h
@@ -0,0 +1,36 @@
1#ifndef _EVAS_ENGINE_GL_DRM_H
2# define _EVAS_ENGINE_GL_DRM_H
3
4# include <Ecore_Drm.h>
5# include <gbm.h>
6
7typedef struct _Evas_Engine_Info_GL_Drm Evas_Engine_Info_GL_Drm;
8
9struct _Evas_Engine_Info_GL_Drm
10{
11 /* PRIVATE - don't mess with this baby or evas will poke its tongue out */
12 /* at you and make nasty noises */
13 Evas_Engine_Info magic;
14
15 struct
16 {
17 struct gbm_device *gbm;
18 struct gbm_surface *surface;
19
20 unsigned int rotation, depth;
21 unsigned int crtc_id, conn_id, buffer_id;
22 unsigned int format, flags;
23
24 Ecore_Drm_Device *dev;
25
26 Eina_Bool destination_alpha : 1;
27 Eina_Bool vsync : 1;
28 Eina_Bool indirect : 1;
29 unsigned char swap_mode : 4;
30 } info;
31
32 /* non-blocking or blocking mode */
33 Evas_Engine_Render_Mode render_mode;
34};
35
36#endif
diff --git a/src/modules/evas/engines/gl_drm/evas_engine.c b/src/modules/evas/engines/gl_drm/evas_engine.c
index 0049819de2..280035da98 100644
--- a/src/modules/evas/engines/gl_drm/evas_engine.c
+++ b/src/modules/evas/engines/gl_drm/evas_engine.c
@@ -1,5 +1,6 @@
1#include "evas_common_private.h" /* Also includes international specific stuff */ 1#include "config.h"
2#include "evas_engine.h" 2#include "evas_engine.h"
3#include <wayland-client.h>
3 4
4#ifdef HAVE_DLSYM 5#ifdef HAVE_DLSYM
5# include <dlfcn.h> /* dlopen,dlclose,etc */ 6# include <dlfcn.h> /* dlopen,dlclose,etc */
@@ -7,10 +8,6 @@
7# error gl_drm should not get compiled if dlsym is not found on the system! 8# error gl_drm should not get compiled if dlsym is not found on the system!
8#endif 9#endif
9 10
10#ifdef EVAS_CSERVE2
11# include "evas_cs2_private.h"
12#endif
13
14#define EVAS_GL_NO_GL_H_CHECK 1 11#define EVAS_GL_NO_GL_H_CHECK 1
15#include "Evas_GL.h" 12#include "Evas_GL.h"
16 13
@@ -20,10 +17,28 @@
20# define EGL_NATIVE_PIXMAP_KHR 0x30b0 17# define EGL_NATIVE_PIXMAP_KHR 0x30b0
21#endif 18#endif
22 19
23#include <wayland-client.h>
24/* external variables */ 20/* external variables */
25int _evas_engine_gl_drm_log_dom = -1; 21int _evas_engine_gl_drm_log_dom = -1;
26int extn_have_buffer_age = 1; 22int _extn_have_buffer_age = 1;
23
24/* local variables */
25static Eina_Bool initted = EINA_FALSE;
26static int gl_wins = 0;
27
28/* local structures */
29typedef struct _Render_Engine Render_Engine;
30struct _Render_Engine
31{
32 Render_Engine_GL_Generic generic;
33};
34
35typedef struct _Native Native;
36struct _Native
37{
38 Evas_Native_Surface ns;
39 struct wl_buffer *wl_buf;
40 void *egl_surface;
41};
27 42
28/* external dynamic loaded Evas_GL function pointers */ 43/* external dynamic loaded Evas_GL function pointers */
29Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL; 44Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL;
@@ -50,29 +65,14 @@ Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock = NULL;
50Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL; 65Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL;
51Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL; 66Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL;
52 67
53/* local structures */
54typedef struct _Render_Engine Render_Engine;
55struct _Render_Engine
56{
57 Render_Engine_GL_Generic generic;
58};
59
60typedef struct _Native Native;
61struct _Native
62{
63 Evas_Native_Surface ns;
64 struct wl_buffer *wl_buf;
65 void *egl_surface;
66};
67
68/* local function prototype types */ 68/* local function prototype types */
69typedef void (*_eng_fn) (void); 69typedef void (*_eng_fn)(void);
70typedef _eng_fn (*glsym_func_eng_fn) (); 70typedef _eng_fn (*glsym_func_eng_fn)();
71typedef void (*glsym_func_void) (); 71typedef void (*glsym_func_void)();
72typedef void *(*glsym_func_void_ptr) (); 72typedef void *(*glsym_func_void_ptr)();
73typedef int (*glsym_func_int) (); 73typedef int (*glsym_func_int)();
74typedef unsigned int (*glsym_func_uint) (); 74typedef unsigned int (*glsym_func_uint)();
75typedef const char *(*glsym_func_const_char_ptr) (); 75typedef const char *(*glsym_func_const_char_ptr)();
76 76
77/* dynamic loaded local egl function pointers */ 77/* dynamic loaded local egl function pointers */
78_eng_fn (*glsym_eglGetProcAddress)(const char *a) = NULL; 78_eng_fn (*glsym_eglGetProcAddress)(const char *a) = NULL;
@@ -99,19 +99,6 @@ static const char *evgl_eng_string_get(void *data);
99static void *evgl_eng_proc_address_get(const char *name); 99static void *evgl_eng_proc_address_get(const char *name);
100static int evgl_eng_rotation_angle_get(void *data); 100static int evgl_eng_rotation_angle_get(void *data);
101 101
102static void _re_winfree(Render_Engine *re);
103
104/* local variables */
105static Eina_Bool initted = EINA_FALSE;
106static int gl_wins = 0;
107
108/* local inline functions */
109static inline Outbuf *
110eng_get_ob(Render_Engine *re)
111{
112 return re->generic.software.ob;
113}
114
115/* function tables - filled in later (func and parent func) */ 102/* function tables - filled in later (func and parent func) */
116static Evas_Func func, pfunc; 103static Evas_Func func, pfunc;
117static const EVGL_Interface evgl_funcs = 104static const EVGL_Interface evgl_funcs =
@@ -136,6 +123,13 @@ static const EVGL_Interface evgl_funcs =
136 NULL, // native_win_surface_config_get 123 NULL, // native_win_surface_config_get
137}; 124};
138 125
126/* local inline functions */
127static inline Outbuf *
128eng_get_ob(Render_Engine *re)
129{
130 return re->generic.software.ob;
131}
132
139/* local functions */ 133/* local functions */
140static void 134static void
141gl_symbols(void) 135gl_symbols(void)
@@ -215,36 +209,38 @@ static void
215gl_extn_veto(Render_Engine *re) 209gl_extn_veto(Render_Engine *re)
216{ 210{
217 const char *str = NULL; 211 const char *str = NULL;
218 str = eglQueryString(eng_get_ob(re)->egl_disp, EGL_EXTENSIONS); 212
213 str = eglQueryString(eng_get_ob(re)->egl.disp, EGL_EXTENSIONS);
219 if (str) 214 if (str)
220 { 215 {
221 const char *s; 216 const char *s = NULL;
222 if (getenv("EVAS_GL_INFO")) 217
223 printf("EGL EXTN:\n%s\n", str); 218 if (getenv("EVAS_GL_INFO")) printf("EGL EXTN:\n%s\n", str);
219
224 // Disable Partial Rendering 220 // Disable Partial Rendering
225 if ((s = getenv("EVAS_GL_PARTIAL_DISABLE")) && atoi(s)) 221 s = getenv("EVAS_GL_PARTIAL_DISABLE");
222 if ((s) && (atoi(s)))
226 { 223 {
227 extn_have_buffer_age = 0; 224 _extn_have_buffer_age = 0;
228 glsym_eglSwapBuffersWithDamage = NULL; 225 glsym_eglSwapBuffersWithDamage = NULL;
229 } 226 }
230 if (!strstr(str, "EGL_EXT_buffer_age")) 227 if (!strstr(str, "EGL_EXT_buffer_age")) _extn_have_buffer_age = 0;
231 extn_have_buffer_age = 0;
232 if (!strstr(str, "EGL_EXT_swap_buffers_with_damage")) 228 if (!strstr(str, "EGL_EXT_swap_buffers_with_damage"))
233 glsym_eglSwapBuffersWithDamage = NULL; 229 glsym_eglSwapBuffersWithDamage = NULL;
234 } 230 }
235 else 231 else
236 { 232 {
237 if (getenv("EVAS_GL_INFO")) 233 if (getenv("EVAS_GL_INFO")) printf("NO EGL EXTN!\n");
238 printf("NO EGL EXTN!\n"); 234 _extn_have_buffer_age = 0;
239 extn_have_buffer_age = 0;
240 } 235 }
241} 236}
242 237
243static void * 238static void *
244evgl_eng_display_get(void *data) 239evgl_eng_display_get(void *data)
245{ 240{
246 Render_Engine *re = (Render_Engine *)data; 241 Render_Engine *re;
247 242
243 re = (Render_Engine *)data;
248 if (!re) 244 if (!re)
249 { 245 {
250 ERR("Invalid Render Engine Data!"); 246 ERR("Invalid Render Engine Data!");
@@ -252,7 +248,7 @@ evgl_eng_display_get(void *data)
252 } 248 }
253 249
254 if (eng_get_ob(re)) 250 if (eng_get_ob(re))
255 return (void*)eng_get_ob(re)->egl_disp; 251 return (void*)eng_get_ob(re)->egl.disp;
256 else 252 else
257 return NULL; 253 return NULL;
258} 254}
@@ -260,8 +256,9 @@ evgl_eng_display_get(void *data)
260static void * 256static void *
261evgl_eng_evas_surface_get(void *data) 257evgl_eng_evas_surface_get(void *data)
262{ 258{
263 Render_Engine *re = (Render_Engine *)data; 259 Render_Engine *re;
264 260
261 re = (Render_Engine *)data;
265 if (!re) 262 if (!re)
266 { 263 {
267 ERR("Invalid Render Engine Data!"); 264 ERR("Invalid Render Engine Data!");
@@ -269,7 +266,7 @@ evgl_eng_evas_surface_get(void *data)
269 } 266 }
270 267
271 if (eng_get_ob(re)) 268 if (eng_get_ob(re))
272 return (void*)eng_get_ob(re)->egl_surface[0]; 269 return (void*)eng_get_ob(re)->egl.surface[0];
273 else 270 else
274 return NULL; 271 return NULL;
275} 272}
@@ -277,19 +274,20 @@ evgl_eng_evas_surface_get(void *data)
277static int 274static int
278evgl_eng_make_current(void *data, void *surface, void *context, int flush) 275evgl_eng_make_current(void *data, void *surface, void *context, int flush)
279{ 276{
280 Render_Engine *re = (Render_Engine *)data; 277 Render_Engine *re;
281 EGLContext ctx; 278 EGLContext ctx;
282 EGLSurface sfc; 279 EGLSurface sfc;
283 EGLDisplay dpy; 280 EGLDisplay dpy;
284 int ret = 0; 281 int ret = 0;
285 282
283 re = (Render_Engine *)data;
286 if (!re) 284 if (!re)
287 { 285 {
288 ERR("Invalid Render Engine Data!"); 286 ERR("Invalid Render Engine Data!");
289 return 0; 287 return 0;
290 } 288 }
291 289
292 dpy = eng_get_ob(re)->egl_disp; 290 dpy = eng_get_ob(re)->egl.disp;
293 ctx = (EGLContext)context; 291 ctx = (EGLContext)context;
294 sfc = (EGLSurface)surface; 292 sfc = (EGLSurface)surface;
295 293
@@ -302,6 +300,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
302 ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError()); 300 ERR("eglMakeCurrent() failed! Error Code=%#x", eglGetError());
303 return 0; 301 return 0;
304 } 302 }
303
305 return 1; 304 return 1;
306 } 305 }
307 306
@@ -309,7 +308,7 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
309 (eglGetCurrentSurface(EGL_READ) != sfc) || 308 (eglGetCurrentSurface(EGL_READ) != sfc) ||
310 (eglGetCurrentSurface(EGL_DRAW) != sfc) ) 309 (eglGetCurrentSurface(EGL_DRAW) != sfc) )
311 { 310 {
312 if (flush) eng_window_use(NULL); 311 if (flush) evas_outbuf_use(NULL);
313 312
314 ret = eglMakeCurrent(dpy, sfc, sfc, ctx); 313 ret = eglMakeCurrent(dpy, sfc, sfc, ctx);
315 if (!ret) 314 if (!ret)
@@ -325,10 +324,11 @@ evgl_eng_make_current(void *data, void *surface, void *context, int flush)
325static void * 324static void *
326evgl_eng_native_window_create(void *data) 325evgl_eng_native_window_create(void *data)
327{ 326{
328 Render_Engine *re = (Render_Engine *)data; 327 Render_Engine *re;
329 struct gbm_surface *surface; 328 struct gbm_surface *surface;
330 Evas_Engine_Info_GL_Drm *info; 329 Evas_Engine_Info_GL_Drm *info;
331 330
331 re = (Render_Engine *)data;
332 if (!re) 332 if (!re)
333 { 333 {
334 ERR("Invalid Render Engine Data!"); 334 ERR("Invalid Render Engine Data!");
@@ -345,9 +345,12 @@ evgl_eng_native_window_create(void *data)
345 surface = gbm_surface_create(info->info.gbm, 1, 1, info->info.format, 345 surface = gbm_surface_create(info->info.gbm, 1, 1, info->info.format,
346 info->info.flags); 346 info->info.flags);
347 if (!surface) 347 if (!surface)
348 ERR("Could not create gl drm window: %m"); 348 {
349 ERR("Could not create gl drm window: %m");
350 return NULL;
351 }
349 352
350 return (void*)surface; 353 return (void *)surface;
351} 354}
352 355
353static int 356static int
@@ -367,16 +370,17 @@ evgl_eng_native_window_destroy(void *data, void *native_window)
367 return 0; 370 return 0;
368 } 371 }
369 372
370 gbm_surface_destroy((struct gbm_surface*)native_window); 373 gbm_surface_destroy((struct gbm_surface *)native_window);
371 return 1; 374 return 1;
372} 375}
373 376
374static void * 377static void *
375evgl_eng_window_surface_create(void *data, void *native_window) 378evgl_eng_window_surface_create(void *data, void *native_window)
376{ 379{
377 Render_Engine *re = (Render_Engine *)data; 380 Render_Engine *re;
378 EGLSurface surface = EGL_NO_SURFACE; 381 EGLSurface surface = EGL_NO_SURFACE;
379 382
383 re = (Render_Engine *)data;
380 if (!re) 384 if (!re)
381 { 385 {
382 ERR("Invalid Render Engine Data!"); 386 ERR("Invalid Render Engine Data!");
@@ -384,8 +388,8 @@ evgl_eng_window_surface_create(void *data, void *native_window)
384 } 388 }
385 389
386 // Create resource surface for EGL 390 // Create resource surface for EGL
387 surface = eglCreateWindowSurface(eng_get_ob(re)->egl_disp, 391 surface = eglCreateWindowSurface(eng_get_ob(re)->egl.disp,
388 eng_get_ob(re)->egl_config, 392 eng_get_ob(re)->egl.config,
389 (EGLNativeWindowType)native_window, 393 (EGLNativeWindowType)native_window,
390 NULL); 394 NULL);
391 if (!surface) 395 if (!surface)
@@ -394,15 +398,16 @@ evgl_eng_window_surface_create(void *data, void *native_window)
394 return NULL; 398 return NULL;
395 } 399 }
396 400
397 return (void*)surface; 401 return (void *)surface;
398} 402}
399 403
400static int 404static int
401evgl_eng_window_surface_destroy(void *data, void *surface) 405evgl_eng_window_surface_destroy(void *data, void *surface)
402{ 406{
403 Render_Engine *re = (Render_Engine *)data; 407 Render_Engine *re;
404 EGLBoolean ret = EGL_FALSE; 408 EGLBoolean ret = EGL_FALSE;
405 409
410 re = (Render_Engine *)data;
406 if (!re) 411 if (!re)
407 { 412 {
408 ERR("Invalid Render Engine Data!"); 413 ERR("Invalid Render Engine Data!");
@@ -415,7 +420,7 @@ evgl_eng_window_surface_destroy(void *data, void *surface)
415 return 0; 420 return 0;
416 } 421 }
417 422
418 ret = eglDestroySurface(eng_get_ob(re)->egl_disp, (EGLSurface)surface); 423 ret = eglDestroySurface(eng_get_ob(re)->egl.disp, (EGLSurface)surface);
419 if (ret == EGL_TRUE) return 1; 424 if (ret == EGL_TRUE) return 1;
420 425
421 return 0; 426 return 0;
@@ -424,10 +429,11 @@ evgl_eng_window_surface_destroy(void *data, void *surface)
424static void * 429static void *
425evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version) 430evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version)
426{ 431{
427 Render_Engine *re = (Render_Engine *)data; 432 Render_Engine *re;
428 EGLContext context = EGL_NO_CONTEXT; 433 EGLContext context = EGL_NO_CONTEXT;
429 int context_attrs[3]; 434 int context_attrs[3];
430 435
436 re = (Render_Engine *)data;
431 if (!re) 437 if (!re)
432 { 438 {
433 ERR("Invalid Render Engine Data!"); 439 ERR("Invalid Render Engine Data!");
@@ -447,16 +453,16 @@ evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version ver
447 // Share context already assumes that it's sharing with evas' context 453 // Share context already assumes that it's sharing with evas' context
448 if (share_ctx) 454 if (share_ctx)
449 { 455 {
450 context = eglCreateContext(eng_get_ob(re)->egl_disp, 456 context = eglCreateContext(eng_get_ob(re)->egl.disp,
451 eng_get_ob(re)->egl_config, 457 eng_get_ob(re)->egl.config,
452 (EGLContext)share_ctx, 458 (EGLContext)share_ctx,
453 context_attrs); 459 context_attrs);
454 } 460 }
455 else 461 else
456 { 462 {
457 context = eglCreateContext(eng_get_ob(re)->egl_disp, 463 context = eglCreateContext(eng_get_ob(re)->egl.disp,
458 eng_get_ob(re)->egl_config, 464 eng_get_ob(re)->egl.config,
459 eng_get_ob(re)->egl_context[0], // Evas' GL Context 465 eng_get_ob(re)->egl.context[0], // Evas' GL Context
460 context_attrs); 466 context_attrs);
461 } 467 }
462 468
@@ -466,22 +472,24 @@ evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version ver
466 return NULL; 472 return NULL;
467 } 473 }
468 474
469 return (void*)context; 475 return (void *)context;
470} 476}
471 477
472static int 478static int
473evgl_eng_context_destroy(void *data, void *context) 479evgl_eng_context_destroy(void *data, void *context)
474{ 480{
475 Render_Engine *re = (Render_Engine *)data; 481 Render_Engine *re;
476 EGLBoolean ret = EGL_FALSE; 482 EGLBoolean ret = EGL_FALSE;
477 483
484 re = (Render_Engine *)data;
478 if ((!re) || (!context)) 485 if ((!re) || (!context))
479 { 486 {
480 ERR("Invalid Render Input Data. Engine: %p, Context: %p", data, context); 487 ERR("Invalid Render Input Data. Engine: %p, Context: %p",
488 data, context);
481 return 0; 489 return 0;
482 } 490 }
483 491
484 ret = eglDestroyContext(eng_get_ob(re)->egl_disp, (EGLContext)context); 492 ret = eglDestroyContext(eng_get_ob(re)->egl.disp, (EGLContext)context);
485 if (ret == EGL_TRUE) return 1; 493 if (ret == EGL_TRUE) return 1;
486 494
487 return 0; 495 return 0;
@@ -490,15 +498,16 @@ evgl_eng_context_destroy(void *data, void *context)
490static const char * 498static const char *
491evgl_eng_string_get(void *data) 499evgl_eng_string_get(void *data)
492{ 500{
493 Render_Engine *re = (Render_Engine *)data; 501 Render_Engine *re;
494 502
503 re = (Render_Engine *)data;
495 if (!re) 504 if (!re)
496 { 505 {
497 ERR("Invalid Render Engine Data!"); 506 ERR("Invalid Render Engine Data!");
498 return NULL; 507 return NULL;
499 } 508 }
500 509
501 return eglQueryString(eng_get_ob(re)->egl_disp, EGL_EXTENSIONS); 510 return eglQueryString(eng_get_ob(re)->egl.disp, EGL_EXTENSIONS);
502} 511}
503 512
504static void * 513static void *
@@ -511,8 +520,9 @@ evgl_eng_proc_address_get(const char *name)
511static int 520static int
512evgl_eng_rotation_angle_get(void *data) 521evgl_eng_rotation_angle_get(void *data)
513{ 522{
514 Render_Engine *re = (Render_Engine *)data; 523 Render_Engine *re;
515 524
525 re = (Render_Engine *)data;
516 if (!re) 526 if (!re)
517 { 527 {
518 ERR("Invalid Render Engine Data!"); 528 ERR("Invalid Render Engine Data!");
@@ -528,13 +538,174 @@ evgl_eng_rotation_angle_get(void *data)
528 } 538 }
529} 539}
530 540
541static Eina_Bool
542eng_preload_make_current(void *data, void *doit)
543{
544 Outbuf *ob;
545
546 ob = (Outbuf *)data;
547 if (!ob) return EINA_FALSE;
548
549 if (doit)
550 {
551 if (!eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
552 ob->egl.surface[0], ob->egl.context[0]))
553 return EINA_FALSE;
554 }
555 else
556 {
557 if (!eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE,
558 EGL_NO_SURFACE, EGL_NO_CONTEXT))
559 return EINA_FALSE;
560 }
561
562 return EINA_TRUE;
563}
564
531static void 565static void
532_re_winfree(Render_Engine *re) 566_re_winfree(Render_Engine *re)
533{ 567{
534 if (!re) return; 568 if (!re) return;
535 if (!eng_get_ob(re)->surf) return; 569 if (!eng_get_ob(re)->surf) return;
536 glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re)); 570 glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
537 eng_window_unsurf(eng_get_ob(re)); 571 evas_outbuf_unsurf(eng_get_ob(re));
572}
573
574static void
575_native_cb_bind(void *data EINA_UNUSED, void *image)
576{
577 Evas_GL_Image *img;
578 Native *n;
579
580 if (!(img = image)) return;
581 if (!(n = img->native.data)) return;
582
583 if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
584 {
585 if (n->egl_surface)
586 {
587 if (glsym_glEGLImageTargetTexture2DOES)
588 {
589 glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
590 if (eglGetError() != EGL_SUCCESS)
591 ERR("glEGLImageTargetTexture2DOES() failed.");
592 }
593 else
594 ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
595 }
596 }
597 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
598 glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
599}
600
601static void
602_native_cb_unbind(void *data EINA_UNUSED, void *image)
603{
604 Evas_GL_Image *img;
605 Native *n;
606
607 if (!(img = image)) return;
608 if (!(n = img->native.data)) return;
609
610 if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
611 {
612 //glBindTexture(GL_TEXTURE_2D, 0); //really need?
613 }
614 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
615 glBindTexture(GL_TEXTURE_2D, 0);
616}
617
618static void
619_native_cb_free(void *data, void *image)
620{
621 Render_Engine *re;
622 Outbuf *ob;
623 Evas_GL_Image *img;
624 Native *n;
625 uint32_t texid;
626 void *wlid;
627
628 if (!(re = (Render_Engine *)data)) return;
629 if (!(img = image)) return;
630 if (!(n = img->native.data)) return;
631 if (!(ob = eng_get_ob(re))) return;
632
633 if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
634 {
635 wlid = (void*)n->wl_buf;
636 eina_hash_del(ob->gl_context->shared->native_wl_hash, &wlid, img);
637 if (n->egl_surface)
638 {
639 if (glsym_eglDestroyImage)
640 {
641 glsym_eglDestroyImage(ob->egl.disp, n->egl_surface);
642 if (eglGetError() != EGL_SUCCESS)
643 ERR("eglDestroyImage() failed.");
644 }
645 else
646 ERR("Try eglDestroyImage on EGL with no support");
647 }
648 }
649 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
650 {
651 texid = n->ns.data.opengl.texture_id;
652 eina_hash_del(ob->gl_context->shared->native_tex_hash, &texid, img);
653 }
654
655 img->native.data = NULL;
656 img->native.func.data = NULL;
657 img->native.func.bind = NULL;
658 img->native.func.unbind = NULL;
659 img->native.func.free = NULL;
660
661 free(n);
662}
663
664static Eina_Bool
665eng_gbm_init(Evas_Engine_Info_GL_Drm *info, int w, int h)
666{
667 Ecore_Drm_Device *dev;
668
669 if (!info) return EINA_FALSE;
670 if (!(dev = info->info.dev)) return EINA_FALSE;
671
672 DBG("Create GBM Device");
673 if (!(info->info.gbm = gbm_create_device(dev->drm.fd)))
674 {
675 ERR("Coult not create gbm device: %m");
676 return EINA_FALSE;
677 }
678
679 if (!(info->info.surface =
680 gbm_surface_create(info->info.gbm, w, h,
681 info->info.format, info->info.flags)))
682 {
683 ERR("Could not create gbm surface: %m");
684 gbm_device_destroy(info->info.gbm);
685 info->info.gbm = NULL;
686 return EINA_FALSE;
687 }
688
689 return EINA_TRUE;
690}
691
692static Eina_Bool
693eng_gbm_shutdown(Evas_Engine_Info_GL_Drm *info)
694{
695 if (!info) return EINA_TRUE;
696
697 if (info->info.surface)
698 {
699 gbm_surface_destroy(info->info.surface);
700 info->info.surface = NULL;
701 }
702 if (info->info.gbm)
703 {
704 gbm_device_destroy(info->info.gbm);
705 info->info.gbm = NULL;
706 }
707
708 return EINA_TRUE;
538} 709}
539 710
540/* engine specific override functions */ 711/* engine specific override functions */
@@ -563,21 +734,22 @@ eng_info_free(Evas *eo_e EINA_UNUSED, void *in)
563} 734}
564 735
565static int 736static int
566eng_setup(Evas *eo_e, void *in) 737eng_setup(Evas *evas, void *in)
567{ 738{
568 Evas_Engine_Info_GL_Drm *info = NULL; 739 Evas_Engine_Info_GL_Drm *info;
569 Evas_Public_Data *epd = NULL; 740 Evas_Public_Data *epd;
570 Render_Engine *re = NULL; 741 Render_Engine *re;
571 Render_Engine_Swap_Mode swap_mode = MODE_FULL; 742 Render_Engine_Swap_Mode swap_mode = MODE_FULL;
572 const char *s; 743 const char *s = NULL;
573 744
574 /* try to cast to our engine info structure */ 745 /* try to cast to our engine info structure */
575 if (!(info = (Evas_Engine_Info_GL_Drm *)in)) return 0; 746 if (!(info = (Evas_Engine_Info_GL_Drm *)in)) return 0;
576 747
577 /* try to get the evas public data */ 748 /* try to get the evas public data */
578 if (!(epd = eo_data_scope_get(eo_e, EVAS_CANVAS_CLASS))) return 0; 749 if (!(epd = eo_data_scope_get(evas, EVAS_CANVAS_CLASS))) return 0;
579 750
580 if ((s = getenv("EVAS_GL_SWAP_MODE"))) 751 s = getenv("EVAS_GL_SWAP_MODE");
752 if (s)
581 { 753 {
582 if ((!strcasecmp(s, "full")) || (!strcasecmp(s, "f"))) 754 if ((!strcasecmp(s, "full")) || (!strcasecmp(s, "f")))
583 swap_mode = MODE_FULL; 755 swap_mode = MODE_FULL;
@@ -594,8 +766,7 @@ eng_setup(Evas *eo_e, void *in)
594 swap_mode = MODE_QUADRUPLE; 766 swap_mode = MODE_QUADRUPLE;
595 } 767 }
596 768
597 /* check for existing engine output */ 769 if (!(re = epd->engine.data.output))
598 if (!epd->engine.data.output)
599 { 770 {
600 Outbuf *ob; 771 Outbuf *ob;
601 Render_Engine_Merge_Mode merge_mode = MERGE_FULL; 772 Render_Engine_Merge_Mode merge_mode = MERGE_FULL;
@@ -606,64 +777,53 @@ eng_setup(Evas *eo_e, void *in)
606 glsym_evas_gl_preload_init(); 777 glsym_evas_gl_preload_init();
607 } 778 }
608 779
609 if (!(info->info.gbm) || !(info->info.surface)) 780 if (!(re = calloc(1, sizeof(Render_Engine)))) return 0;
610 return 0;
611
612#ifdef GL_DRM_DBG
613 DBG("FD: %d, GBM_DEVICE: 0x%x, GBM_SURFACE: 0x%x",
614 info->info.fd, (unsigned int)info->info.gbm,
615 (unsigned int)info->info.surface);
616#endif
617 781
618 re = calloc(1, sizeof(Render_Engine)); 782 if (!eng_gbm_init(info, epd->output.w, epd->output.h))
619 if (!re) return 0; 783 {
784 free(re);
785 return 0;
786 }
620 787
621 /* try to create new outbuf */ 788 /* try to create new outbuf */
622 ob = eng_window_new(info, eo_e, info->info.gbm, info->info.surface, 789 ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode);
623 info->info.screen,info->info.depth,
624 epd->output.w, epd->output.h, info->indirect,
625 info->info.destination_alpha,
626 info->info.rotation, swap_mode);
627 if (!ob) 790 if (!ob)
628 { 791 {
629 /* shutdown destroy gbm surface & shutdown gbm device */ 792 eng_gbm_shutdown(info);
630 evas_drm_gbm_shutdown(info);
631 free(re); 793 free(re);
632 return 0; 794 return 0;
633 } 795 }
634 796
635 if (!evas_render_engine_gl_generic_init(&re->generic, ob, 797 if (!evas_render_engine_gl_generic_init(&re->generic, ob,
636 eng_outbuf_swap_mode, 798 evas_outbuf_buffer_state_get,
637 eng_outbuf_get_rot, 799 evas_outbuf_rot_get,
638 eng_outbuf_reconfigure, 800 evas_outbuf_reconfigure,
639 eng_outbuf_region_first_rect, 801 evas_outbuf_update_region_first_rect,
640 eng_outbuf_new_region_for_update, 802 evas_outbuf_update_region_new,
641 eng_outbuf_push_updated_region, 803 evas_outbuf_update_region_push,
642 eng_outbuf_push_free_region_for_update, 804 evas_outbuf_update_region_free,
643 NULL, 805 NULL,
644 eng_outbuf_flush, 806 evas_outbuf_flush,
645 eng_window_free, 807 evas_outbuf_free,
646 eng_window_use, 808 evas_outbuf_use,
647 eng_outbuf_gl_context_get, 809 evas_outbuf_gl_context_get,
648 eng_outbuf_egl_display_get, 810 evas_outbuf_egl_display_get,
649 eng_gl_context_new, 811 evas_outbuf_gl_context_new,
650 eng_gl_context_use, 812 evas_outbuf_gl_context_use,
651 &evgl_funcs, 813 &evgl_funcs, ob->w, ob->h))
652 epd->output.w, epd->output.h))
653 { 814 {
815 eng_gbm_shutdown(info);
654 /* free outbuf */ 816 /* free outbuf */
655 eng_window_free(ob); 817 evas_outbuf_free(ob);
656 /* shutdown destroy gbm surface & shutdown gbm device */
657 evas_drm_gbm_shutdown(info);
658 free(re); 818 free(re);
659 return 0; 819 return 0;
660 } 820 }
661 821
662 /* tell the engine to use this render_engine for output */
663 epd->engine.data.output = re; 822 epd->engine.data.output = re;
664 gl_wins++; 823 gl_wins++;
665 824
666 if ((s = getenv("EVAS_GL_PARTIAL_MERGE"))) 825 s = getenv("EVAS_GL_PARTIAL_MERGE");
826 if (s)
667 { 827 {
668 if ((!strcmp(s, "bounding")) || (!strcmp(s, "b"))) 828 if ((!strcmp(s, "bounding")) || (!strcmp(s, "b")))
669 merge_mode = MERGE_BOUNDING; 829 merge_mode = MERGE_BOUNDING;
@@ -681,36 +841,24 @@ eng_setup(Evas *eo_e, void *in)
681 } 841 }
682 else 842 else
683 { 843 {
684 re = epd->engine.data.output;
685
686 if (eng_get_ob(re) && _re_wincheck(eng_get_ob(re))) 844 if (eng_get_ob(re) && _re_wincheck(eng_get_ob(re)))
687 { 845 {
688 if ((eng_get_ob(re)->info->info.gbm != eng_get_ob(re)->gbm) || 846 if ((info->info.gbm != eng_get_ob(re)->gbm) ||
689 (eng_get_ob(re)->info->info.surface != eng_get_ob(re)->surface) || 847 (info->info.surface != eng_get_ob(re)->surface) ||
690 (eng_get_ob(re)->info->info.screen != eng_get_ob(re)->screen) || 848 (info->info.depth != eng_get_ob(re)->depth) ||
691 (eng_get_ob(re)->info->info.depth != eng_get_ob(re)->depth) || 849 (info->info.destination_alpha != eng_get_ob(re)->destination_alpha))
692 (eng_get_ob(re)->info->info.destination_alpha != eng_get_ob(re)->alpha))
693 { 850 {
694 Outbuf *ob; 851 Outbuf *ob;
695 852
696 eng_get_ob(re)->gl_context->references++; 853 eng_get_ob(re)->gl_context->references++;
697 gl_wins--; 854 gl_wins--;
698 855
699 ob = eng_window_new(info, eo_e, 856 ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode);
700 eng_get_ob(re)->info->info.gbm, 857
701 eng_get_ob(re)->info->info.surface, 858 evas_outbuf_free(eng_get_ob(re));
702 eng_get_ob(re)->info->info.screen,
703 eng_get_ob(re)->info->info.depth,
704 epd->output.w, epd->output.h,
705 eng_get_ob(re)->info->indirect,
706 eng_get_ob(re)->info->info.destination_alpha,
707 eng_get_ob(re)->info->info.rotation,
708 swap_mode);
709
710 eng_window_free(eng_get_ob(re));
711 re->generic.software.ob = NULL; 859 re->generic.software.ob = NULL;
712 860
713 eng_window_use(ob); 861 evas_outbuf_use(ob);
714 if (ob) 862 if (ob)
715 { 863 {
716 evas_render_engine_software_generic_update(&re->generic.software, ob, 864 evas_render_engine_software_generic_update(&re->generic.software, ob,
@@ -722,34 +870,23 @@ eng_setup(Evas *eo_e, void *in)
722 } 870 }
723 else if ((eng_get_ob(re)->w != epd->output.w) || 871 else if ((eng_get_ob(re)->w != epd->output.w) ||
724 (eng_get_ob(re)->h != epd->output.h) || 872 (eng_get_ob(re)->h != epd->output.h) ||
725 (eng_get_ob(re)->info->info.rotation != eng_get_ob(re)->rot)) 873 (info->info.rotation != eng_get_ob(re)->rotation))
726 { 874 {
727 Outbuf *ob; 875 Outbuf *ob;
728 876
729 eng_get_ob(re)->gl_context->references++; 877 eng_get_ob(re)->gl_context->references++;
730 gl_wins--; 878 gl_wins--;
731 879
732 eng_window_free(eng_get_ob(re)); 880 evas_outbuf_free(eng_get_ob(re));
733 re->generic.software.ob = NULL; 881 re->generic.software.ob = NULL;
734 evas_drm_gbm_shutdown(eng_get_ob(re)->info);
735 if (!evas_drm_gbm_init(info, epd->output.w, epd->output.h))
736 return 0;
737 882
738#ifdef GL_DRM_DBG 883 eng_gbm_shutdown(eng_get_ob(re)->info);
739 DBG("FD: %d, GBM_DEVICE: 0x%x, GBM_SURFACE: 0x%x", 884 if (!eng_gbm_init(info, epd->output.w, epd->output.h))
740 info->info.fd, (unsigned int)info->info.gbm, 885 return 0;
741 (unsigned int)info->info.surface);
742#endif
743 886
744 ob = eng_window_new(info, eo_e, info->info.gbm, 887 ob = evas_outbuf_new(info, epd->output.w, epd->output.h, swap_mode);
745 info->info.surface, info->info.screen,
746 info->info.depth,
747 epd->output.w, epd->output.h,
748 info->indirect,
749 info->info.destination_alpha,
750 info->info.rotation, swap_mode);
751 888
752 eng_window_use(ob); 889 evas_outbuf_use(ob);
753 if (ob) 890 if (ob)
754 { 891 {
755 evas_render_engine_software_generic_update(&re->generic.software, ob, 892 evas_render_engine_software_generic_update(&re->generic.software, ob,
@@ -772,9 +909,9 @@ eng_setup(Evas *eo_e, void *in)
772 { 909 {
773 if (eng_get_ob(re)) 910 if (eng_get_ob(re))
774 { 911 {
775 eng_window_free(eng_get_ob(re)); 912 evas_outbuf_free(eng_get_ob(re));
776 gl_wins--; 913 gl_wins--;
777 evas_drm_gbm_shutdown(info); 914 eng_gbm_shutdown(info);
778 } 915 }
779 free(re); 916 free(re);
780 return 0; 917 return 0;
@@ -788,7 +925,7 @@ eng_setup(Evas *eo_e, void *in)
788 epd->engine.func->context_new(epd->engine.data.output); 925 epd->engine.func->context_new(epd->engine.data.output);
789 } 926 }
790 927
791 eng_window_use(eng_get_ob(re)); 928 evas_outbuf_use(eng_get_ob(re));
792 929
793 return 1; 930 return 1;
794} 931}
@@ -799,22 +936,22 @@ eng_output_free(void *data)
799 Render_Engine *re; 936 Render_Engine *re;
800 937
801 re = (Render_Engine *)data; 938 re = (Render_Engine *)data;
802
803 if (re) 939 if (re)
804 { 940 {
805 glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re)); 941 glsym_evas_gl_preload_render_relax(eng_preload_make_current, eng_get_ob(re));
806 942
807 if (gl_wins == 1) glsym_evgl_engine_shutdown(re); 943 if (gl_wins == 1) glsym_evgl_engine_shutdown(re);
808 944
809 evas_drm_gbm_shutdown(eng_get_ob(re)->info); 945 eng_gbm_shutdown(eng_get_ob(re)->info);
810 946
811 //evas_render_engine_software_generic_clean() frees ob. 947 /* NB: evas_render_engine_software_generic_clean() frees ob */
812 evas_render_engine_software_generic_clean(&re->generic.software); 948 evas_render_engine_software_generic_clean(&re->generic.software);
813 949
814 gl_wins--; 950 gl_wins--;
815 951
816 free(re); 952 free(re);
817 } 953 }
954
818 if ((initted == EINA_TRUE) && (gl_wins == 0)) 955 if ((initted == EINA_TRUE) && (gl_wins == 0))
819 { 956 {
820 glsym_evas_gl_preload_shutdown(); 957 glsym_evas_gl_preload_shutdown();
@@ -823,35 +960,15 @@ eng_output_free(void *data)
823 } 960 }
824} 961}
825 962
826Eina_Bool
827eng_preload_make_current(void *data, void *doit)
828{
829 Outbuf *ob = data;
830 if (!ob) return EINA_FALSE;
831
832 if (doit)
833 {
834 if (!eglMakeCurrent(ob->egl_disp, ob->egl_surface[0],
835 ob->egl_surface[0], ob->egl_context[0]))
836 return EINA_FALSE;
837 }
838 else
839 {
840 if (!eglMakeCurrent(ob->egl_disp, EGL_NO_SURFACE,
841 EGL_NO_SURFACE, EGL_NO_CONTEXT))
842 return EINA_FALSE;
843 }
844 return EINA_TRUE;
845}
846
847static Eina_Bool 963static Eina_Bool
848eng_canvas_alpha_get(void *data, void *info EINA_UNUSED) 964eng_canvas_alpha_get(void *data, void *info EINA_UNUSED)
849{ 965{
850 Render_Engine *re; 966 Render_Engine *re;
851 967
852 if (!(re = (Render_Engine *)data)) return EINA_FALSE; 968 re = (Render_Engine *)data;
969 if (!re) return EINA_FALSE;
853 970
854 return re->generic.software.ob->alpha; 971 return eng_get_ob(re)->destination_alpha;
855} 972}
856 973
857static void 974static void
@@ -859,7 +976,8 @@ eng_output_dump(void *data)
859{ 976{
860 Render_Engine *re; 977 Render_Engine *re;
861 978
862 if (!(re = (Render_Engine *)data)) return; 979 re = (Render_Engine *)data;
980 if (!re) return;
863 981
864 evas_common_image_image_all_unload(); 982 evas_common_image_image_all_unload();
865 evas_common_font_font_all_unload(); 983 evas_common_font_font_all_unload();
@@ -867,101 +985,6 @@ eng_output_dump(void *data)
867 _re_winfree(re); 985 _re_winfree(re);
868} 986}
869 987
870static void
871_native_cb_bind(void *data EINA_UNUSED, void *image)
872{
873 Evas_GL_Image *img;
874 Native *n;
875
876 if (!(img = image)) return;
877 if (!(n = img->native.data)) return;
878
879 if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
880 {
881 if (n->egl_surface)
882 {
883 if (glsym_glEGLImageTargetTexture2DOES)
884 {
885 glsym_glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, n->egl_surface);
886 if (eglGetError() != EGL_SUCCESS)
887 ERR("glEGLImageTargetTexture2DOES() failed.");
888 }
889 else
890 ERR("Try glEGLImageTargetTexture2DOES on EGL with no support");
891 }
892 }
893 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
894 {
895 glBindTexture(GL_TEXTURE_2D, n->ns.data.opengl.texture_id);
896 }
897}
898
899static void
900_native_cb_unbind(void *data EINA_UNUSED, void *image)
901{
902 Evas_GL_Image *img;
903 Native *n;
904
905 if (!(img = image)) return;
906 if (!(n = img->native.data)) return;
907
908 if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
909 {
910 //glBindTexture(GL_TEXTURE_2D, 0); //really need?
911 }
912 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
913 {
914 glBindTexture(GL_TEXTURE_2D, 0);
915 }
916}
917
918static void
919_native_cb_free(void *data, void *image)
920{
921 Render_Engine *re;
922 Outbuf *ob;
923 Evas_GL_Image *img;
924 Native *n;
925 uint32_t texid;
926 void *wlid;
927
928 if (!(re = (Render_Engine *)data)) return;
929 if (!(img = image)) return;
930 if (!(n = img->native.data)) return;
931 if (!(ob = eng_get_ob(re))) return;
932
933 if (n->ns.type == EVAS_NATIVE_SURFACE_WL)
934 {
935 wlid = (void*)n->wl_buf;
936 eina_hash_del(ob->gl_context->shared->native_wl_hash, &wlid, img);
937 if (n->egl_surface)
938 {
939 if (glsym_eglDestroyImage)
940 {
941 glsym_eglDestroyImage(eng_get_ob(re)->egl_disp,
942 n->egl_surface);
943 if (eglGetError() != EGL_SUCCESS)
944 ERR("eglDestroyImage() failed.");
945 }
946 else
947 ERR("Try eglDestroyImage on EGL with no support");
948 }
949 }
950 else if (n->ns.type == EVAS_NATIVE_SURFACE_OPENGL)
951 {
952 texid = n->ns.data.opengl.texture_id;
953 eina_hash_del(ob->gl_context->shared->native_tex_hash, &texid, img);
954 }
955
956 img->native.data = NULL;
957 img->native.func.data = NULL;
958 img->native.func.bind = NULL;
959 img->native.func.unbind = NULL;
960 img->native.func.free = NULL;
961
962 free(n);
963}
964
965static void * 988static void *
966eng_image_native_set(void *data, void *image, void *native) 989eng_image_native_set(void *data, void *image, void *native)
967{ 990{
@@ -972,11 +995,13 @@ eng_image_native_set(void *data, void *image, void *native)
972 Evas_GL_Image *img, *img2; 995 Evas_GL_Image *img, *img2;
973 unsigned int tex = 0, fbo = 0; 996 unsigned int tex = 0, fbo = 0;
974 uint32_t texid; 997 uint32_t texid;
975 void *wlid; 998 void *wlid, *wl_buf = NULL;
976 void *wl_buf = NULL; 999
1000 re = (Render_Engine *)data;
1001 if (!re) return NULL;
977 1002
978 if (!(re = (Render_Engine *)data)) return NULL; 1003 ob = eng_get_ob(re);
979 if (!(ob = eng_get_ob(re))) return NULL; 1004 if (!ob) return NULL;
980 1005
981 ns = native; 1006 ns = native;
982 1007
@@ -1027,7 +1052,7 @@ eng_image_native_set(void *data, void *image, void *native)
1027 1052
1028 if ((!ns) && (!img->native.data)) return img; 1053 if ((!ns) && (!img->native.data)) return img;
1029 1054
1030 eng_window_use(ob); 1055 evas_outbuf_use(ob);
1031 1056
1032 if (img->native.data) 1057 if (img->native.data)
1033 { 1058 {
@@ -1085,8 +1110,10 @@ eng_image_native_set(void *data, void *image, void *native)
1085 EGLint attribs[3]; 1110 EGLint attribs[3];
1086 int format, yinvert = 1; 1111 int format, yinvert = 1;
1087 1112
1088 glsym_eglQueryWaylandBufferWL(ob->egl_disp, wl_buf, EGL_TEXTURE_FORMAT, &format); 1113 glsym_eglQueryWaylandBufferWL(ob->egl.disp, wl_buf,
1089 if ((format != EGL_TEXTURE_RGB) && (format != EGL_TEXTURE_RGBA)) 1114 EGL_TEXTURE_FORMAT, &format);
1115 if ((format != EGL_TEXTURE_RGB) &&
1116 (format != EGL_TEXTURE_RGBA))
1090 { 1117 {
1091 ERR("eglQueryWaylandBufferWL() %d format is not supported ", format); 1118 ERR("eglQueryWaylandBufferWL() %d format is not supported ", format);
1092 glsym_evas_gl_common_image_free(img); 1119 glsym_evas_gl_common_image_free(img);
@@ -1099,20 +1126,23 @@ eng_image_native_set(void *data, void *image, void *native)
1099 attribs[2] = EGL_NONE; 1126 attribs[2] = EGL_NONE;
1100 1127
1101 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface)); 1128 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1102 glsym_eglQueryWaylandBufferWL(ob->egl_disp, wl_buf, EGL_WAYLAND_Y_INVERTED_WL, &yinvert); 1129 glsym_eglQueryWaylandBufferWL(ob->egl.disp, wl_buf,
1103 eina_hash_add(ob->gl_context->shared->native_wl_hash, &wlid, img); 1130 EGL_WAYLAND_Y_INVERTED_WL,
1131 &yinvert);
1132 eina_hash_add(ob->gl_context->shared->native_wl_hash,
1133 &wlid, img);
1104 1134
1105 n->wl_buf = wl_buf; 1135 n->wl_buf = wl_buf;
1106 if (glsym_eglCreateImage) 1136 if (glsym_eglCreateImage)
1107 n->egl_surface = glsym_eglCreateImage(ob->egl_disp, 1137 n->egl_surface = glsym_eglCreateImage(ob->egl.disp,
1108 NULL, 1138 NULL,
1109 EGL_WAYLAND_BUFFER_WL, 1139 EGL_WAYLAND_BUFFER_WL,
1110 wl_buf, 1140 wl_buf, attribs);
1111 attribs);
1112 else 1141 else
1113 { 1142 {
1114 ERR("Try eglCreateImage on EGL with no support"); 1143 ERR("Try eglCreateImage on EGL with no support");
1115 eina_hash_del(ob->gl_context->shared->native_wl_hash, &wlid, img); 1144 eina_hash_del(ob->gl_context->shared->native_wl_hash,
1145 &wlid, img);
1116 glsym_evas_gl_common_image_free(img); 1146 glsym_evas_gl_common_image_free(img);
1117 free(n); 1147 free(n);
1118 return NULL; 1148 return NULL;
@@ -1121,7 +1151,8 @@ eng_image_native_set(void *data, void *image, void *native)
1121 if (!n->egl_surface) 1151 if (!n->egl_surface)
1122 { 1152 {
1123 ERR("eglCreatePixmapSurface() for %p failed", wl_buf); 1153 ERR("eglCreatePixmapSurface() for %p failed", wl_buf);
1124 eina_hash_del(ob->gl_context->shared->native_wl_hash, &wlid, img); 1154 eina_hash_del(ob->gl_context->shared->native_wl_hash,
1155 &wlid, img);
1125 glsym_evas_gl_common_image_free(img); 1156 glsym_evas_gl_common_image_free(img);
1126 free(n); 1157 free(n);
1127 return NULL; 1158 return NULL;
@@ -1151,7 +1182,8 @@ eng_image_native_set(void *data, void *image, void *native)
1151 if ((n = calloc(1, sizeof(Native)))) 1182 if ((n = calloc(1, sizeof(Native))))
1152 { 1183 {
1153 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface)); 1184 memcpy(&(n->ns), ns, sizeof(Evas_Native_Surface));
1154 eina_hash_add(ob->gl_context->shared->native_tex_hash, &texid, img); 1185 eina_hash_add(ob->gl_context->shared->native_tex_hash,
1186 &texid, img);
1155 1187
1156 n->egl_surface = 0; 1188 n->egl_surface = 0;
1157 1189
@@ -1173,7 +1205,6 @@ eng_image_native_set(void *data, void *image, void *native)
1173 return img; 1205 return img;
1174} 1206}
1175 1207
1176
1177/* module api functions */ 1208/* module api functions */
1178static int 1209static int
1179module_open(Evas_Module *em) 1210module_open(Evas_Module *em)
@@ -1202,14 +1233,13 @@ module_open(Evas_Module *em)
1202 func = pfunc; 1233 func = pfunc;
1203 1234
1204 /* now to override methods */ 1235 /* now to override methods */
1205#define ORD(f) EVAS_API_OVERRIDE(f, &func, eng_) 1236 EVAS_API_OVERRIDE(info, &func, eng_);
1206 ORD(info); 1237 EVAS_API_OVERRIDE(info_free, &func, eng_);
1207 ORD(info_free); 1238 EVAS_API_OVERRIDE(setup, &func, eng_);
1208 ORD(setup); 1239 EVAS_API_OVERRIDE(canvas_alpha_get, &func, eng_);
1209 ORD(canvas_alpha_get); 1240 EVAS_API_OVERRIDE(output_free, &func, eng_);
1210 ORD(output_free); 1241 EVAS_API_OVERRIDE(output_dump, &func, eng_);
1211 ORD(output_dump); 1242 EVAS_API_OVERRIDE(image_native_set, &func, eng_);
1212 ORD(image_native_set);
1213 1243
1214 /* Mesa's EGL driver loads wayland egl by default. (called by eglGetProcaddr() ) 1244 /* Mesa's EGL driver loads wayland egl by default. (called by eglGetProcaddr() )
1215 * implicit env set (EGL_PLATFORM=drm) prevent that. */ 1245 * implicit env set (EGL_PLATFORM=drm) prevent that. */
@@ -1218,6 +1248,7 @@ module_open(Evas_Module *em)
1218 1248
1219 /* now advertise out own api */ 1249 /* now advertise out own api */
1220 em->functions = (void *)(&func); 1250 em->functions = (void *)(&func);
1251
1221 return 1; 1252 return 1;
1222} 1253}
1223 1254
@@ -1226,6 +1257,7 @@ module_close(Evas_Module *em EINA_UNUSED)
1226{ 1257{
1227 /* unregister the eina log domain for this engine */ 1258 /* unregister the eina log domain for this engine */
1228 eina_log_domain_unregister(_evas_engine_gl_drm_log_dom); 1259 eina_log_domain_unregister(_evas_engine_gl_drm_log_dom);
1260 _evas_engine_gl_drm_log_dom = -1;
1229} 1261}
1230 1262
1231static Evas_Module_Api evas_modapi = 1263static Evas_Module_Api evas_modapi =
diff --git a/src/modules/evas/engines/gl_drm/evas_engine.h b/src/modules/evas/engines/gl_drm/evas_engine.h
new file mode 100644
index 0000000000..b00cf382cc
--- /dev/null
+++ b/src/modules/evas/engines/gl_drm/evas_engine.h
@@ -0,0 +1,128 @@
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_GL_Drm.h"
9
10# define GL_GLEXT_PROTOTYPES
11# include <EGL/egl.h>
12# include <EGL/eglext.h>
13# include <EGL/eglmesaext.h>
14# include <GLES2/gl2.h>
15# include <GLES2/gl2ext.h>
16# include "../gl_generic/Evas_Engine_GL_Generic.h"
17
18extern int _evas_engine_gl_drm_log_dom;
19extern int _extn_have_buffer_age;
20
21# ifdef ERR
22# undef ERR
23# endif
24# define ERR(...) EINA_LOG_DOM_ERR(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
25
26# ifdef DBG
27# undef DBG
28# endif
29# define DBG(...) EINA_LOG_DOM_DBG(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
30
31# ifdef INF
32# undef INF
33# endif
34# define INF(...) EINA_LOG_DOM_INFO(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
35
36# ifdef WRN
37# undef WRN
38# endif
39# define WRN(...) EINA_LOG_DOM_WARN(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
40
41# ifdef CRI
42# undef CRI
43# endif
44# define CRI(...) EINA_LOG_DOM_CRIT(_evas_engine_gl_drm_log_dom, __VA_ARGS__)
45
46extern Evas_GL_Common_Context_New glsym_evas_gl_common_context_new;
47extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush;
48extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free;
49extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use;
50extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe;
51extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done;
52extern Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize;
53extern Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump;
54extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock;
55extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock;
56
57struct _Context_3D
58{
59 EGLDisplay display;
60 EGLContext context;
61 EGLSurface surface;
62};
63
64struct _Outbuf
65{
66 Evas_Engine_Info_GL_Drm *info;
67 Evas_Engine_GL_Context *gl_context;
68
69 int w, h;
70 unsigned int rotation, depth;
71 Render_Engine_Swap_Mode swap_mode;
72
73 struct gbm_device *gbm;
74 struct gbm_surface *surface;
75
76 struct
77 {
78 EGLContext context[1];
79 EGLSurface surface[1];
80 EGLConfig config;
81 EGLDisplay disp;
82 } egl;
83
84 struct
85 {
86 int prev_age, frame_cnt;
87 int curr, last, num;
88 Ecore_Drm_Fb *buffer[4];
89 struct gbm_bo *bo[4];
90 Eina_List *pending_writes;
91 } priv;
92
93 Eina_Bool destination_alpha : 1;
94 Eina_Bool vsync : 1;
95 Eina_Bool lost_back : 1;
96 Eina_Bool surf : 1;
97 Eina_Bool drew : 1;
98};
99
100Outbuf *evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_Mode swap_mode);
101void evas_outbuf_free(Outbuf *ob);
102void evas_outbuf_use(Outbuf *ob);
103void evas_outbuf_resurf(Outbuf *ob);
104void evas_outbuf_unsurf(Outbuf *ob);
105void evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth);
106Render_Engine_Swap_Mode evas_outbuf_buffer_state_get(Outbuf *ob);
107int evas_outbuf_rot_get(Outbuf *ob);
108Eina_Bool evas_outbuf_update_region_first_rect(Outbuf *ob);
109void *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch);
110void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h);
111void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update);
112void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode);
113Evas_Engine_GL_Context* evas_outbuf_gl_context_get(Outbuf *ob);
114void *evas_outbuf_egl_display_get(Outbuf *ob);
115Context_3D *evas_outbuf_gl_context_new(Outbuf *ob);
116void evas_outbuf_gl_context_use(Context_3D *ctx);
117
118static inline Eina_Bool
119_re_wincheck(Outbuf *ob)
120{
121 if (ob->surf) return EINA_TRUE;
122 evas_outbuf_resurf(ob);
123 ob->lost_back = 1;
124 if (!ob->surf) ERR("GL engine can't re-create window surface!");
125 return EINA_FALSE;
126}
127
128#endif
diff --git a/src/modules/evas/engines/gl_drm/evas_outbuf.c b/src/modules/evas/engines/gl_drm/evas_outbuf.c
new file mode 100644
index 0000000000..124a3563a3
--- /dev/null
+++ b/src/modules/evas/engines/gl_drm/evas_outbuf.c
@@ -0,0 +1,656 @@
1#include "evas_engine.h"
2
3/* local variables */
4static Outbuf *_evas_gl_drm_window = NULL;
5static EGLContext context = EGL_NO_CONTEXT;
6static int win_count = 0;
7
8static void
9_evas_outbuf_cb_pageflip(void *data)
10{
11 Outbuf *ob;
12 Ecore_Drm_Fb *fb;
13
14 if (!(ob = data)) return;
15
16 if ((fb = ob->priv.buffer[ob->priv.curr]))
17 {
18 fb->pending_flip = EINA_FALSE;
19 gbm_surface_release_buffer(ob->surface, ob->priv.bo[ob->priv.curr]);
20 }
21
22 ob->priv.last = ob->priv.curr;
23 ob->priv.curr = (ob->priv.curr + 1) % ob->priv.num;
24}
25
26static void
27_evas_outbuf_buffer_swap(Outbuf *ob, Eina_Rectangle *rects, unsigned int count)
28{
29 Ecore_Drm_Fb *buff;
30
31 buff = ob->priv.buffer[ob->priv.curr];
32
33 ob->priv.bo[ob->priv.curr] = gbm_surface_lock_front_buffer(ob->surface);
34
35 ecore_drm_fb_dirty(buff, rects, count);
36 ecore_drm_fb_set(ob->info->info.dev, buff);
37 ecore_drm_fb_send(ob->info->info.dev, buff, _evas_outbuf_cb_pageflip, ob);
38}
39
40static Eina_Bool
41_evas_outbuf_make_current(void *data, void *doit)
42{
43 Outbuf *ob;
44
45 if (!(ob = data)) return EINA_FALSE;
46
47 if (doit)
48 {
49 if (!eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
50 ob->egl.surface[0], ob->egl.context[0]))
51 return EINA_FALSE;
52 }
53 else
54 {
55 if (!eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE,
56 EGL_NO_SURFACE, EGL_NO_CONTEXT))
57 return EINA_FALSE;
58 }
59
60 return EINA_TRUE;
61}
62
63static Eina_Bool
64_evas_outbuf_egl_setup(Outbuf *ob)
65{
66 int ctx_attr[3];
67 int cfg_attr[40];
68 int maj = 0, min = 0;
69 int ncfg = 0, n = 0;
70 const GLubyte *vendor, *renderer, *version, *glslversion;
71 Eina_Bool blacklist = EINA_FALSE;
72
73 /* setup gbm egl surface */
74 ctx_attr[0] = EGL_CONTEXT_CLIENT_VERSION;
75 ctx_attr[1] = 2;
76 ctx_attr[2] = EGL_NONE;
77
78 cfg_attr[n++] = EGL_SURFACE_TYPE;
79 cfg_attr[n++] = EGL_WINDOW_BIT;
80 cfg_attr[n++] = EGL_RED_SIZE;
81 cfg_attr[n++] = 1;
82 cfg_attr[n++] = EGL_GREEN_SIZE;
83 cfg_attr[n++] = 1;
84 cfg_attr[n++] = EGL_BLUE_SIZE;
85 cfg_attr[n++] = 1;
86 cfg_attr[n++] = EGL_ALPHA_SIZE;
87 if (ob->destination_alpha) cfg_attr[n++] = 1;
88 else cfg_attr[n++] = 0;
89 cfg_attr[n++] = EGL_RENDERABLE_TYPE;
90 cfg_attr[n++] = EGL_OPENGL_ES2_BIT;
91 cfg_attr[n++] = EGL_NONE;
92
93 ob->egl.disp = eglGetDisplay((EGLNativeDisplayType)(ob->gbm));
94 if (ob->egl.disp == EGL_NO_DISPLAY)
95 {
96 ERR("eglGetDisplay() fail. code=%#x", eglGetError());
97 return EINA_FALSE;
98 }
99
100 if (!eglInitialize(ob->egl.disp, &maj, &min))
101 {
102 ERR("eglInitialize() fail. code=%#x", eglGetError());
103 return EINA_FALSE;
104 }
105
106 eglBindAPI(EGL_OPENGL_ES_API);
107 if (eglGetError() != EGL_SUCCESS)
108 {
109 ERR("eglBindAPI() fail. code=%#x", eglGetError());
110 return EINA_FALSE;
111 }
112
113 if (!eglChooseConfig(ob->egl.disp, cfg_attr, &ob->egl.config,
114 1, &ncfg) || (ncfg != 1))
115 {
116 ERR("eglChooseConfig() fail. code=%#x", eglGetError());
117 return EINA_FALSE;
118 }
119
120 ob->egl.surface[0] =
121 eglCreateWindowSurface(ob->egl.disp, ob->egl.config,
122 (EGLNativeWindowType)ob->surface, NULL);
123 if (ob->egl.surface[0] == EGL_NO_SURFACE)
124 {
125 ERR("eglCreateWindowSurface() fail for %p. code=%#x",
126 ob->surface, eglGetError());
127 return EINA_FALSE;
128 }
129
130 ob->egl.context[0] =
131 eglCreateContext(ob->egl.disp, ob->egl.config, context, ctx_attr);
132 if (ob->egl.context[0] == EGL_NO_CONTEXT)
133 {
134 ERR("eglCreateContext() fail. code=%#x", eglGetError());
135 return EINA_FALSE;
136 }
137
138 if (context == EGL_NO_CONTEXT) context = ob->egl.context[0];
139
140 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
141 ob->egl.surface[0], ob->egl.context[0]) == EGL_FALSE)
142 {
143 ERR("eglMakeCurrent() fail. code=%#x", eglGetError());
144 return EINA_FALSE;
145 }
146
147 vendor = glGetString(GL_VENDOR);
148 renderer = glGetString(GL_RENDERER);
149 version = glGetString(GL_VERSION);
150 glslversion = glGetString(GL_SHADING_LANGUAGE_VERSION);
151 if (!vendor) vendor = (unsigned char *)"-UNKNOWN-";
152 if (!renderer) renderer = (unsigned char *)"-UNKNOWN-";
153 if (!version) version = (unsigned char *)"-UNKNOWN-";
154 if (!glslversion) glslversion = (unsigned char *)"-UNKNOWN-";
155 if (getenv("EVAS_GL_INFO"))
156 {
157 fprintf(stderr, "vendor : %s\n", vendor);
158 fprintf(stderr, "renderer: %s\n", renderer);
159 fprintf(stderr, "version : %s\n", version);
160 fprintf(stderr, "glsl ver: %s\n", glslversion);
161 }
162
163 if (strstr((const char *)vendor, "Mesa Project"))
164 {
165 if (strstr((const char *)renderer, "Software Rasterizer"))
166 blacklist = EINA_TRUE;
167 }
168 if (strstr((const char *)renderer, "softpipe"))
169 blacklist = EINA_TRUE;
170 if (strstr((const char *)renderer, "llvmpipe"))
171 blacklist = EINA_TRUE;
172
173 if ((blacklist) && (!getenv("EVAS_GL_NO_BLACKLIST")))
174 {
175 ERR("OpenGL Driver blacklisted:");
176 ERR("Vendor: %s", (const char *)vendor);
177 ERR("Renderer: %s", (const char *)renderer);
178 ERR("Version: %s", (const char *)version);
179 return EINA_FALSE;
180 }
181
182 ob->gl_context = glsym_evas_gl_common_context_new();
183 if (!ob->gl_context) return EINA_FALSE;
184
185#ifdef GL_GLES
186 ob->gl_context->egldisp = ob->egl.disp;
187 ob->gl_context->eglctxt = ob->egl.context[0];
188#endif
189
190 evas_outbuf_use(ob);
191 glsym_evas_gl_common_context_resize(ob->gl_context,
192 ob->w, ob->h, ob->rotation);
193
194 ob->surf = EINA_TRUE;
195
196 return EINA_TRUE;
197}
198
199Outbuf *
200evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_Mode swap_mode)
201{
202 Outbuf *ob;
203 char *num;
204 int i = 0;
205
206 /* try to allocate space for outbuf */
207 if (!(ob = calloc(1, sizeof(Outbuf)))) return NULL;
208
209 win_count++;
210
211 ob->w = w;
212 ob->h = h;
213 ob->info = info;
214 ob->depth = info->info.depth;
215 ob->rotation = info->info.rotation;
216 ob->destination_alpha = info->info.destination_alpha;
217 ob->vsync = info->info.vsync;
218 ob->gbm = info->info.gbm;
219 ob->surface = info->info.surface;
220 ob->swap_mode = swap_mode;
221 ob->priv.num = 2;
222
223 if ((num = getenv("EVAS_GL_DRM_BUFFERS")))
224 {
225 ob->priv.num = atoi(num);
226 if (ob->priv.num <= 0) ob->priv.num = 1;
227 else if (ob->priv.num > 4) ob->priv.num = 4;
228 }
229
230 if ((num = getenv("EVAS_GL_DRM_VSYNC")))
231 ob->vsync = atoi(num);
232
233 if (!_evas_outbuf_egl_setup(ob))
234 {
235 evas_outbuf_free(ob);
236 return NULL;
237 }
238
239 for (; i < ob->priv.num; i++)
240 {
241 ob->priv.buffer[i] =
242 ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h);
243 if (!ob->priv.buffer[i]) break;
244
245 DBG("Evas Engine Created Dumb Buffer");
246 DBG("\tFb: %d", ob->priv.buffer[i]->id);
247 DBG("\tHandle: %d", ob->priv.buffer[i]->hdl);
248 DBG("\tStride: %d", ob->priv.buffer[i]->stride);
249 DBG("\tSize: %d", ob->priv.buffer[i]->size);
250 DBG("\tW: %d\tH: %d",
251 ob->priv.buffer[i]->w, ob->priv.buffer[i]->h);
252 }
253
254 ecore_drm_fb_set(info->info.dev, ob->priv.buffer[0]);
255
256 return ob;
257}
258
259void
260evas_outbuf_free(Outbuf *ob)
261{
262 int i = 0, ref = 0;
263
264 win_count--;
265 evas_outbuf_use(ob);
266
267 if (ob == _evas_gl_drm_window) _evas_gl_drm_window = NULL;
268
269 if (ob->gl_context)
270 {
271 ref = ob->gl_context->references - 1;
272 glsym_evas_gl_common_context_free(ob->gl_context);
273 }
274
275 eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
276
277 if (ob->egl.context[0] != context)
278 eglDestroyContext(ob->egl.disp, ob->egl.context[0]);
279
280 if (ob->egl.surface[0] != EGL_NO_SURFACE)
281 eglDestroySurface(ob->egl.disp, ob->egl.surface[0]);
282
283//#if 0
284 if (ob->surface)
285 {
286 gbm_surface_destroy(ob->surface);
287 ob->info->info.surface = NULL;
288 }
289//#endif
290
291 if (ref == 0)
292 {
293 if (context) eglDestroyContext(ob->egl.disp, context);
294 eglTerminate(ob->egl.disp);
295 eglReleaseThread();
296 context = EGL_NO_CONTEXT;
297 }
298
299 for (; i < ob->priv.num; i++)
300 ecore_drm_fb_destroy(ob->priv.buffer[i]);
301
302 free(ob);
303}
304
305void
306evas_outbuf_use(Outbuf *ob)
307{
308 Eina_Bool force = EINA_FALSE;
309
310 glsym_evas_gl_preload_render_lock(_evas_outbuf_make_current, ob);
311
312 if (_evas_gl_drm_window)
313 {
314 if (eglGetCurrentContext() != _evas_gl_drm_window->egl.context[0])
315 force = EINA_TRUE;
316 }
317
318 if ((_evas_gl_drm_window != ob) || (force))
319 {
320 if (_evas_gl_drm_window)
321 {
322 glsym_evas_gl_common_context_use(_evas_gl_drm_window->gl_context);
323 glsym_evas_gl_common_context_flush(_evas_gl_drm_window->gl_context);
324 }
325
326 _evas_gl_drm_window = ob;
327
328 if (ob)
329 {
330 if (ob->egl.surface[0] != EGL_NO_SURFACE)
331 {
332 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0],
333 ob->egl.surface[0],
334 ob->egl.context[0]) == EGL_FALSE)
335 ERR("eglMakeCurrent() failed!");
336 }
337 }
338 }
339
340 if (ob) glsym_evas_gl_common_context_use(ob->gl_context);
341}
342
343void
344evas_outbuf_resurf(Outbuf *ob)
345{
346 if (ob->surf) return;
347 if (getenv("EVAS_GL_INFO")) printf("resurf %p\n", ob);
348
349 ob->egl.surface[0] =
350 eglCreateWindowSurface(ob->egl.disp, ob->egl.config,
351 (EGLNativeWindowType)ob->surface, NULL);
352
353 if (ob->egl.surface[0] == EGL_NO_SURFACE)
354 {
355 ERR("eglCreateWindowSurface() fail for %p. code=%#x",
356 ob->surface, eglGetError());
357 return;
358 }
359
360 if (eglMakeCurrent(ob->egl.disp, ob->egl.surface[0], ob->egl.surface[0],
361 ob->egl.context[0]) == EGL_FALSE)
362 ERR("eglMakeCurrent() failed!");
363
364 ob->surf = EINA_TRUE;
365}
366
367void
368evas_outbuf_unsurf(Outbuf *ob)
369{
370 if (!ob->surf) return;
371 if (!getenv("EVAS_GL_WIN_RESURF")) return;
372 if (getenv("EVAS_GL_INFO")) printf("unsurf %p\n", ob);
373
374 if (_evas_gl_drm_window)
375 glsym_evas_gl_common_context_flush(_evas_gl_drm_window->gl_context);
376 if (_evas_gl_drm_window == ob)
377 {
378 eglMakeCurrent(ob->egl.disp, EGL_NO_SURFACE,
379 EGL_NO_SURFACE, EGL_NO_CONTEXT);
380 if (ob->egl.surface[0] != EGL_NO_SURFACE)
381 eglDestroySurface(ob->egl.disp, ob->egl.surface[0]);
382 ob->egl.surface[0] = EGL_NO_SURFACE;
383
384 _evas_gl_drm_window = NULL;
385 }
386
387 ob->surf = EINA_FALSE;
388}
389
390void
391evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth)
392{
393 int i = 0;
394
395 if (depth == OUTBUF_DEPTH_INHERIT) depth = ob->depth;
396
397 /* check for changes */
398 if ((ob->w == w) && (ob->h == h) &&
399 (ob->destination_alpha == ob->info->info.destination_alpha) &&
400 ((int)ob->rotation == rot) && (ob->depth == depth))
401 return;
402
403 ob->w = w;
404 ob->h = h;
405 ob->depth = depth;
406 ob->rotation = rot;
407
408 /* destroy the old buffers */
409 for (; i < ob->priv.num; i++)
410 ecore_drm_fb_destroy(ob->priv.buffer[i]);
411
412 for (i = 0; i < ob->priv.num; i++)
413 {
414 ob->priv.buffer[i] =
415 ecore_drm_fb_create(ob->info->info.dev, ob->w, ob->h);
416 if (!ob->priv.buffer[i])
417 {
418 ERR("Failed to create buffer %d", i);
419 break;
420 }
421 }
422
423 evas_outbuf_use(ob);
424
425 glsym_evas_gl_common_context_resize(ob->gl_context, w, h, rot);
426
427 //TODO: need drm gbm surface destroy & re-create.?
428}
429
430Render_Engine_Swap_Mode
431evas_outbuf_buffer_state_get(Outbuf *ob)
432{
433 if (ob->swap_mode == MODE_AUTO && _extn_have_buffer_age)
434 {
435 Render_Engine_Swap_Mode swap_mode;
436 EGLint age = 0;
437
438 if (!eglQuerySurface(ob->egl.disp, ob->egl.surface[0],
439 EGL_BUFFER_AGE_EXT, &age))
440 age = 0;
441
442 if (age == 1) swap_mode = MODE_COPY;
443 else if (age == 2) swap_mode = MODE_DOUBLE;
444 else if (age == 3) swap_mode = MODE_TRIPLE;
445 else if (age == 4) swap_mode = MODE_QUADRUPLE;
446 else swap_mode = MODE_FULL;
447 if ((int)age != ob->priv.prev_age) swap_mode = MODE_FULL;
448 ob->priv.prev_age = age;
449
450 return swap_mode;
451 }
452
453 return ob->swap_mode;
454}
455
456int
457evas_outbuf_rot_get(Outbuf *ob)
458{
459 return ob->rotation;
460}
461
462Eina_Bool
463evas_outbuf_update_region_first_rect(Outbuf *ob)
464{
465 ob->gl_context->preserve_bit = GL_COLOR_BUFFER_BIT0_QCOM;
466
467 glsym_evas_gl_preload_render_lock(_evas_outbuf_make_current, ob);
468 evas_outbuf_use(ob);
469
470 if (!_re_wincheck(ob)) return EINA_TRUE;
471
472 glsym_evas_gl_common_context_resize(ob->gl_context, ob->w, ob->h, ob->rotation);
473 glsym_evas_gl_common_context_flush(ob->gl_context);
474 glsym_evas_gl_common_context_newframe(ob->gl_context);
475
476 return EINA_FALSE;
477}
478
479void *
480evas_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)
481{
482 if ((w == ob->w) && (h == ob->h))
483 ob->gl_context->master_clip.enabled = EINA_FALSE;
484 else
485 {
486 ob->gl_context->master_clip.enabled = EINA_TRUE;
487 ob->gl_context->master_clip.x = x;
488 ob->gl_context->master_clip.y = y;
489 ob->gl_context->master_clip.w = w;
490 ob->gl_context->master_clip.h = h;
491 }
492
493 return ob->gl_context->def_surface;
494}
495
496void
497evas_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)
498{
499 /* Is it really necessary to flush per region ? Shouldn't we be able to
500 still do that for the full canvas when doing partial update */
501 if (!_re_wincheck(ob)) return;
502 ob->drew = EINA_TRUE;
503 glsym_evas_gl_common_context_flush(ob->gl_context);
504}
505
506void
507evas_outbuf_update_region_free(Outbuf *ob EINA_UNUSED, RGBA_Image *update EINA_UNUSED)
508{
509 /* Nothing to do here as we don't really create an image per area */
510}
511
512void
513evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects EINA_UNUSED, Evas_Render_Mode render_mode)
514{
515 if (render_mode == EVAS_RENDER_MODE_ASYNC_INIT) goto end;
516
517 if (!_re_wincheck(ob)) goto end;
518 if (!ob->drew) goto end;
519
520 ob->drew = EINA_FALSE;
521 evas_outbuf_use(ob);
522 glsym_evas_gl_common_context_done(ob->gl_context);
523
524 if (!ob->vsync)
525 {
526 if (ob->info->info.vsync) eglSwapInterval(ob->egl.disp, 1);
527 else eglSwapInterval(ob->egl.disp, 0);
528 ob->vsync = 1;
529 }
530
531 /* if (ob->info->callback.pre_swap) */
532 /* ob->info->callback.pre_swap(ob->info->callback.data, ob->evas); */
533
534// TODO: Check eglSwapBuffersWithDamage for gl_drm and apply
535#if 0
536 if ((glsym_eglSwapBuffersWithDamage) && (ob->swap_mode != MODE_FULL))
537 {
538 EGLint num = 0, *result = NULL, i = 0;
539 Tilebuf_Rect *r;
540
541 // if partial swaps can be done use re->rects
542 num = eina_inlist_count(EINA_INLIST_GET(rects));
543 if (num > 0)
544 {
545 result = alloca(sizeof(EGLint) * 4 * num);
546 EINA_INLIST_FOREACH(EINA_INLIST_GET(rects), r)
547 {
548 int gw, gh;
549
550 gw = ob->gl_context->w;
551 gh = ob->gl_context->h;
552 switch (ob->rot)
553 {
554 case 0:
555 result[i + 0] = r->x;
556 result[i + 1] = gh - (r->y + r->h);
557 result[i + 2] = r->w;
558 result[i + 3] = r->h;
559 break;
560 case 90:
561 result[i + 0] = r->y;
562 result[i + 1] = r->x;
563 result[i + 2] = r->h;
564 result[i + 3] = r->w;
565 break;
566 case 180:
567 result[i + 0] = gw - (r->x + r->w);
568 result[i + 1] = r->y;
569 result[i + 2] = r->w;
570 result[i + 3] = r->h;
571 break;
572 case 270:
573 result[i + 0] = gh - (r->y + r->h);
574 result[i + 1] = gw - (r->x + r->w);
575 result[i + 2] = r->h;
576 result[i + 3] = r->w;
577 break;
578 default:
579 result[i + 0] = r->x;
580 result[i + 1] = gh - (r->y + r->h);
581 result[i + 2] = r->w;
582 result[i + 3] = r->h;
583 break;
584 }
585 i += 4;
586 }
587 glsym_eglSwapBuffersWithDamage(ob->egl.disp, ob->egl.surface[0],
588 result, num);
589 }
590 }
591 else
592#endif
593 eglSwapBuffers(ob->egl.disp, ob->egl.surface[0]);
594
595 /* if (ob->info->callback.post_swap) */
596 /* ob->info->callback.post_swap(ob->info->callback.data, ob->evas); */
597
598 //Flush GL Surface data to Framebuffer
599 _evas_outbuf_buffer_swap(ob, NULL, 0);
600
601 ob->priv.frame_cnt++;
602
603 end:
604 //TODO: Need render unlock after drm page flip?
605 glsym_evas_gl_preload_render_unlock(_evas_outbuf_make_current, ob);
606}
607
608Evas_Engine_GL_Context *
609evas_outbuf_gl_context_get(Outbuf *ob)
610{
611 return ob->gl_context;
612}
613
614void *
615evas_outbuf_egl_display_get(Outbuf *ob)
616{
617 return ob->egl.disp;
618}
619
620Context_3D *
621evas_outbuf_gl_context_new(Outbuf *ob)
622{
623 Context_3D *ctx;
624 int context_attrs[3] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
625
626 if (!ob) return NULL;
627
628 ctx = calloc(1, sizeof(Context_3D));
629 if (!ctx) return NULL;
630
631 ctx->context = eglCreateContext(ob->egl.disp, ob->egl.config,
632 ob->egl.context[0], context_attrs);
633
634 if (!ctx->context)
635 {
636 ERR("EGL context creation failed.");
637 goto error;
638 }
639
640 ctx->display = ob->egl.disp;
641 ctx->surface = ob->egl.surface[0];
642
643 return ctx;
644
645error:
646 free(ctx);
647 return NULL;
648}
649
650void
651evas_outbuf_gl_context_use(Context_3D *ctx)
652{
653 if (eglMakeCurrent(ctx->display, ctx->surface,
654 ctx->surface, ctx->context) == EGL_FALSE)
655 ERR("eglMakeCurrent() failed.");
656}