#include "../gl_common/evas_gl_define.h"
#include "../software_generic/evas_native_common.h"
+#include <tbm_bufmgr.h>
+
#ifdef HAVE_DLSYM
# include <dlfcn.h>
#endif
# 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
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;
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)
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;
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
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)
//
evas_gl_thread_link_init();
symbols();
+ tbm_symbols();
/* advertise out which functions we support */
em->functions = (void *)(&func);