diff options
author | Chris Michael <cp.michael@samsung.com> | 2015-06-03 12:56:35 -0400 |
---|---|---|
committer | Chris Michael <cp.michael@samsung.com> | 2015-06-05 10:00:44 -0400 |
commit | ee593050f1674f29a99156f135c92f43cb5897e2 (patch) | |
tree | 2b9640cee9900f7700f789887f28df679cb00f32 | |
parent | 58dbb63ba4bbc235477793b016ba31d2bf17d1fb (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>
-rw-r--r-- | src/Makefile_Evas.am | 3 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h | 36 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_engine.c | 668 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_engine.h | 128 | ||||
-rw-r--r-- | src/modules/evas/engines/gl_drm/evas_outbuf.c | 656 |
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 | |||
1199 | if BUILD_ENGINE_GL_DRM | 1199 | if BUILD_ENGINE_GL_DRM |
1200 | dist_installed_evasmainheaders_DATA += modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h | 1200 | dist_installed_evasmainheaders_DATA += modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h |
1201 | GL_DRM_SOURCES = \ | 1201 | GL_DRM_SOURCES = \ |
1202 | modules/evas/engines/gl_drm/evas_drm.c \ | 1202 | modules/evas/engines/gl_drm/evas_outbuf.c \ |
1203 | modules/evas/engines/gl_drm/evas_drm_main.c \ | ||
1204 | modules/evas/engines/gl_drm/evas_engine.c \ | 1203 | modules/evas/engines/gl_drm/evas_engine.c \ |
1205 | modules/evas/engines/gl_drm/evas_engine.h \ | 1204 | modules/evas/engines/gl_drm/evas_engine.h \ |
1206 | modules/evas/engines/gl_drm/Evas_Engine_GL_Drm.h | 1205 | modules/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 | |||
7 | typedef struct _Evas_Engine_Info_GL_Drm Evas_Engine_Info_GL_Drm; | ||
8 | |||
9 | struct _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 */ |
25 | int _evas_engine_gl_drm_log_dom = -1; | 21 | int _evas_engine_gl_drm_log_dom = -1; |
26 | int extn_have_buffer_age = 1; | 22 | int _extn_have_buffer_age = 1; |
23 | |||
24 | /* local variables */ | ||
25 | static Eina_Bool initted = EINA_FALSE; | ||
26 | static int gl_wins = 0; | ||
27 | |||
28 | /* local structures */ | ||
29 | typedef struct _Render_Engine Render_Engine; | ||
30 | struct _Render_Engine | ||
31 | { | ||
32 | Render_Engine_GL_Generic generic; | ||
33 | }; | ||
34 | |||
35 | typedef struct _Native Native; | ||
36 | struct _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 */ |
29 | Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL; | 44 | Evas_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; | |||
50 | Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL; | 65 | Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock = NULL; |
51 | Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL; | 66 | Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_relax = NULL; |
52 | 67 | ||
53 | /* local structures */ | ||
54 | typedef struct _Render_Engine Render_Engine; | ||
55 | struct _Render_Engine | ||
56 | { | ||
57 | Render_Engine_GL_Generic generic; | ||
58 | }; | ||
59 | |||
60 | typedef struct _Native Native; | ||
61 | struct _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 */ |
69 | typedef void (*_eng_fn) (void); | 69 | typedef void (*_eng_fn)(void); |
70 | typedef _eng_fn (*glsym_func_eng_fn) (); | 70 | typedef _eng_fn (*glsym_func_eng_fn)(); |
71 | typedef void (*glsym_func_void) (); | 71 | typedef void (*glsym_func_void)(); |
72 | typedef void *(*glsym_func_void_ptr) (); | 72 | typedef void *(*glsym_func_void_ptr)(); |
73 | typedef int (*glsym_func_int) (); | 73 | typedef int (*glsym_func_int)(); |
74 | typedef unsigned int (*glsym_func_uint) (); | 74 | typedef unsigned int (*glsym_func_uint)(); |
75 | typedef const char *(*glsym_func_const_char_ptr) (); | 75 | typedef 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); | |||
99 | static void *evgl_eng_proc_address_get(const char *name); | 99 | static void *evgl_eng_proc_address_get(const char *name); |
100 | static int evgl_eng_rotation_angle_get(void *data); | 100 | static int evgl_eng_rotation_angle_get(void *data); |
101 | 101 | ||
102 | static void _re_winfree(Render_Engine *re); | ||
103 | |||
104 | /* local variables */ | ||
105 | static Eina_Bool initted = EINA_FALSE; | ||
106 | static int gl_wins = 0; | ||
107 | |||
108 | /* local inline functions */ | ||
109 | static inline Outbuf * | ||
110 | eng_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) */ |
116 | static Evas_Func func, pfunc; | 103 | static Evas_Func func, pfunc; |
117 | static const EVGL_Interface evgl_funcs = | 104 | static 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 */ | ||
127 | static inline Outbuf * | ||
128 | eng_get_ob(Render_Engine *re) | ||
129 | { | ||
130 | return re->generic.software.ob; | ||
131 | } | ||
132 | |||
139 | /* local functions */ | 133 | /* local functions */ |
140 | static void | 134 | static void |
141 | gl_symbols(void) | 135 | gl_symbols(void) |
@@ -215,36 +209,38 @@ static void | |||
215 | gl_extn_veto(Render_Engine *re) | 209 | gl_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 | ||
243 | static void * | 238 | static void * |
244 | evgl_eng_display_get(void *data) | 239 | evgl_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) | |||
260 | static void * | 256 | static void * |
261 | evgl_eng_evas_surface_get(void *data) | 257 | evgl_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) | |||
277 | static int | 274 | static int |
278 | evgl_eng_make_current(void *data, void *surface, void *context, int flush) | 275 | evgl_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) | |||
325 | static void * | 324 | static void * |
326 | evgl_eng_native_window_create(void *data) | 325 | evgl_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 | ||
353 | static int | 356 | static 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 | ||
374 | static void * | 377 | static void * |
375 | evgl_eng_window_surface_create(void *data, void *native_window) | 378 | evgl_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 | ||
400 | static int | 404 | static int |
401 | evgl_eng_window_surface_destroy(void *data, void *surface) | 405 | evgl_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) | |||
424 | static void * | 429 | static void * |
425 | evgl_eng_context_create(void *data, void *share_ctx, Evas_GL_Context_Version version) | 430 | evgl_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 | ||
472 | static int | 478 | static int |
473 | evgl_eng_context_destroy(void *data, void *context) | 479 | evgl_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) | |||
490 | static const char * | 498 | static const char * |
491 | evgl_eng_string_get(void *data) | 499 | evgl_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 | ||
504 | static void * | 513 | static void * |
@@ -511,8 +520,9 @@ evgl_eng_proc_address_get(const char *name) | |||
511 | static int | 520 | static int |
512 | evgl_eng_rotation_angle_get(void *data) | 521 | evgl_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 | ||
541 | static Eina_Bool | ||
542 | eng_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 | |||
531 | static void | 565 | static 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 | |||
574 | static 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 | |||
601 | static 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 | |||
618 | static 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 | |||
664 | static Eina_Bool | ||
665 | eng_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 | |||
692 | static Eina_Bool | ||
693 | eng_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 | ||
565 | static int | 736 | static int |
566 | eng_setup(Evas *eo_e, void *in) | 737 | eng_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 | ||
826 | Eina_Bool | ||
827 | eng_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 | |||
847 | static Eina_Bool | 963 | static Eina_Bool |
848 | eng_canvas_alpha_get(void *data, void *info EINA_UNUSED) | 964 | eng_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 | ||
857 | static void | 974 | static 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 | ||
870 | static 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 | |||
899 | static 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 | |||
918 | static 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 | |||
965 | static void * | 988 | static void * |
966 | eng_image_native_set(void *data, void *image, void *native) | 989 | eng_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 */ |
1178 | static int | 1209 | static int |
1179 | module_open(Evas_Module *em) | 1210 | module_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 | ||
1231 | static Evas_Module_Api evas_modapi = | 1263 | static 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 | |||
18 | extern int _evas_engine_gl_drm_log_dom; | ||
19 | extern 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 | |||
46 | extern Evas_GL_Common_Context_New glsym_evas_gl_common_context_new; | ||
47 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_flush; | ||
48 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_free; | ||
49 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_use; | ||
50 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_newframe; | ||
51 | extern Evas_GL_Common_Context_Call glsym_evas_gl_common_context_done; | ||
52 | extern Evas_GL_Common_Context_Resize_Call glsym_evas_gl_common_context_resize; | ||
53 | extern Evas_GL_Common_Buffer_Dump_Call glsym_evas_gl_common_buffer_dump; | ||
54 | extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_lock; | ||
55 | extern Evas_GL_Preload_Render_Call glsym_evas_gl_preload_render_unlock; | ||
56 | |||
57 | struct _Context_3D | ||
58 | { | ||
59 | EGLDisplay display; | ||
60 | EGLContext context; | ||
61 | EGLSurface surface; | ||
62 | }; | ||
63 | |||
64 | struct _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 | |||
100 | Outbuf *evas_outbuf_new(Evas_Engine_Info_GL_Drm *info, int w, int h, Render_Engine_Swap_Mode swap_mode); | ||
101 | void evas_outbuf_free(Outbuf *ob); | ||
102 | void evas_outbuf_use(Outbuf *ob); | ||
103 | void evas_outbuf_resurf(Outbuf *ob); | ||
104 | void evas_outbuf_unsurf(Outbuf *ob); | ||
105 | void evas_outbuf_reconfigure(Outbuf *ob, int w, int h, int rot, Outbuf_Depth depth); | ||
106 | Render_Engine_Swap_Mode evas_outbuf_buffer_state_get(Outbuf *ob); | ||
107 | int evas_outbuf_rot_get(Outbuf *ob); | ||
108 | Eina_Bool evas_outbuf_update_region_first_rect(Outbuf *ob); | ||
109 | void *evas_outbuf_update_region_new(Outbuf *ob, int x, int y, int w, int h, int *cx, int *cy, int *cw, int *ch); | ||
110 | void evas_outbuf_update_region_push(Outbuf *ob, RGBA_Image *update, int x, int y, int w, int h); | ||
111 | void evas_outbuf_update_region_free(Outbuf *ob, RGBA_Image *update); | ||
112 | void evas_outbuf_flush(Outbuf *ob, Tilebuf_Rect *rects, Evas_Render_Mode render_mode); | ||
113 | Evas_Engine_GL_Context* evas_outbuf_gl_context_get(Outbuf *ob); | ||
114 | void *evas_outbuf_egl_display_get(Outbuf *ob); | ||
115 | Context_3D *evas_outbuf_gl_context_new(Outbuf *ob); | ||
116 | void evas_outbuf_gl_context_use(Context_3D *ctx); | ||
117 | |||
118 | static 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 */ | ||
4 | static Outbuf *_evas_gl_drm_window = NULL; | ||
5 | static EGLContext context = EGL_NO_CONTEXT; | ||
6 | static int win_count = 0; | ||
7 | |||
8 | static 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 | |||
26 | static 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 | |||
40 | static 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 | |||
63 | static 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 | |||
199 | Outbuf * | ||
200 | evas_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 | |||
259 | void | ||
260 | evas_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 | |||
305 | void | ||
306 | evas_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 | |||
343 | void | ||
344 | evas_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 | |||
367 | void | ||
368 | evas_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 | |||
390 | void | ||
391 | evas_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 | |||
430 | Render_Engine_Swap_Mode | ||
431 | evas_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 | |||
456 | int | ||
457 | evas_outbuf_rot_get(Outbuf *ob) | ||
458 | { | ||
459 | return ob->rotation; | ||
460 | } | ||
461 | |||
462 | Eina_Bool | ||
463 | evas_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 | |||
479 | void * | ||
480 | evas_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 | |||
496 | void | ||
497 | evas_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 | |||
506 | void | ||
507 | evas_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 | |||
512 | void | ||
513 | evas_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 | |||
608 | Evas_Engine_GL_Context * | ||
609 | evas_outbuf_gl_context_get(Outbuf *ob) | ||
610 | { | ||
611 | return ob->gl_context; | ||
612 | } | ||
613 | |||
614 | void * | ||
615 | evas_outbuf_egl_display_get(Outbuf *ob) | ||
616 | { | ||
617 | return ob->egl.disp; | ||
618 | } | ||
619 | |||
620 | Context_3D * | ||
621 | evas_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 | |||
645 | error: | ||
646 | free(ctx); | ||
647 | return NULL; | ||
648 | } | ||
649 | |||
650 | void | ||
651 | evas_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 | } | ||