From 2c56305918f2cb03342e5d62bc7078528f7e6bb1 Mon Sep 17 00:00:00 2001 From: Changyeon Lee Date: Wed, 23 Jun 2021 19:48:49 +0900 Subject: [PATCH] wayland_egl: use LINUX_DMA_BUF_EXT when EGLImage is created with tbm_surface It is possible gl driver doesn't support EGL_TIZEN_image_native_surface. but if gl dirver support EGL_EXT_image_dma_buf_import, we can use it instead of EGL_TIZEN_image_native_surface. This patch try to use EGL_EXT_image_dma_buf_import extension if EGL_TIZEN_image_native_surface extension isn't supported when eglImage is created with tbm_surface. Change-Id: Ia779101d32448d966343034495dad899574f8552 --- src/modules/evas/engines/wayland_egl/evas_engine.c | 163 ++++++++++++++++++++- 1 file changed, 157 insertions(+), 6 deletions(-) diff --git a/src/modules/evas/engines/wayland_egl/evas_engine.c b/src/modules/evas/engines/wayland_egl/evas_engine.c index b5749e2..decbef9 100755 --- a/src/modules/evas/engines/wayland_egl/evas_engine.c +++ b/src/modules/evas/engines/wayland_egl/evas_engine.c @@ -3,6 +3,8 @@ #include "../gl_common/evas_gl_define.h" #include "../software_generic/evas_native_common.h" +#include + #ifdef HAVE_DLSYM # include #endif @@ -20,6 +22,47 @@ # define EGL_Y_INVERTED_NOK 0x307F #endif +#ifndef DRM_FORMAT_MOD_LINEAR +# define DRM_FORMAT_MOD_LINEAR 0 +#endif +#ifndef DRM_FORMAT_MOD_INVALID +# define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1) +#endif + +#ifndef EGL_DMA_BUF_PLANE3_FD_EXT +# define EGL_DMA_BUF_PLANE3_FD_EXT 0x3440 +#endif +#ifndef EGL_DMA_BUF_PLANE3_OFFSET_EXT +# define EGL_DMA_BUF_PLANE3_OFFSET_EXT 0x3441 +#endif +#ifndef EGL_DMA_BUF_PLANE3_PITCH_EXT +# define EGL_DMA_BUF_PLANE3_PITCH_EXT 0x3442 +#endif +#ifndef EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT +# define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 +#endif +#ifndef EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT +# define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 +#endif +#ifndef EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT +# define EGL_DMA_BUF_PLANE1_MODIFIER_LO_EXT 0x3445 +#endif +#ifndef EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT +# define EGL_DMA_BUF_PLANE1_MODIFIER_HI_EXT 0x3446 +#endif +#ifndef EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT +# define EGL_DMA_BUF_PLANE2_MODIFIER_LO_EXT 0x3447 +#endif +#ifndef EGL_DMA_BUF_PLANE2_MODIFIER_HIa_EXT +# define EGL_DMA_BUF_PLANE2_MODIFIER_HI_EXT 0x3448 +#endif +#ifndef EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT +# define EGL_DMA_BUF_PLANE3_MODIFIER_LO_EXT 0x3449 +#endif +#ifndef EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT +# define EGL_DMA_BUF_PLANE3_MODIFIER_HI_EXT 0x344A +#endif + /* local structures */ typedef struct _Render_Engine Render_Engine; struct _Render_Engine @@ -34,6 +77,9 @@ typedef int (*glsym_func_int) (); typedef EGLBoolean (*glsym_func_bool) (); typedef unsigned int (*glsym_func_uint) (); typedef const char *(*glsym_func_const_char_ptr) (); +typedef void (*secsym_func_void) (); +typedef void *(*secsym_func_void_ptr) (); +typedef int (*secsym_func_int) (); Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL; Evas_GL_Common_Image_Call glsym_evas_gl_common_image_unref = NULL; @@ -93,6 +139,17 @@ Eina_Bool partial_render = EINA_TRUE; //enable/disable partial render o unsigned int (*glsym_prev_eglSwapBuffersWithDamage) (EGLDisplay a, void *b, const EGLint *d, EGLint c) = NULL; unsigned int (*glsym_prev_eglSetDamageRegionKHR) (EGLDisplay a, EGLSurface b, EGLint *c, EGLint d) = NULL; +static Eina_Bool has_tizen_native_surface = EINA_TRUE; +static Eina_Bool has_dma_buf_import = EINA_TRUE; + +static void *tbm_lib_handle; + +void *(*secsym_tbm_surface_internal_get_bo) (void *surface, int bo_idx) = NULL; +int (*secsym_tbm_surface_internal_get_plane_bo_idx) (void *surface, int plane_idx) = NULL; +int (*secsym_tbm_surface_internal_get_num_planes) (unsigned int format) = NULL; +int (*secsym_tbm_bo_get_handle) (void *bo, int device) = NULL; +int (*secsym_tbm_surface_get_info) (void *surface, void *info) = NULL; + /* local functions */ static inline Outbuf * eng_get_ob(Render_Engine *re) @@ -191,11 +248,45 @@ eng_gl_symbols(EGLDisplay edsp) FINDSYM(glsym_eglCreateSyncKHR, "eglCreateSyncKHR", glsym_func_void_ptr); FINDSYM(glsym_eglDestroySyncKHR, "eglDestroySyncKHR", glsym_func_bool); FINDSYM(glsym_eglWaitSyncKHR, "eglWaitSyncKHR", glsym_func_int); +#undef FINDSYM done = EINA_TRUE; } static void +tbm_symbols(void) +{ + static Eina_Bool tbm_sym_done = EINA_FALSE; + if (tbm_sym_done) return; + tbm_sym_done = EINA_TRUE; + +#ifdef GL_GLES + tbm_lib_handle = dlopen("libtbm.so.1", RTLD_NOW); + if (!tbm_lib_handle) + { + DBG("Unable to open libtbm: %s", dlerror()); + return; + } + +#define FINDSYM(dst, sym, typ) \ + if (!dst) dst = (typ)dlsym(tbm_lib_handle, sym); \ + if (!dst) \ + { \ + ERR("Symbol not found %s\n", sym); \ + return; \ + } + + FINDSYM(secsym_tbm_surface_internal_get_bo, "tbm_surface_internal_get_bo", secsym_func_void_ptr); + FINDSYM(secsym_tbm_surface_internal_get_plane_bo_idx, "tbm_surface_internal_get_plane_bo_idx", secsym_func_int); + FINDSYM(secsym_tbm_surface_internal_get_num_planes, "tbm_surface_internal_get_num_planes", secsym_func_int); + FINDSYM(secsym_tbm_bo_get_handle, "tbm_bo_get_handle", secsym_func_int); + FINDSYM(secsym_tbm_surface_get_info, "tbm_surface_get_info", secsym_func_int); + +#undef FINDSYM +#endif +} + +static void gl_extn_veto(Render_Engine *re) { const char *str = NULL; @@ -253,6 +344,11 @@ gl_extn_veto(Render_Engine *re) if (strstr(str, "EGL_TIZEN_image_native_surface")) { eng_get_ob(re)->gl_context->shared->info.egl_tbm_ext = 1; + has_tizen_native_surface = EINA_TRUE; + } + if (strstr(str, "EGL_EXT_image_dma_buf_import")) + { + has_dma_buf_import = EINA_TRUE; } } else @@ -1793,12 +1889,66 @@ eng_image_native_set(void *engine, void *image, void *native) n->ns_data.tbm.buffer = buffer; if (glsym_evas_gl_common_eglDestroyImage) - n->ns_data.tbm.surface = - glsym_evas_gl_common_eglCreateImage(ob->egl_disp, - EGL_NO_CONTEXT, - EGL_NATIVE_SURFACE_TIZEN, - (void *)buffer, - NULL); + { + if (has_tizen_native_surface) + { + n->ns_data.tbm.surface = glsym_evas_gl_common_eglCreateImage(ob->egl_disp, + EGL_NO_CONTEXT, + EGL_NATIVE_SURFACE_TIZEN, + (void *)buffer, + NULL); + } + else if (has_dma_buf_import) + { + tbm_surface_info_s info = {0, }; + EGLint attribs[50]; + int atti = 0; + tbm_bo tbo = NULL; + int bo_idx, num_planes, i; + int plane_fd_ext[4] = {EGL_DMA_BUF_PLANE0_FD_EXT, + EGL_DMA_BUF_PLANE1_FD_EXT, + EGL_DMA_BUF_PLANE2_FD_EXT, + EGL_DMA_BUF_PLANE3_FD_EXT}; + int plane_offset_ext[4] = {EGL_DMA_BUF_PLANE0_OFFSET_EXT, + EGL_DMA_BUF_PLANE1_OFFSET_EXT, + EGL_DMA_BUF_PLANE2_OFFSET_EXT, + EGL_DMA_BUF_PLANE3_OFFSET_EXT}; + int plane_pitch_ext[4] = {EGL_DMA_BUF_PLANE0_PITCH_EXT, + EGL_DMA_BUF_PLANE1_PITCH_EXT, + EGL_DMA_BUF_PLANE2_PITCH_EXT, + EGL_DMA_BUF_PLANE3_PITCH_EXT}; + + secsym_tbm_surface_get_info(buffer, &info); + + attribs[atti++] = EGL_WIDTH; + attribs[atti++] = info.width; + attribs[atti++] = EGL_HEIGHT; + attribs[atti++] = info.height; + attribs[atti++] = EGL_LINUX_DRM_FOURCC_EXT; + attribs[atti++] = info.format; + + num_planes = secsym_tbm_surface_internal_get_num_planes(info.format); + for (i = 0; i < num_planes; i++) + { + bo_idx = secsym_tbm_surface_internal_get_plane_bo_idx(buffer, i); + tbo = secsym_tbm_surface_internal_get_bo(buffer, bo_idx); + attribs[atti++] = plane_fd_ext[i]; + attribs[atti++] = secsym_tbm_bo_get_handle(tbo, TBM_DEVICE_3D); + attribs[atti++] = plane_offset_ext[i]; + attribs[atti++] = info.planes[i].offset; + attribs[atti++] = plane_pitch_ext[i]; + attribs[atti++] = info.planes[i].stride; + } + + attribs[atti++] = EGL_NONE; + + n->ns_data.tbm.surface = glsym_evas_gl_common_eglCreateImage(ob->egl_disp, + EGL_NO_CONTEXT, + EGL_LINUX_DMA_BUF_EXT, + NULL, + attribs); + } + } else ERR("Try eglCreateImage on EGL with no support"); if (!n->ns_data.tbm.surface) @@ -1899,6 +2049,7 @@ module_open(Evas_Module *em) // evas_gl_thread_link_init(); symbols(); + tbm_symbols(); /* advertise out which functions we support */ em->functions = (void *)(&func); -- 2.7.4