add e_explicit_sync for supporting zwp_linux_explicit_synchronization 00/237900/10
authorChangyeon Lee <cyeon.lee@samsung.com>
Wed, 8 Jul 2020 08:11:28 +0000 (17:11 +0900)
committerChangyeon Lee <cyeon.lee@samsung.com>
Wed, 8 Jul 2020 08:48:46 +0000 (17:48 +0900)
Change-Id: Ie79f995c41572bf2652f94df9c87013df659a100

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

index 235db3e..7d69f8b 100755 (executable)
@@ -369,7 +369,7 @@ AC_MSG_RESULT([${have_shm_open}])
 AC_SUBST(SHM_OPEN_LIBS)
 
 if test "x${e_cv_want_wayland_only}" != "xno" || test "x${e_cv_want_wayland_clients}" != "xno";then
-  PKG_CHECK_MODULES([WAYLAND], [wayland-server >= 1.8.0 xkbcommon uuid xdg-shell-unstable-v5-server xdg-shell-unstable-v6-server tizen-remote-surface-server scaler-server screenshooter-server tizen-extension-server tizen-launch-server tizen-surface-server tizen-dpms-server eom-server presentation-time-server tizen-hwc-server],
+  PKG_CHECK_MODULES([WAYLAND], [wayland-server >= 1.8.0 xkbcommon uuid xdg-shell-unstable-v5-server xdg-shell-unstable-v6-server tizen-remote-surface-server scaler-server screenshooter-server tizen-extension-server tizen-launch-server tizen-surface-server tizen-dpms-server eom-server presentation-time-server tizen-hwc-server linux-explicit-synchronization-unstable-v1-server],
     [
       have_wayland=yes
       AC_DEFINE_UNQUOTED([HAVE_WAYLAND],[1],[enable wayland support])
index e79a82e..c936a7b 100644 (file)
@@ -55,6 +55,7 @@ BuildRequires:  systemd-devel
 BuildRequires:  pkgconfig(libinput)
 BuildRequires:  pkgconfig(presentation-time-server)
 BuildRequires:  pkgconfig(egl)
+BuildRequires:  pkgconfig(linux-explicit-synchronization-unstable-v1-server)
 BuildRequires:  pkgconfig(tizen-hwc-server)
 Requires:       libwayland-extension-server
 
index 8c826de..5c7e09c 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_explicit_sync.h \
 src/bin/e_egl_sync.h \
 src/bin/e_info_server_input.h
 
@@ -220,6 +221,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_explicit_sync.c \
 src/bin/e_egl_sync.c \
 src/bin/e_info_server_input.c \
 $(ENLIGHTENMENTHEADERS)
index c683a04..d19e089 100644 (file)
@@ -969,6 +969,7 @@ struct E_Client
    Eina_Bool skip_save_img: 1; // indicates that window doesn't want to save its image file
 
    E_Hwc_Window *hwc_window; // hwc window for the tdm_hwc.
+   E_Explicit_Sync_Surface *explicit_sync_surface;
    int comp_override;
 
    struct
index cc857b5..2dbf3fa 100644 (file)
@@ -653,6 +653,7 @@ _e_comp_screen_deinit_outputs(E_Comp_Screen *e_comp_screen)
         e_output_del(output);
      }
 
+   e_explicit_sync_deinit();
    e_egl_sync_deinit();
    e_hwc_deinit();
    e_hwc_windows_deinit();
@@ -1107,6 +1108,11 @@ e_comp_screen_init()
      ELOGF("E_EGL_SYNC", "Enabled the E_Egl_Sync", NULL);
    e_main_ts_end("\tE_Egl_Sync Init Done");
 
+   e_main_ts_begin("\tE_Explicit_Sync Init");
+   if (e_explicit_sync_init())
+     ELOGF("EX-SYNC", "Enabled the E_Explicit_Sync", NULL);
+   e_main_ts_end("\tE_Explicit_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);
index 48653e5..1537d05 100644 (file)
@@ -4291,6 +4291,9 @@ e_comp_wl_surface_commit(E_Client *ec)
           e_pixmap_image_clear(ec->pixmap, 1);
      }
 
+   if (ec->explicit_sync_surface)
+     e_explicit_sync_surface_commit(ec->explicit_sync_surface);
+
    ignored = ec->ignored;
 
    if (e_comp_wl_subsurface_order_commit(ec))
@@ -4375,6 +4378,12 @@ e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer)
         ref->buffer->busy--;
         if (ref->buffer->busy == 0)
           {
+             if (ref->buffer->buffer_release)
+               {
+                  e_explicit_sync_buffer_release_destroy(ref->buffer->buffer_release);
+                  ref->buffer->buffer_release = NULL;
+               }
+
              if (ref->buffer->resource)
                {
                   if (!wl_resource_get_client(ref->buffer->resource)) return;
index c0d2143..ac95bd0 100644 (file)
@@ -118,6 +118,8 @@ struct _E_Comp_Wl_Buffer
    int32_t w, h;
    int transform; // the value of wl_tbm.set_buffer_transform
    uint32_t busy;
+
+   E_Explicit_Sync_Buffer_Release *buffer_release;
 };
 
 struct _E_Comp_Wl_Buffer_Ref
diff --git a/src/bin/e_explicit_sync.c b/src/bin/e_explicit_sync.c
new file mode 100644 (file)
index 0000000..1db20c1
--- /dev/null
@@ -0,0 +1,544 @@
+#include "e.h"
+#include <linux-explicit-synchronization-unstable-v1-server-protocol.h>
+#include <tizen-extension-server-protocol.h>
+
+#define EX_SYNC_TRACE(f, ec, x... )                              \
+   do                                                            \
+     {                                                           \
+        if (ex_sync_trace)                                       \
+          {                                                      \
+             if (ec)                                             \
+               {                                                 \
+                  INF("EWL|%20.20s|w:0x%08zx|ec:%8p|"f,          \
+                      "EX-SYNC",                                 \
+                      (e_client_util_win_get(ec)),               \
+                      (ec),                                      \
+                      ##x);                                      \
+               }                                                 \
+             else                                                \
+               {                                                 \
+                  INF("EWL|%20.20s|            |             |"f,\
+                      "EX-SYNC",##x);                            \
+               }                                                 \
+          }                                                      \
+      }                                                          \
+   while (0)
+
+static E_Explicit_Sync *_explicit_sync = NULL;
+static Eina_Bool _explicit_sync_enabled = EINA_FALSE;
+static Eina_Bool ex_sync_trace = EINA_FALSE;
+
+static E_Comp_Wl_Buffer *
+_e_explicit_sync_comp_wl_buffer_get(E_Client *ec)
+{
+   E_Comp_Client_Data *cdata;
+
+   if (!ec) return NULL;
+
+   cdata = ec->comp_data;
+   if (!cdata) return NULL;
+
+   return cdata->buffer_ref.buffer;
+}
+
+static Eina_Bool
+_e_explicit_sync_fd_is_valid(int fd)
+{
+   if (fd < 0) return EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
+static void
+_e_explicit_sync_fd_set(int *fd, int new_fd)
+{
+   if (*fd == new_fd) return;
+
+   if (*fd >= 0) close(*fd);
+   *fd = new_fd;
+}
+
+static void
+_e_explicit_sync_fd_clear(int* fd)
+{
+   _e_explicit_sync_fd_set(fd, -1);
+}
+
+static void
+_e_explicit_sync_fd_move(int *dst, int *src)
+{
+   if (dst == src) return;
+
+   _e_explicit_sync_fd_set(dst, *src);
+   *src = -1;
+}
+
+static void
+_e_explicit_sync_surface_cb_destroy(struct wl_client *client,
+                                    struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+_e_explicit_sync_surface_cb_set_acquire_fence(struct wl_client *client,
+                                              struct wl_resource *resource,
+                                              int32_t fd)
+{
+   E_Explicit_Sync_Surface *explicit_sync_surface;
+
+   explicit_sync_surface = wl_resource_get_user_data(resource);
+   if (!explicit_sync_surface)
+     {
+        wl_resource_post_error(resource,
+                               ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_NO_SURFACE,
+                               "surface no longer exists");
+        goto fail;
+     }
+
+   if (!_e_explicit_sync_fd_is_valid(fd))
+     {
+        wl_resource_post_error(resource,
+                               ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_INVALID_FENCE,
+                               "invalid acquire fence fd");
+        goto fail;
+     }
+
+   if (explicit_sync_surface->pending_acquire_fence_fd != -1)
+     {
+        wl_resource_post_error(resource,
+                               ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_DUPLICATE_FENCE,
+                               "exist acquire fence fd");
+        goto fail;
+     }
+
+   _e_explicit_sync_fd_set(&explicit_sync_surface->pending_acquire_fence_fd, fd);
+
+   EX_SYNC_TRACE("Explicit_Sync Surface:%p Set Acquire fence fd:%d",
+                 explicit_sync_surface->ec, explicit_sync_surface, fd);
+
+   return;
+
+fail:
+   close(fd);
+}
+
+static void
+_e_explicit_sync_buffer_release_cb_resource_destroy(struct wl_resource *resource)
+{
+   E_Explicit_Sync_Buffer_Release *explicit_sync_buffer_release;
+
+   explicit_sync_buffer_release = wl_resource_get_user_data(resource);
+   if (!explicit_sync_buffer_release) return;
+
+   EX_SYNC_TRACE("Explicit_Sync Buffer_Release:%p Destroy", NULL, explicit_sync_buffer_release);
+
+   if (explicit_sync_buffer_release->fence_fd != -1)
+     _e_explicit_sync_fd_clear(&explicit_sync_buffer_release->fence_fd);
+
+   E_FREE(explicit_sync_buffer_release);
+}
+
+EINTERN void
+e_explicit_sync_buffer_release_destroy(E_Explicit_Sync_Buffer_Release *explicit_sync_buffer_release)
+{
+   EINA_SAFETY_ON_NULL_RETURN(explicit_sync_buffer_release);
+   EINA_SAFETY_ON_NULL_RETURN(explicit_sync_buffer_release->resource);
+
+   if (explicit_sync_buffer_release->fence_fd != -1)
+     {
+        zwp_linux_buffer_release_v1_send_fenced_release(explicit_sync_buffer_release->resource,
+                                                        explicit_sync_buffer_release->fence_fd);
+
+        EX_SYNC_TRACE("Explicit_Sync Buffer_Release:%p Release fence:%d",
+                      NULL, explicit_sync_buffer_release, explicit_sync_buffer_release->fence_fd);
+     }
+   else
+     {
+        zwp_linux_buffer_release_v1_send_immediate_release(explicit_sync_buffer_release->resource);
+
+        EX_SYNC_TRACE("Explicit_Sync Buffer_Release:%p Immediate Release", NULL, explicit_sync_buffer_release);
+     }
+
+   wl_resource_destroy(explicit_sync_buffer_release->resource);
+}
+
+EINTERN Eina_Bool
+e_explicit_sync_buffer_release_fence_fd_set(E_Explicit_Sync_Buffer_Release *explicit_sync_buffer_release,
+                                            int fence_fd)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(explicit_sync_buffer_release, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(explicit_sync_buffer_release->resource, EINA_FALSE);
+
+   if (explicit_sync_buffer_release->fence_fd != -1)
+     _e_explicit_sync_fd_clear(&explicit_sync_buffer_release->fence_fd);
+
+   explicit_sync_buffer_release->fence_fd = fence_fd;
+
+   EX_SYNC_TRACE("Explicit_Sync Buffer_Release:%p Set fence:%d",
+                 NULL, explicit_sync_buffer_release, explicit_sync_buffer_release->fence_fd);
+
+   return EINA_TRUE;
+}
+
+static void
+_e_explicit_sync_surface_cb_get_release(struct wl_client *client,
+                                        struct wl_resource *resource,
+                                        uint32_t id)
+{
+   E_Explicit_Sync_Surface *explicit_sync_surface = NULL;
+   E_Explicit_Sync_Buffer_Release *explicit_sync_buffer_release = NULL;
+
+   explicit_sync_surface = wl_resource_get_user_data(resource);
+   if ((!explicit_sync_surface) ||
+       (!explicit_sync_surface->ec) ||
+       (e_object_is_del(E_OBJECT(explicit_sync_surface->ec))))
+     {
+        wl_resource_post_error(resource,
+                               ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_NO_SURFACE,
+                               "explicit_sync_surface is already destroyed");
+        goto fail;
+     }
+
+   if (explicit_sync_surface->pending_buffer_release)
+     {
+         wl_resource_post_error(resource,
+                                ZWP_LINUX_SURFACE_SYNCHRONIZATION_V1_ERROR_DUPLICATE_RELEASE,
+                                "already has a buffer release");
+         goto fail;
+     }
+
+   explicit_sync_buffer_release = E_NEW(E_Explicit_Sync_Buffer_Release, 1);
+   if (!explicit_sync_buffer_release)
+     {
+        wl_client_post_no_memory(client);
+        goto fail;
+     }
+
+   explicit_sync_buffer_release->fence_fd = -1;
+   explicit_sync_buffer_release->resource = wl_resource_create(client,
+                                                               &zwp_linux_buffer_release_v1_interface,
+                                                               wl_resource_get_version(resource),
+                                                               id);
+   if (!explicit_sync_buffer_release->resource)
+     {
+        wl_client_post_no_memory(client);
+        goto fail;
+     }
+
+   wl_resource_set_implementation(explicit_sync_buffer_release->resource,
+                                  NULL,
+                                  explicit_sync_buffer_release,
+                                  _e_explicit_sync_buffer_release_cb_resource_destroy);
+
+   explicit_sync_surface->pending_buffer_release = explicit_sync_buffer_release;
+
+   EX_SYNC_TRACE("Explicit_Sync Surface:%p Buffer_Release:%p Create",
+                 explicit_sync_surface->ec, explicit_sync_surface, explicit_sync_buffer_release);
+
+   return;
+
+fail:
+   if (explicit_sync_buffer_release)
+     E_FREE(explicit_sync_buffer_release);
+}
+
+static const struct zwp_linux_surface_synchronization_v1_interface _e_explicit_sync_surface_implementation = {
+   _e_explicit_sync_surface_cb_destroy,
+   _e_explicit_sync_surface_cb_set_acquire_fence,
+   _e_explicit_sync_surface_cb_get_release
+};
+
+static void
+_e_explicit_sync_surface_cb_ec_free(void *data, void *obj)
+{
+   E_Client *ec = (E_Client *)obj;
+
+   EINA_SAFETY_ON_NULL_RETURN(ec);
+
+   if (!ec->explicit_sync_surface) return;
+
+   ec->explicit_sync_surface->ec_delfn = NULL;
+   ec->explicit_sync_surface->ec = NULL;
+}
+
+static void
+_e_explicit_sync_surface_cb_resource_destroy(struct wl_resource *resource)
+{
+   E_Explicit_Sync_Surface *explicit_sync_surface;
+
+   explicit_sync_surface = wl_resource_get_user_data(resource);
+   if (!explicit_sync_surface) return;
+
+   EX_SYNC_TRACE("Explicit_Sync Surface:%p Destroy", explicit_sync_surface->ec, explicit_sync_surface);
+
+   if (explicit_sync_surface->pending_acquire_fence_fd != -1)
+     _e_explicit_sync_fd_clear(&explicit_sync_surface->pending_acquire_fence_fd);
+
+   if (explicit_sync_surface->acquire_fence_fd != -1)
+     _e_explicit_sync_fd_clear(&explicit_sync_surface->acquire_fence_fd);
+
+   if (explicit_sync_surface->ec)
+     {
+        e_object_delfn_del(E_OBJECT(explicit_sync_surface->ec), explicit_sync_surface->ec_delfn);
+        explicit_sync_surface->ec_delfn = NULL;
+        explicit_sync_surface->ec = NULL;
+     }
+
+   E_FREE(explicit_sync_surface);
+}
+
+static void _e_explicit_sync_cb_get_synchronization(struct wl_client *client,
+                                                    struct wl_resource *resource,
+                                                    uint32_t id,
+                                                    struct wl_resource *surface)
+{
+   E_Client *ec;
+   E_Explicit_Sync_Surface *explicit_sync_surface = NULL;
+
+   ec = wl_resource_get_user_data(surface);
+   if ((!ec) || (e_object_is_del(E_OBJECT(ec))))
+     {
+        wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "invalid wl_surface resource:%u",
+                               (unsigned int)wl_resource_get_id(surface));
+        goto fail;
+     }
+
+   if (ec->explicit_sync_surface)
+     {
+        wl_resource_post_error(resource,
+                               ZWP_LINUX_EXPLICIT_SYNCHRONIZATION_V1_ERROR_SYNCHRONIZATION_EXISTS,
+                               "wl_surface resource:%u already has synchronization",
+                               (unsigned int)wl_resource_get_id(surface));
+        goto fail;
+     }
+
+   explicit_sync_surface = E_NEW(E_Explicit_Sync_Surface, 1);
+   if (!explicit_sync_surface)
+     {
+        wl_client_post_no_memory(client);
+        goto fail;
+     }
+
+   explicit_sync_surface->acquire_fence_fd = -1;
+   explicit_sync_surface->pending_acquire_fence_fd = -1;
+
+   explicit_sync_surface->resource = wl_resource_create(client,
+                                                        &zwp_linux_surface_synchronization_v1_interface,
+                                                        wl_resource_get_version(resource),
+                                                        id);
+   if (!explicit_sync_surface->resource)
+     {
+        wl_client_post_no_memory(client);
+        goto fail;
+     }
+
+   wl_resource_set_implementation(explicit_sync_surface->resource,
+                                  &_e_explicit_sync_surface_implementation,
+                                  explicit_sync_surface,
+                                  _e_explicit_sync_surface_cb_resource_destroy);
+
+   ec->explicit_sync_surface = explicit_sync_surface;
+   explicit_sync_surface->ec = ec;
+   explicit_sync_surface->ec_delfn = e_object_delfn_add(E_OBJECT(ec),
+                                                        _e_explicit_sync_surface_cb_ec_free,
+                                                        NULL);
+
+   EX_SYNC_TRACE("Explicit_Sync Surface:%p Create", explicit_sync_surface->ec, explicit_sync_surface);
+
+   return;
+
+fail:
+   if (explicit_sync_surface)
+     E_FREE(explicit_sync_surface);
+}
+
+static void
+_e_explicit_sync_cb_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static const struct zwp_linux_explicit_synchronization_v1_interface e_explicit_sync_implementation = {
+   _e_explicit_sync_cb_destroy,
+   _e_explicit_sync_cb_get_synchronization
+};
+
+static void
+_explicit_sync_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+   struct wl_resource *resource;
+   E_Explicit_Sync *explicit_sync;
+
+   explicit_sync = _explicit_sync;
+
+   resource = wl_resource_create(client, &zwp_linux_explicit_synchronization_v1_interface, version, id);
+   if (!resource)
+     {
+        wl_client_post_no_memory(client);
+        return;
+     }
+
+   wl_resource_set_implementation(resource, &e_explicit_sync_implementation,
+                                  explicit_sync, NULL);
+}
+
+EINTERN Eina_Bool
+e_explicit_sync_surface_commit(E_Explicit_Sync_Surface *explicit_sync_surface)
+{
+   E_Client *ec;
+   E_Comp_Wl_Buffer *buffer;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(explicit_sync_surface, EINA_FALSE);
+
+   ec = explicit_sync_surface->ec;
+   if ((!ec) || e_object_is_del(E_OBJECT(ec)))
+     {
+        ERR("invalid ec");
+        return EINA_FALSE;
+     }
+
+   if (explicit_sync_surface->pending_acquire_fence_fd != -1)
+     {
+        if (explicit_sync_surface->acquire_fence_fd != -1)
+          _e_explicit_sync_fd_clear(&explicit_sync_surface->acquire_fence_fd);
+
+        _e_explicit_sync_fd_move(&explicit_sync_surface->acquire_fence_fd,
+                                 &explicit_sync_surface->pending_acquire_fence_fd);
+     }
+
+   if (explicit_sync_surface->pending_buffer_release)
+     {
+        buffer = _e_explicit_sync_comp_wl_buffer_get(ec);
+        if (buffer)
+          {
+             if (buffer->buffer_release)
+               e_explicit_sync_buffer_release_destroy(buffer->buffer_release);
+
+             buffer->buffer_release = explicit_sync_surface->pending_buffer_release;
+             explicit_sync_surface->pending_buffer_release = NULL;
+          }
+     }
+
+   EX_SYNC_TRACE("Explicit_Sync Surface:%p Commit", explicit_sync_surface->ec, explicit_sync_surface);
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_explicit_sync_surface_sync(E_Explicit_Sync_Surface *explicit_sync_surface)
+{
+   E_Explicit_Sync *explicit_sync;
+   E_Egl_Sync *egl_sync;
+
+   explicit_sync = _explicit_sync;
+   EINA_SAFETY_ON_NULL_RETURN_VAL(explicit_sync, EINA_FALSE);
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(explicit_sync_surface, EINA_FALSE);
+
+   if (explicit_sync_surface->acquire_fence_fd == -1)
+     return EINA_TRUE;
+
+   egl_sync = e_egl_sync_fence_create_with_fd(explicit_sync_surface->acquire_fence_fd);
+   EINA_SAFETY_ON_NULL_GOTO(egl_sync, fail);
+
+   if (!e_egl_sync_wait(egl_sync))
+     {
+        ERR("Failed to wait on E_Egl_Sync");
+        goto fail;
+     }
+
+   e_egl_sync_destroy(egl_sync);
+
+   EX_SYNC_TRACE("Explicit_Sync Surface:%p Sync", explicit_sync_surface->ec, explicit_sync_surface);
+
+   return EINA_TRUE;
+
+fail:
+   if (egl_sync)
+     e_egl_sync_destroy(egl_sync);
+
+   return EINA_FALSE;
+}
+
+EINTERN Eina_Bool
+e_explicit_sync_init(void)
+{
+   E_Explicit_Sync *explicit_sync = NULL;
+   E_Output *output;
+   Eina_Bool ret = EINA_FALSE;
+   Eina_List *l;
+
+   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 (_explicit_sync) return EINA_TRUE;
+   if (!e_comp_gl_get()) return EINA_FALSE;
+   if (!e_egl_sync_enabled_get()) return EINA_FALSE;
+
+   EINA_LIST_FOREACH(e_comp->e_comp_screen->outputs, l, output)
+     {
+         if (!output) continue;
+         if (!output->hwc) continue;
+         if (output->hwc->hwc_policy != E_HWC_POLICY_WINDOWS) continue;
+         if (!output->hwc->tdm_hwc_fence) continue;
+
+         ret = EINA_TRUE;
+     }
+
+   if (!ret) return EINA_FALSE;
+
+   explicit_sync = E_NEW(E_Explicit_Sync, 1);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(explicit_sync, EINA_FALSE);
+
+   explicit_sync->global = wl_global_create(e_comp_wl->wl.disp,
+                                           &zwp_linux_explicit_synchronization_v1_interface,
+                                           2,
+                                           explicit_sync,
+                                           _explicit_sync_cb_bind);
+   EINA_SAFETY_ON_NULL_GOTO(explicit_sync->global, fail);
+
+   _explicit_sync = explicit_sync;
+   _explicit_sync_enabled = EINA_TRUE;
+
+   return EINA_TRUE;
+
+fail:
+   if (explicit_sync->global)
+      wl_global_destroy(explicit_sync->global);
+
+   E_FREE(explicit_sync);
+
+   return EINA_FALSE;
+}
+
+EINTERN void
+e_explicit_sync_deinit(void)
+{
+   E_Explicit_Sync *explicit_sync;
+
+   explicit_sync = _explicit_sync;
+   if (!explicit_sync) return;
+
+   wl_global_destroy(explicit_sync->global);
+   E_FREE(explicit_sync);
+
+   _explicit_sync = NULL;
+}
+
+EINTERN void
+e_explicit_sync_trace_debug(Eina_Bool onoff)
+{
+   if (onoff == ex_sync_trace) return;
+   ex_sync_trace = onoff;
+   INF("Explicit Sync Debug is %s", onoff?"ON":"OFF");
+}
+
+EINTERN Eina_Bool
+e_explicit_sync_enabled_get(void)
+{
+   return _explicit_sync_enabled;
+}
diff --git a/src/bin/e_explicit_sync.h b/src/bin/e_explicit_sync.h
new file mode 100644 (file)
index 0000000..3b71692
--- /dev/null
@@ -0,0 +1,48 @@
+#ifdef E_TYPEDEFS
+
+typedef struct _E_Explicit_Sync E_Explicit_Sync;
+typedef struct _E_Explicit_Sync_Surface E_Explicit_Sync_Surface;
+typedef struct _E_Explicit_Sync_Buffer_Release E_Explicit_Sync_Buffer_Release;
+
+#else
+#ifndef E_EXPLICIT_SYNC_H
+#define E_EXPLICIT_SYNC_H
+
+struct _E_Explicit_Sync
+{
+   struct wl_global *global;
+};
+
+struct _E_Explicit_Sync_Surface
+{
+   struct wl_resource *resource;
+
+   int pending_acquire_fence_fd;
+   int acquire_fence_fd;
+
+   E_Client *ec;
+   E_Object_Delfn *ec_delfn;
+
+   E_Explicit_Sync_Buffer_Release *pending_buffer_release;
+};
+
+struct _E_Explicit_Sync_Buffer_Release
+{
+   struct wl_resource *resource;
+   int fence_fd;
+};
+
+
+EINTERN Eina_Bool e_explicit_sync_init(void);
+EINTERN void      e_explicit_sync_deinit(void);
+EINTERN void      e_explicit_sync_trace_debug(Eina_Bool onoff);
+EINTERN Eina_Bool e_explicit_sync_enabled_get(void);
+
+EINTERN Eina_Bool e_explicit_sync_surface_commit(E_Explicit_Sync_Surface *explicit_sync_surface);
+EINTERN Eina_Bool e_explicit_sync_surface_sync(E_Explicit_Sync_Surface *explicit_sync_surface);
+
+EINTERN Eina_Bool e_explicit_sync_buffer_release_fence_fd_set(E_Explicit_Sync_Buffer_Release *explicit_sync_buffer_release, int fence_fd);
+EINTERN void      e_explicit_sync_buffer_release_destroy(E_Explicit_Sync_Buffer_Release *explicit_sync_buffer_release);
+
+#endif // E_EXPLICIT_SYNC_H
+#endif
index 3e4db81..0aa4d3f 100644 (file)
@@ -57,6 +57,7 @@
 #include "e_hwc_window.h"
 #include "e_hwc_window_queue.h"
 #include "e_presentation_time.h"
+#include "e_explicit_sync.h"
 #include "e_egl_sync.h"
 #include "e_comp_wl.h"
 #include "e_comp_wl_subsurface.h"