add e_egl_sync for using EGLSyncKHR 99/237899/6
authorChangyeon Lee <cyeon.lee@samsung.com>
Wed, 1 Jul 2020 10:10:51 +0000 (19:10 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Wed, 8 Jul 2020 08:09:36 +0000 (17:09 +0900)
Change-Id: Ibbbbecfaca2830fbcd0cf8fd55ff802003ef8c50

configure.ac
packaging/enlightenment.spec
src/bin/Makefile.mk
src/bin/e_comp_screen.c
src/bin/e_egl_sync.c [new file with mode: 0644]
src/bin/e_egl_sync.h [new file with mode: 0644]
src/bin/e_includes.h

index f9ae583..235db3e 100755 (executable)
@@ -482,6 +482,9 @@ AM_CONDITIONAL([HAVE_HWC], [test "x${have_hwc}" = "xyes"])
 #pixman
 PKG_CHECK_MODULES([PIXMAN], [pixman-1])
 
+#egl
+PKG_CHECK_MODULES([EGL], [egl])
+
 # Check for systemd
 want_systemd="yes"
 AC_ARG_ENABLE([systemd],
index 289b02c..e79a82e 100644 (file)
@@ -54,6 +54,7 @@ BuildRequires:  pkgconfig(pixman-1)
 BuildRequires:  systemd-devel
 BuildRequires:  pkgconfig(libinput)
 BuildRequires:  pkgconfig(presentation-time-server)
+BuildRequires:  pkgconfig(egl)
 BuildRequires:  pkgconfig(tizen-hwc-server)
 Requires:       libwayland-extension-server
 
index c8cca4d..8c826de 100644 (file)
@@ -97,6 +97,7 @@ src/bin/e_hwc_planes.h \
 src/bin/e_hwc_windows.h \
 src/bin/e_hwc_window.h \
 src/bin/e_hwc_window_queue.h \
+src/bin/e_egl_sync.h \
 src/bin/e_info_server_input.h
 
 if HAVE_WAYLAND_TBM
@@ -219,6 +220,7 @@ src/bin/e_hwc_planes.c \
 src/bin/e_hwc_windows.c \
 src/bin/e_hwc_window.c \
 src/bin/e_hwc_window_queue.c \
+src/bin/e_egl_sync.c \
 src/bin/e_info_server_input.c \
 $(ENLIGHTENMENTHEADERS)
 
@@ -289,7 +291,7 @@ src/bin/e_devicemgr_inputgen.c \
 src/bin/e_devicemgr_wl.c \
 src/bin/e_msg.c
 
-src_bin_enlightenment_CPPFLAGS = $(E_CPPFLAGS) -DEFL_BETA_API_SUPPORT -DEFL_EO_API_SUPPORT -DE_LOGGING=2 @WAYLAND_CFLAGS@ $(TTRACE_CFLAGS) $(DLOG_CFLAGS) $(PIXMAN_CFLAGS) $(POLICY_CFLAGS)
+src_bin_enlightenment_CPPFLAGS = $(E_CPPFLAGS) -DEFL_BETA_API_SUPPORT -DEFL_EO_API_SUPPORT -DE_LOGGING=2 @WAYLAND_CFLAGS@ $(TTRACE_CFLAGS) $(DLOG_CFLAGS) $(PIXMAN_CFLAGS) $(POLICY_CFLAGS) $(EGL_CFLAGS)
 if HAVE_LIBGOMP
 src_bin_enlightenment_CPPFLAGS += -fopenmp
 endif
@@ -312,7 +314,7 @@ src_bin_enlightenment_LDFLAGS = -export-dynamic
 if HAVE_LIBGOMP
 src_bin_enlightenment_LDFLAGS += -fopenmp
 endif
-src_bin_enlightenment_LDADD = @e_libs@ @dlopen_libs@ @cf_libs@ @VALGRIND_LIBS@ @WAYLAND_LIBS@ -lm @SHM_OPEN_LIBS@ $(TTRACE_LIBS) $(DLOG_LIBS) $(PIXMAN_LIBS) $(POLICY_LIBS)
+src_bin_enlightenment_LDADD = @e_libs@ @dlopen_libs@ @cf_libs@ @VALGRIND_LIBS@ @WAYLAND_LIBS@ -lm @SHM_OPEN_LIBS@ $(TTRACE_LIBS) $(DLOG_LIBS) $(PIXMAN_LIBS) $(POLICY_LIBS) $(EGL_LIBS)
 if HAVE_WAYLAND_TBM
 src_bin_enlightenment_LDADD += @WAYLAND_TBM_LIBS@
 endif
index 22f0c40..cc857b5 100644 (file)
@@ -653,6 +653,7 @@ _e_comp_screen_deinit_outputs(E_Comp_Screen *e_comp_screen)
         e_output_del(output);
      }
 
+   e_egl_sync_deinit();
    e_hwc_deinit();
    e_hwc_windows_deinit();
    e_hwc_planes_deinit();
@@ -1101,6 +1102,11 @@ e_comp_screen_init()
      }
    e_main_ts_end("\tE_Comp_Canvas Init Done");
 
+   e_main_ts_begin("\tE_Egl_Sync Init");
+   if (e_egl_sync_init())
+     ELOGF("E_EGL_SYNC", "Enabled the E_Egl_Sync", NULL);
+   e_main_ts_end("\tE_Egl_Sync Init Done");
+
    /* pointer */
    e_input_device_pointer_xy_get(NULL, &ptr_x, &ptr_y);
    e_comp_wl->ptr.x = wl_fixed_from_int(ptr_x);
diff --git a/src/bin/e_egl_sync.c b/src/bin/e_egl_sync.c
new file mode 100644 (file)
index 0000000..f0aba2b
--- /dev/null
@@ -0,0 +1,289 @@
+#include "e.h"
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+typedef struct _E_Egl_Sync_Mgr E_Egl_Sync_Mgr;
+
+struct _E_Egl_Sync_Mgr
+{
+   EGLDisplay egl_display;
+
+   PFNEGLCREATESYNCKHRPROC create_sync;
+   PFNEGLDESTROYSYNCKHRPROC destroy_sync;
+   PFNEGLDUPNATIVEFENCEFDTIZENPROC dup_native_fence_fd;
+   PFNEGLWAITSYNCKHRPROC wait_sync;
+};
+
+struct _E_Egl_Sync
+{
+   EGLSyncKHR sync;
+};
+
+static E_Egl_Sync_Mgr *_egl_sync_mgr = NULL;
+static Eina_Bool _egl_sync_enabled = EINA_FALSE;
+
+static Eina_Bool
+_e_egl_sync_extension_check(const char *extensions, const char *extension)
+{
+   size_t extlen = strlen(extension);
+   const char *end = extensions + strlen(extensions);
+
+   while (extensions < end)
+     {
+        size_t n = 0;
+
+        /* Skip whitespaces, if any */
+        if (*extensions == ' ')
+          {
+             extensions++;
+             continue;
+          }
+
+        n = strcspn(extensions, " ");
+
+        /* Compare strings */
+        if (n == extlen && strncmp(extension, extensions, n) == 0)
+          return EINA_TRUE;
+
+        extensions += n;
+    }
+
+   return EINA_FALSE;
+}
+
+EINTERN E_Egl_Sync *
+e_egl_sync_fence_create(void)
+{
+   E_Egl_Sync_Mgr *egl_sync_mgr;
+   E_Egl_Sync *egl_sync = NULL;
+   EGLint attribs[] = { EGL_NONE };
+   EGLSyncKHR sync = EGL_NO_SYNC_KHR;
+
+   egl_sync_mgr = _egl_sync_mgr;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(egl_sync_mgr, NULL);
+
+   sync = egl_sync_mgr->create_sync(egl_sync_mgr->egl_display,
+                                    EGL_SYNC_NATIVE_FENCE_TIZEN,
+                                    attribs);
+   if (sync == EGL_NO_SYNC_KHR)
+     {
+        ERR("Failed to create EGLSyncKHR object");
+        goto fail;
+     }
+
+   egl_sync = E_NEW(E_Egl_Sync, 1);
+   EINA_SAFETY_ON_NULL_GOTO(egl_sync, fail);
+
+   egl_sync->sync = sync;
+
+   return egl_sync;
+
+fail:
+   if (sync != EGL_NO_SYNC_KHR)
+     egl_sync_mgr->destroy_sync(egl_sync_mgr->egl_display, sync);
+
+   return NULL;
+}
+
+EINTERN E_Egl_Sync *
+e_egl_sync_fence_create_with_fd(int fd)
+{
+   E_Egl_Sync_Mgr *egl_sync_mgr;
+   E_Egl_Sync *egl_sync = NULL;
+   EGLint attribs[] = { EGL_SYNC_NATIVE_FENCE_FD_TIZEN, -1, EGL_NONE };
+   EGLSyncKHR sync = EGL_NO_SYNC_KHR;
+
+   egl_sync_mgr = _egl_sync_mgr;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(egl_sync_mgr, NULL);
+   EINA_SAFETY_ON_TRUE_RETURN_VAL(fd <  0, NULL);
+
+   attribs[1] = dup(fd);
+   if (attribs[1] < -1)
+     {
+        ERR("Failed to dup fd");
+        goto fail;
+     }
+
+   sync = egl_sync_mgr->create_sync(egl_sync_mgr->egl_display,
+                                    EGL_SYNC_NATIVE_FENCE_TIZEN,
+                                    attribs);
+   if (sync == EGL_NO_SYNC_KHR)
+     {
+        ERR("Failed to create EGLSyncKHR object");
+        goto fail;
+     }
+
+   egl_sync = E_NEW(E_Egl_Sync, 1);
+   EINA_SAFETY_ON_NULL_GOTO(egl_sync, fail);
+
+   egl_sync->sync = sync;
+
+   return egl_sync;
+
+fail:
+   if (attribs[1] >= 0)
+     close(attribs[1]);
+
+   if (sync != EGL_NO_SYNC_KHR)
+     egl_sync_mgr->destroy_sync(egl_sync_mgr->egl_display, sync);
+
+   return NULL;
+}
+
+EINTERN void
+e_egl_sync_destroy(E_Egl_Sync *egl_sync)
+{
+   E_Egl_Sync_Mgr *egl_sync_mgr;
+
+   egl_sync_mgr = _egl_sync_mgr;
+   EINA_SAFETY_ON_NULL_RETURN(egl_sync_mgr);
+
+   if (!egl_sync) return;
+
+   egl_sync_mgr->destroy_sync(egl_sync_mgr->egl_display, egl_sync->sync);
+
+   E_FREE(egl_sync);
+}
+
+EINTERN Eina_Bool
+e_egl_sync_wait(E_Egl_Sync *egl_sync)
+{
+   E_Egl_Sync_Mgr *egl_sync_mgr;
+   EGLint wait_ret;
+
+   egl_sync_mgr = _egl_sync_mgr;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(egl_sync_mgr, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(egl_sync, EINA_FALSE);
+
+   wait_ret = egl_sync_mgr->wait_sync(egl_sync_mgr->egl_display, egl_sync->sync, 0);
+   if (wait_ret == EGL_FALSE)
+     {
+        ERR("Failed to wait on EGLSyncKHR object");
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+EINTERN int
+e_egl_sync_fence_fd_dup(E_Egl_Sync *egl_sync)
+{
+   E_Egl_Sync_Mgr *egl_sync_mgr;
+   int fence_fd = -1;
+
+   egl_sync_mgr = _egl_sync_mgr;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(egl_sync_mgr, -1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(egl_sync, -1);
+
+   fence_fd = egl_sync_mgr->dup_native_fence_fd(egl_sync_mgr->egl_display, egl_sync->sync);
+   if (fence_fd == EGL_NO_NATIVE_FENCE_FD_TIZEN)
+     {
+        ERR("Failed to dup fence_fd");
+        return -1;
+     }
+
+   return fence_fd;
+}
+
+EINTERN Eina_Bool
+e_egl_sync_init(void)
+{
+   E_Egl_Sync_Mgr *egl_sync_mgr = NULL;
+   const char *extensions = NULL;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp_wl->wl.disp, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp->e_comp_screen, EINA_FALSE);
+
+   if (_egl_sync_mgr) return EINA_TRUE;
+   if (!e_comp_gl_get()) return EINA_TRUE;
+
+   egl_sync_mgr = E_NEW(E_Egl_Sync_Mgr, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(egl_sync_mgr, EINA_FALSE);
+
+   egl_sync_mgr->egl_display = eglGetCurrentDisplay();
+   EINA_SAFETY_ON_NULL_GOTO(egl_sync_mgr->egl_display, fail);
+
+   extensions = (const char *)eglQueryString(egl_sync_mgr->egl_display, EGL_EXTENSIONS);
+   if (!extensions)
+     {
+        ERR("Failed to query eglExtensions");
+        goto fail;
+     }
+
+   if (!_e_egl_sync_extension_check(extensions, "EGL_KHR_fence_sync"))
+     {
+        INF("Not support EGL_KHR_fence_sync extension");
+        goto fail;
+     }
+
+   if (!_e_egl_sync_extension_check(extensions, "EGL_KHR_wait_sync"))
+     {
+        INF("Not support EGL_KHR_wait_sync extension");
+        goto fail;
+     }
+
+   if (!_e_egl_sync_extension_check(extensions, "EGL_TIZEN_native_fence_sync"))
+     {
+        INF("Not support EGL_TIZEN_native_fence_sync extension");
+        goto fail;
+     }
+
+   egl_sync_mgr->create_sync = (void *)eglGetProcAddress("eglCreateSyncKHR");
+   if (!egl_sync_mgr->create_sync)
+     {
+        ERR("Failed to get eglCreateSyncKHR");
+        goto fail;
+     }
+
+   egl_sync_mgr->destroy_sync = (void *)eglGetProcAddress("eglDestroySyncKHR");
+   if (!egl_sync_mgr->destroy_sync)
+     {
+        ERR("Failed to get eglDestroySyncKHR");
+        goto fail;
+     }
+
+   egl_sync_mgr->dup_native_fence_fd = (void *)eglGetProcAddress("eglDupNativeFenceFDTIZEN");
+   if (!egl_sync_mgr->dup_native_fence_fd)
+     {
+        ERR("Failed to get eglDupNativeFenceFDTIZEN");
+        goto fail;
+     }
+
+   egl_sync_mgr->wait_sync = (void *)eglGetProcAddress("eglWaitSyncKHR");
+   if (!egl_sync_mgr->wait_sync)
+     {
+        ERR("Failed to get eglWaitSyncKHR");
+        goto fail;
+     }
+
+   _egl_sync_mgr = egl_sync_mgr;
+   _egl_sync_enabled = EINA_TRUE;
+
+   return EINA_TRUE;
+
+fail:
+   E_FREE(egl_sync_mgr);
+
+   return EINA_FALSE;
+}
+
+EINTERN void
+e_egl_sync_deinit(void)
+{
+   E_Egl_Sync_Mgr *egl_sync_mgr;
+
+   egl_sync_mgr = _egl_sync_mgr;
+   if (!egl_sync_mgr) return;
+
+   E_FREE(egl_sync_mgr);
+
+   _egl_sync_mgr = NULL;
+}
+
+EINTERN Eina_Bool
+e_egl_sync_enabled_get(void)
+{
+   return _egl_sync_enabled;
+}
diff --git a/src/bin/e_egl_sync.h b/src/bin/e_egl_sync.h
new file mode 100644 (file)
index 0000000..25c5555
--- /dev/null
@@ -0,0 +1,20 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Egl_Sync E_Egl_Sync;
+
+#else
+#ifndef E_EGL_SYNC_H
+#define E_EGL_SYNC_H
+
+EINTERN Eina_Bool    e_egl_sync_init(void);
+EINTERN void         e_egl_sync_deinit(void);
+EINTERN Eina_Bool    e_egl_sync_enabled_get(void);
+
+EINTERN E_Egl_Sync  *e_egl_sync_fence_create(void);
+EINTERN E_Egl_Sync  *e_egl_sync_fence_create_with_fd(int fd);
+EINTERN void         e_egl_sync_destroy(E_Egl_Sync *egl_sync);
+EINTERN Eina_Bool    e_egl_sync_wait(E_Egl_Sync *egl_sync);
+EINTERN int          e_egl_sync_fence_fd_dup(E_Egl_Sync *egl_sync);
+
+#endif // E_EGL_SYNC_H
+#endif
index c5cca03..3e4db81 100644 (file)
@@ -57,6 +57,7 @@
 #include "e_hwc_window.h"
 #include "e_hwc_window_queue.h"
 #include "e_presentation_time.h"
+#include "e_egl_sync.h"
 #include "e_comp_wl.h"
 #include "e_comp_wl_subsurface.h"
 #include "e_comp_wl_data.h"