Add prototype implementation for Video & UI synchronization. 25/227525/2
authorSeunghun Lee <shiin.lee@samsung.com>
Mon, 2 Mar 2020 04:50:14 +0000 (13:50 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Fri, 13 Mar 2020 00:22:16 +0000 (00:22 +0000)
Change-Id: I29732676e494f4e9d7a09b40b039bdfb916b59d0

src/bin/Makefile.mk
src/bin/e_comp_wl.c
src/bin/e_includes.h
src/bin/video/e_client_video.c
src/bin/video/e_client_video.h
src/bin/video/e_client_video_surface_provider.c [new file with mode: 0644]
src/bin/video/e_client_video_surface_provider.h [new file with mode: 0644]
src/bin/video/e_comp_wl_video.c
src/bin/video/e_comp_wl_video.h

index 004b816..ad636c0 100644 (file)
@@ -108,6 +108,7 @@ src/bin/e_comp_wl_rsm.h \
 src/bin/video/e_comp_wl_video.h \
 src/bin/video/e_comp_wl_video_buffer.h \
 src/bin/video/e_client_video.h \
+src/bin/video/e_client_video_surface_provider.h \
 src/bin/video/e_zone_video.h \
 src/bin/video/e_video_debug.h \
 src/bin/e_comp_wl_viewport.h \
@@ -228,6 +229,7 @@ src/bin/e_comp_wl_rsm.c \
 src/bin/video/e_comp_wl_video.c \
 src/bin/video/e_comp_wl_video_buffer.c \
 src/bin/video/e_client_video.c \
+src/bin/video/e_client_video_surface_provider.c \
 src/bin/video/e_zone_video.c \
 src/bin/video/e_video_debug.c \
 src/bin/video/e_util_video.c \
index ff593f2..17cc721 100644 (file)
@@ -2983,6 +2983,7 @@ _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_res
      }
 
    if (e_comp_wl_remote_surface_commit(ec)) return;
+   if (e_client_video_commit(ec)) return;
    if (e_comp_wl_subsurface_commit(ec)) return;
 
    e_comp_wl_surface_commit(ec);
index 17a9098..3e4cbc6 100644 (file)
@@ -87,6 +87,7 @@
 #include "e_xdg_shell_v6.h"
 #include "e_devicemgr.h"
 #include "e_video_debug.h"
+#include "e_client_video_surface_provider.h"
 #include "e_client_video.h"
 #include "e_zone_video.h"
 #include "e_comp_wl_video.h"
index bddef2f..3e59bd3 100644 (file)
@@ -28,6 +28,13 @@ struct _E_Client_Video
    Eina_List *event_handlers;
    E_Comp_Wl_Hook *subsurf_create_hook_handler;
 
+   struct
+     {
+        uint32_t serial;
+        Eina_Bool pending_enabled;
+        Eina_Bool enabled;
+     } sync;
+
    Eina_Bool hw_composition;
    Eina_Bool follow_topmost_visibility;
    Eina_Bool allowed_property;
@@ -560,3 +567,97 @@ e_client_video_property_allow_get(E_Client_Video *ecv)
    EINA_SAFETY_ON_NULL_RETURN_VAL(ecv, EINA_FALSE);
    return ecv->allowed_property;
 }
+
+E_API Eina_Bool
+e_client_video_sync_serial_set(E_Client *ec, uint32_t serial)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   INTERNAL_DATA_GET;
+
+   if (!ecv)
+     return EINA_FALSE;
+
+   ecv->sync.serial = serial;
+   ecv->sync.pending_enabled = EINA_TRUE;
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_client_video_sync_serial_get(E_Client *ec, uint32_t *ret)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   INTERNAL_DATA_GET;
+
+   if (!ecv)
+     return EINA_FALSE;
+
+   *ret = ecv->sync.serial;
+
+   return EINA_TRUE;
+}
+
+static E_Client *
+_e_client_video_surface_provider_ec_find(E_Client_Video *ecv)
+{
+   E_Client *ec;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ecv->ec->comp_data, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ecv->ec->comp_data->sub.data, NULL);
+
+   ec = ecv->ec->comp_data->sub.data->parent;
+   while (ec)
+     {
+        if (e_client_video_surface_provider_check(ec))
+          return ec;
+
+        if ((!ec->comp_data) ||
+            (!ec->comp_data->sub.data))
+          goto fail;
+
+        ec = ec->comp_data->sub.data->parent;
+     }
+
+fail:
+   return NULL;
+}
+
+EINTERN Eina_Bool
+e_client_video_commit(E_Client *ec)
+{
+   E_Client *provider_ec;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE);
+
+   INTERNAL_DATA_GET;
+
+   if (ecv)
+     {
+        /* FIXME is it really necessary? */
+        ecv->sync.enabled = ecv->sync.pending_enabled;
+        ecv->sync.pending_enabled = EINA_FALSE;
+
+        if (ecv->sync.enabled)
+          {
+             provider_ec = _e_client_video_surface_provider_ec_find(ecv);
+             if (provider_ec)
+               {
+                  if (e_client_video_surface_provider_sync_done_check(provider_ec))
+                    {
+                       e_comp_wl_subsurface_commit(ec);
+                       e_client_video_surface_provider_commit_by_sync(provider_ec);
+
+                       return EINA_TRUE;
+                    }
+               }
+          }
+
+     }
+   else if (e_client_video_surface_provider_check(ec))
+     return e_client_video_surface_provider_commit(ec);
+
+   return EINA_FALSE;
+}
index c58233a..621066e 100644 (file)
@@ -49,4 +49,8 @@ EINTERN Eina_Bool    e_client_video_commit_data_release(E_Client *ec, unsigned i
 
 EINTERN tbm_surface_h  e_client_video_tbm_surface_get(E_Client *ec);
 
+E_API Eina_Bool       e_client_video_sync_serial_set(E_Client *ec, uint32_t serial);
+EINTERN Eina_Bool     e_client_video_sync_serial_get(E_Client *ec, uint32_t *serial);
+EINTERN Eina_Bool     e_client_video_commit(E_Client *ec);
+
 #endif
diff --git a/src/bin/video/e_client_video_surface_provider.c b/src/bin/video/e_client_video_surface_provider.c
new file mode 100644 (file)
index 0000000..784da86
--- /dev/null
@@ -0,0 +1,493 @@
+#include "e_video_internal.h"
+
+#include <tizen-extension-server-protocol.h>
+
+#ifdef EO_DATA_KEY
+#undef EO_DATA_KEY
+#endif
+#define EO_DATA_KEY "E_Client_Video_Surface_Provider"
+
+#ifdef INTERN_DATA_GET
+#undef INTERN_DATA_GET
+#endif
+#define INTERN_DATA_GET                               \
+   E_Client_Video_Surface_Provider *pd;               \
+   pd = evas_object_data_get(ec->frame, EO_DATA_KEY)
+
+#ifdef MY_HANDLE
+#undef MY_HANDLE
+#endif
+#define MY_HANDLE E_Client_Video_Surface_Provider
+
+struct _E_Client_Video_Surface_Provider
+{
+   E_Client *ec;
+
+   Eina_List *event_handlers;
+
+   struct
+     {
+        struct wl_resource *resource;
+        struct wl_listener destroy_listener;
+     } wl;
+
+   struct
+     {
+        struct
+          {
+             E_Comp_Wl_Surface_State data;
+             E_Comp_Wl_Buffer_Ref buffer_ref;
+          } cache;
+
+        int video_count;
+        uint32_t serial;
+
+        Eina_Bool pending_enabled;
+        Eina_Bool enabled;
+        Eina_Bool done;
+     } sync;
+};
+
+static Eina_Bool   _ecvsp_ec_validate(E_Client *ec);
+static MY_HANDLE  *_ecvsp_create(E_Client *ec, struct wl_resource *wl_resource);
+static void        _ecvsp_destroy(MY_HANDLE *pd);
+static void        _ecvsp_commit_to_cache(MY_HANDLE *pd, E_Comp_Wl_Surface_State *src);
+static void        _ecvsp_commit_from_cache(MY_HANDLE *pd);
+static void        _ecvsp_commit(MY_HANDLE *pd);
+static Eina_Bool   _ecvsp_sync_done_check(MY_HANDLE *pd);
+
+static Eina_Bool   _ecvsp_cb_ec_remove(void *data, int type, void *event);
+
+E_API Eina_Bool
+e_client_video_surface_provider_set(E_Client *ec, struct wl_resource *wl_resource)
+{
+   MY_HANDLE *pd;
+
+   VIN("Set video surface provider", ec);
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(wl_resource, EINA_FALSE);
+
+   if (!_ecvsp_ec_validate(ec))
+     {
+        VER("validation failed", ec);
+        return EINA_FALSE;
+     }
+
+   pd = evas_object_data_get(ec->frame, EO_DATA_KEY);
+   if (pd)
+     {
+        VER("Given client was already set as Video Surface Provider", ec);
+        /* FIXME TRUE? FALSE? */
+        return EINA_FALSE;
+     }
+
+   pd = _ecvsp_create(ec, wl_resource);
+   if (!pd)
+     {
+        VER("failed to create Video Surface Provider", ec);
+        return EINA_FALSE;
+     }
+
+   evas_object_data_set(ec->frame, EO_DATA_KEY, pd);
+
+   return EINA_TRUE;
+}
+
+E_API void
+e_client_video_surface_provider_unset(E_Client *ec)
+{
+   INTERN_DATA_GET;
+
+   if (!pd)
+     {
+        VWR("It's not video client or already deleted(%d)",
+            ec, e_object_is_del(E_OBJECT(ec)));
+        return;
+     }
+
+   VIN("Unset video surface provider", ec);
+
+   evas_object_data_del(ec->frame, EO_DATA_KEY);
+
+   _ecvsp_destroy(pd);
+}
+
+E_API Eina_Bool
+e_client_video_surface_provider_check(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+
+   INTERN_DATA_GET;
+
+   return !!pd;
+}
+
+EINTERN Eina_Bool
+e_client_video_surface_provider_sync_done_check(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE);
+
+   INTERN_DATA_GET;
+
+   if (!pd->sync.enabled)
+     return EINA_FALSE;
+
+   return _ecvsp_sync_done_check(pd);
+}
+
+/* NOTE
+ * e_comp_wl_surface_commit() will be done if it returns false.
+ * So, note that you have to call e_comp_wl_surface_commit() somewhere if
+ * you want revise this behavior. */
+EINTERN Eina_Bool
+e_client_video_surface_provider_commit(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
+
+   INTERN_DATA_GET;
+
+   if (!pd)
+     return EINA_FALSE;
+
+   if ((pd->sync.enabled) &&
+       (!pd->sync.pending_enabled))
+     {
+        /* FIXME consider again */
+        VIN("dislabed sync before done", ec);
+        goto sync_done;
+     }
+
+   pd->sync.enabled = pd->sync.pending_enabled;
+   pd->sync.pending_enabled = EINA_FALSE;
+
+   if (!pd->sync.enabled)
+     return EINA_FALSE;
+
+   if (_ecvsp_sync_done_check(pd))
+     goto sync_done;
+   else
+     _ecvsp_commit_to_cache(pd, &ec->comp_data->pending);
+
+   return EINA_TRUE;
+
+sync_done:
+   VIN("sync done: serial(%d)", ec, pd->sync.serial);
+
+   _ecvsp_commit(pd);
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_client_video_surface_provider_commit_by_sync(E_Client *ec)
+{
+   E_Client *subc;
+   Eina_List *l;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
+
+   INTERN_DATA_GET;
+
+   if (!pd)
+     return EINA_FALSE;
+
+   if (!pd->sync.enabled)
+     return EINA_FALSE;
+
+   VIN("sync done: serial(%d)", ec, pd->sync.serial);
+
+   if (pd->sync.cache.data.has_data)
+     _ecvsp_commit_from_cache(pd);
+
+   EINA_LIST_FOREACH(pd->ec->comp_data->sub.list, l, subc)
+     {
+        if (pd->ec != subc)
+          e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
+     }
+
+   EINA_LIST_FOREACH(pd->ec->comp_data->sub.below_list, l, subc)
+     {
+        if (pd->ec != subc)
+          e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
+     }
+
+   /* notify sync done to wl_client */
+   tizen_video_surface_provider_send_sync_done(pd->wl.resource,
+                                               pd->sync.serial);
+
+   pd->sync.enabled = EINA_FALSE;
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecvsp_ec_validate(E_Client *ec)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->comp_data, EINA_FALSE);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ec->frame, EINA_FALSE);
+
+   if (e_object_is_del(E_OBJECT(ec)))
+     {
+        VER("Can't handle deleted client", ec);
+        return EINA_FALSE;
+     }
+
+   if (e_client_is_video(ec))
+     {
+        VER("Video Client cannot be Video Surface Provider", ec);
+        return EINA_FALSE;
+     }
+
+   if (ec->comp_data->sub.data)
+     {
+        VER("Subsurface is not supported for Vide Surface Provider for now", ec);
+        return EINA_FALSE;
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecvsp_cb_ec_remove(void *data, int type, void *event)
+{
+   E_Event_Client *ev;
+   MY_HANDLE *pd;
+
+   ev = event;
+   pd = data;
+
+   if (ev->ec != pd->ec)
+     goto end;
+
+   _ecvsp_destroy(pd);
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_ecvsp_cb_wl_destroy(struct wl_client *client, struct wl_resource *resource)
+{
+   wl_resource_destroy(resource);
+}
+
+static void
+_ecvsp_cb_wl_sync_serial_set(struct wl_client *client, struct wl_resource *resource, uint32_t serial)
+{
+   MY_HANDLE *pd;
+
+   pd = wl_resource_get_user_data(resource);
+
+   VIN("sync with serial (%d)", pd->ec, serial);
+
+   pd->sync.serial = serial;
+   pd->sync.pending_enabled = EINA_TRUE;
+}
+
+static const struct tizen_video_surface_provider_interface _ecvsp_wl_interface =
+{
+   _ecvsp_cb_wl_destroy,
+   _ecvsp_cb_wl_sync_serial_set,
+};
+
+static void
+_ecvsp_cb_wl_resource_destroy(struct wl_resource *resource)
+{
+   MY_HANDLE *pd;
+
+   pd = wl_resource_get_user_data(resource);
+
+   _ecvsp_destroy(pd);
+}
+
+static MY_HANDLE *
+_ecvsp_create(E_Client *ec, struct wl_resource *wl_resource)
+{
+   MY_HANDLE *pd;
+
+   pd = E_NEW(MY_HANDLE, 1);
+   if (!pd)
+     {
+        VER("Failed to allocate memory", ec);
+        return EINA_FALSE;
+     }
+
+   e_object_ref(E_OBJECT(ec));
+
+   pd->ec = ec;
+   pd->wl.resource = wl_resource;
+
+   wl_resource_set_implementation(wl_resource,
+                                  &_ecvsp_wl_interface,
+                                  pd,
+                                  _ecvsp_cb_wl_resource_destroy);
+
+   E_LIST_HANDLER_APPEND(pd->event_handlers, E_EVENT_CLIENT_REMOVE,
+                         _ecvsp_cb_ec_remove, pd);
+
+   return pd;
+}
+
+static void
+_ecvsp_destroy(MY_HANDLE *pd)
+{
+   if (pd->wl.destroy_listener.notify)
+     {
+        wl_list_remove(&pd->wl.destroy_listener.link);
+        pd->wl.destroy_listener.notify = NULL;
+     }
+
+   E_FREE_LIST(pd->event_handlers, ecore_event_handler_del);
+
+   e_object_unref(E_OBJECT(pd->ec));
+}
+
+static void
+_ecvsp_commit_to_cache(MY_HANDLE *pd, E_Comp_Wl_Surface_State *src)
+{
+   E_Comp_Wl_Surface_State *dst;
+   struct wl_resource *cb;
+   Eina_List *l, *ll;
+   Eina_Iterator *itr;
+   Eina_Rectangle *rect;
+
+   DBG("Video Surface Provider Commit to Cache");
+
+   dst = &pd->sync.cache.data;
+
+   /* move pending damage */
+   EINA_LIST_FOREACH_SAFE(src->damages, l, ll, rect)
+      eina_list_move_list(&dst->damages, &src->damages, l);
+
+   EINA_LIST_FOREACH_SAFE(src->buffer_damages, l, ll, rect)
+      eina_list_move_list(&dst->buffer_damages, &src->buffer_damages, l);
+
+   if (src->new_attach)
+     {
+        dst->new_attach = EINA_TRUE;
+        e_comp_wl_surface_state_buffer_set(dst, src->buffer);
+        e_comp_wl_buffer_reference(&pd->sync.cache.buffer_ref, src->buffer);
+     }
+
+   dst->sx = src->sx;
+   dst->sy = src->sy;
+
+   dst->buffer_viewport.changed |= src->buffer_viewport.changed;
+   dst->buffer_viewport.buffer = src->buffer_viewport.buffer;
+   dst->buffer_viewport.surface = src->buffer_viewport.surface;
+
+   e_comp_wl_surface_state_buffer_set(src, NULL);
+   src->sx = 0;
+   src->sy = 0;
+   src->new_attach = EINA_FALSE;
+   src->buffer_viewport.changed = 0;
+
+   /* copy src->opaque into dst->opaque */
+   itr = eina_tiler_iterator_new(src->opaque);
+   EINA_ITERATOR_FOREACH(itr, rect)
+      eina_tiler_rect_add(dst->opaque, rect);
+   eina_iterator_free(itr);
+
+   /* repeat for input */
+   itr = eina_tiler_iterator_new(src->input);
+   EINA_ITERATOR_FOREACH(itr, rect)
+      eina_tiler_rect_add(dst->input, rect);
+   eina_iterator_free(itr);
+
+   EINA_LIST_FOREACH_SAFE(src->frames, l, ll, cb)
+     {
+        if (cb)
+          eina_list_move_list(&dst->frames, &src->frames, l);
+     }
+
+   dst->has_data = EINA_TRUE;
+}
+
+static void
+_ecvsp_commit_from_cache(MY_HANDLE *pd)
+{
+   e_comp_wl_surface_state_commit(pd->ec, &pd->sync.cache.data);
+   e_comp_wl_buffer_reference(&pd->sync.cache.buffer_ref, NULL);
+}
+
+static void
+_ecvsp_commit(MY_HANDLE *pd)
+{
+   E_Client *subc;
+   Eina_List *l;
+
+   if (pd->sync.cache.data.has_data)
+     {
+        _ecvsp_commit_to_cache(pd, &pd->ec->comp_data->pending);
+        _ecvsp_commit_from_cache(pd);
+     }
+   else
+     e_comp_wl_surface_commit(pd->ec);
+
+   EINA_LIST_FOREACH(pd->ec->comp_data->sub.list, l, subc)
+     {
+        if (pd->ec != subc)
+          e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
+     }
+
+   EINA_LIST_FOREACH(pd->ec->comp_data->sub.below_list, l, subc)
+     {
+        if (pd->ec != subc)
+          e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
+     }
+
+   /* notify sync done to wl_client */
+   tizen_video_surface_provider_send_sync_done(pd->wl.resource,
+                                               pd->sync.serial);
+
+   pd->sync.enabled = EINA_FALSE;
+}
+
+static Eina_Bool
+_ecvsp_cb_surface_tree_foreach(void *data, E_Client *ec)
+{
+   MY_HANDLE *pd;
+   Eina_Bool res;
+   uint32_t serial;
+
+   pd = data;
+   res = e_client_video_sync_serial_get(ec, &serial);
+   if (res)
+     {
+        pd->sync.video_count++;
+        if (pd->sync.serial != serial)
+          {
+             pd->sync.done = EINA_FALSE;
+             return EINA_FALSE;
+          }
+     }
+
+   return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecvsp_sync_done_check(MY_HANDLE *pd)
+{
+   pd->sync.video_count = 0;
+   pd->sync.done = EINA_TRUE;
+   e_client_surface_tree_foreach(pd->ec, _ecvsp_cb_surface_tree_foreach, pd);
+
+   if (pd->sync.video_count == 0)
+     {
+        /* Exception handling: Let's consider it as sync done. */
+        VER("CRI: cannot find video client", pd->ec);
+        return EINA_TRUE;
+     }
+   
+   if (pd->sync.done)
+     {
+        VIN("sync done successfully", pd->ec);
+        return EINA_TRUE;
+     }
+
+   return EINA_FALSE;
+}
diff --git a/src/bin/video/e_client_video_surface_provider.h b/src/bin/video/e_client_video_surface_provider.h
new file mode 100644 (file)
index 0000000..bc34fc7
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _E_CLIENT_VIDEO_SURFACE_PROVIDER_H_
+#define _E_CLIENT_VIDEO_SURFACE_PROVIDER_H_
+
+typedef struct _E_Client_Video_Surface_Provider E_Client_Video_Surface_Provider;
+
+E_API Eina_Bool      e_client_video_surface_provider_set(E_Client *ec, struct wl_resource *wl_resource);
+E_API void           e_client_video_surface_provider_unset(E_Client *ec);
+E_API Eina_Bool      e_client_video_surface_provider_check(E_Client *ec);
+
+EINTERN Eina_Bool    e_client_video_surface_provider_sync_done_check(E_Client *ec);
+EINTERN Eina_Bool    e_client_video_surface_provider_commit(E_Client *ec);
+EINTERN Eina_Bool    e_client_video_surface_provider_commit_by_sync(E_Client *ec);
+
+#endif
index 1fc7b5f..46e9087 100644 (file)
@@ -301,6 +301,21 @@ _e_comp_wl_video_object_cb_disallowed_attribute(struct wl_client *client,
    e_client_video_property_disallow(video->ec);
 }
 
+static void
+_e_comp_wl_video_object_cb_set_sync_serial(struct wl_client *client,
+                                           struct wl_resource *resource,
+                                           uint32_t serial)
+{
+   E_Video *video;
+
+   video = wl_resource_get_user_data(resource);
+   EINA_SAFETY_ON_NULL_RETURN(video);
+
+   ELOGF("VDSYNC", "tizne_video_object.sync (serial %d)", video->ec, serial);
+
+   e_client_video_sync_serial_set(video->ec, serial);
+}
+
 static const struct tizen_video_object_interface _e_comp_wl_video_object_interface =
 {
    _e_comp_wl_video_object_cb_destroy,
@@ -309,6 +324,7 @@ static const struct tizen_video_object_interface _e_comp_wl_video_object_interfa
    _e_comp_wl_video_object_cb_unfollow_topmost_visibility,
    _e_comp_wl_video_object_cb_allowed_attribute,
    _e_comp_wl_video_object_cb_disallowed_attribute,
+   _e_comp_wl_video_object_cb_set_sync_serial,
 };
 
 static void
@@ -373,11 +389,40 @@ _e_comp_wl_video_cb_destroy(struct wl_client *client, struct wl_resource *resour
    wl_resource_destroy(resource);
 }
 
+static void
+_e_comp_wl_video_cb_get_surface_provider(struct wl_client *client,
+                                         struct wl_resource *resource,
+                                         uint32_t id,
+                                         struct wl_resource *surface)
+{
+   E_Client *ec;
+   struct wl_resource *new_resource;
+
+   ec = wl_resource_get_user_data(surface);
+   if (!ec)
+     {
+        wl_resource_post_error(resource, 
+                               WL_DISPLAY_ERROR_INVALID_OBJECT,
+                               "invalid object");
+        return;
+     }
+
+   ELOGF("VDSYNC", "get_surface_provider", ec);
+
+   new_resource = wl_resource_create(client,
+                                     &tizen_video_surface_provider_interface,
+                                     wl_resource_get_version(resource),
+                                     id);
+
+   e_client_video_surface_provider_set(ec, new_resource);
+}
+
 static const struct tizen_video_interface _e_comp_wl_video_interface =
 {
    _e_comp_wl_video_cb_get_object,
    _e_comp_wl_video_cb_get_viewport,
    _e_comp_wl_video_cb_destroy,
+   _e_comp_wl_video_cb_get_surface_provider,
 };
 
 static void
@@ -444,7 +489,7 @@ e_comp_wl_video_init(void)
 
    /* try to add tizen_video to wayland globals */
    e_comp->wl_comp_data->video.global =
-      wl_global_create(e_comp_wl->wl.disp, &tizen_video_interface, 1, NULL, _e_comp_wl_video_cb_bind);
+      wl_global_create(e_comp_wl->wl.disp, &tizen_video_interface, 2, NULL, _e_comp_wl_video_cb_bind);
 
    if (!e_comp->wl_comp_data->video.global)
      {
index ce93c4f..d0986d0 100644 (file)
@@ -8,6 +8,7 @@
 
 EINTERN int e_comp_wl_video_init(void);
 EINTERN void e_comp_wl_video_shutdown(void);
+EINTERN Eina_Bool e_client_video_commit_sync(E_Client *ec);
 
 #define C(b,m)              (((b) >> (m)) & 0xFF)
 #define FOURCC_STR(id)      C(id,0), C(id,8), C(id,16), C(id,24)