gl_tbm: use LINUX_DMA_BUF_EXT when EGLImage is created with tbm_surface 51/260551/9
authorChangyeon Lee <cyeon.lee@samsung.com>
Tue, 18 May 2021 08:41:14 +0000 (17:41 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Thu, 12 Aug 2021 06:27:24 +0000 (15:27 +0900)
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: Ie1c2c98ec1db14d46149911343aec55095f35853

src/modules/evas/engines/gl_tbm/evas_engine.c

index c250783..115a80c 100755 (executable)
 # 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
+
 // TODO : Fix to conflict tbm reference data and struct next time.
 #define __tbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \
                   ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24))
@@ -46,6 +87,7 @@ 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) ();
 
 /* external dynamic loaded Evas_GL function pointers */
 Evas_GL_Common_Image_Call glsym_evas_gl_common_image_ref = NULL;
@@ -100,6 +142,11 @@ static void *tbm_lib_handle;
 void *(*secsym_tbm_surface_queue_create) (int queue_size, int width,
                                           int height, int format, int flags) = NULL;
 void (*secsym_tbm_surface_queue_destroy) (void *surface_queue) = NULL;
+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 variables */
@@ -108,6 +155,9 @@ static int gl_wins = 0;
 static Evas_Func func, pfunc;
 static Eina_Bool useHash = EINA_FALSE;
 
+static Eina_Bool has_tizen_native_surface = EINA_TRUE;
+static Eina_Bool has_dma_buf_import = EINA_TRUE;
+
 /* external variables */
 int _evas_engine_gl_tbm_log_dom = -1;
 Eina_Bool support_partial_render = EINA_TRUE;
@@ -268,6 +318,11 @@ tbm_symbols(void)
 
    FINDSYM(secsym_tbm_surface_queue_create, "tbm_surface_queue_create", secsym_func_void_ptr);
    FINDSYM(secsym_tbm_surface_queue_destroy, "tbm_surface_queue_destroy", secsym_func_void);
+   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
@@ -334,6 +389,14 @@ gl_extn_veto(Render_Engine *re)
           {
              glsym_eglSwapBuffersWithDamage = NULL;
           }
+        if (!strstr(str, "EGL_TIZEN_image_native_surface"))
+          {
+             has_tizen_native_surface = EINA_FALSE;
+          }
+        if (!strstr(str, "EGL_EXT_image_dma_buf_import"))
+          {
+             has_dma_buf_import = EINA_FALSE;
+          }
      }
    else
      {
@@ -1770,11 +1833,66 @@ eng_image_native_set(void *engine, void *image, void *native)
                n->ns_data.tbm.buffer = buffer;
 
                if (glsym_eglCreateImage)
-                 n->ns_data.tbm.surface = glsym_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_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_eglCreateImage(ob->egl_disp,
+                                                                       EGL_NO_CONTEXT,
+                                                                       EGL_LINUX_DMA_BUF_EXT,
+                                                                       NULL,
+                                                                       attribs);
+                      }
+                 }
                else
                  {
                     ERR("Try eglCreateImage on EGL with no support");