Supports the video shell for synchronization with video player. 49/315149/2 tizen
authorWonsik Jung <sidein@samsung.com>
Thu, 25 Jul 2024 12:57:12 +0000 (21:57 +0900)
committerWonsik Jung <sidein@samsung.com>
Thu, 1 Aug 2024 05:58:21 +0000 (14:58 +0900)
Appends new API to support for synchronization window surface and video player.
It is different for previous solution.

Change-Id: Ifa12cec7bbf6205d8970d761ec6e83e9a5358471

packaging/efl.spec
src/lib/ecore_wl2/Ecore_Wayland2.h
src/lib/ecore_wl2/ecore_wl2_display.c
src/lib/ecore_wl2/ecore_wl2_private.h
src/lib/ecore_wl2/ecore_wl2_subsurf.c
src/lib/ecore_wl2/ecore_wl2_window.c
src/lib/ecore_wl2/meson.build

index 88dfd4c..d5203c7 100644 (file)
@@ -49,6 +49,7 @@ BuildRequires:  pkgconfig(tizen-policy-ext-client)
 BuildRequires:  pkgconfig(wtz-foreign-client)
 BuildRequires:  pkgconfig(wtz-screen-client)
 BuildRequires:  pkgconfig(wtz-shell-client)
+BuildRequires:  pkgconfig(wtz-video-shell-client)
 BuildRequires:  pkgconfig(relative-pointer-unstable-v1-client)
 BuildRequires:  pkgconfig(pointer-constraints-unstable-v1-client)
 BuildRequires:  wayland-protocols
index b5faec2..6befb3a 100644 (file)
@@ -82,6 +82,22 @@ typedef struct _Ecore_Wl2_Egl_Window Ecore_Wl2_Egl_Window;
  */
 typedef struct _Ecore_Wl2_Subsurface Ecore_Wl2_Subsurface;
 
+/**
+ * @ingroup Ecore_Wl2_Group
+ *
+ * @typedef Ecore_Wl2_VideoShell_Surface
+ * Type for Ecore_Wl2_VideoShell_Surface
+ */
+typedef struct _Ecore_Wl2_VideoShell_Surface Ecore_Wl2_VideoShell_Surface;
+
+/**
+ * @ingroup Ecore_Wl2_Group
+ *
+ * @typedef Ecore_Wl2_VideoShell_Surface_Wrapper
+ * Type for Ecore_Wl2_VideoShell_Surface_Wrapper
+ */
+typedef struct _Ecore_Wl2_VideoShell_Surface_Wrapper Ecore_Wl2_VideoShell_Surface_Wrapper;
+
 /*
  * @ingroup Ecore_Wl2_Group
  *
@@ -1290,6 +1306,221 @@ EAPI void ecore_wl2_window_background_blur_set(Ecore_Wl2_Window *window, int rad
  */
 EAPI int ecore_wl2_window_background_blur_get(Ecore_Wl2_Window *window);
 
+////////////////////////////////////////////////////////////////////////////////////////////
+/// Supports new video shell
+
+/**
+* Creates a new Video Shell Surface object
+*
+* @param[in] window Window to create the video shell surface for
+*
+* @return A newly created Ecore_Wl2_VideoShell_Surface object or NULL if an error occurred
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI Ecore_Wl2_VideoShell_Surface * Ecore_Wl2_VideoShell_Surface_new(Ecore_Wl2_Window *window);
+
+/**
+* Frees the memory used by the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to be freed
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_del(Ecore_Wl2_VideoShell_Surface *videoShellSurface);
+
+/**
+* Retrieves the handle associated with the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to retrieve the handle from
+*
+* @return The handle associated with the given Video Shell Surface object
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI const char * Ecore_Wl2_VideoShell_Surface_handle_get(Ecore_Wl2_VideoShell_Surface *videoShellSurface);
+
+/**
+* Retrieves the underlying Wayland surface associated with the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to retrieve the surface from
+*
+* @return The underlying Wayland surface associated with the given Video Shell Surface object
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI struct wl_surface * Ecore_Wl2_VideoShell_Surface_surface_get(Ecore_Wl2_VideoShell_Surface *videoShellSurface);
+
+/**
+* Maps (shows) the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to map
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_map(Ecore_Wl2_VideoShell_Surface *videoShellSurface);
+
+/**
+* Unmaps (hides) the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to unmap
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_unmap(Ecore_Wl2_VideoShell_Surface *videoShellSurface);
+
+/**
+* Places the given Video Shell Surface object above its sibling in the stacking order
+*
+* @param[in] videoShellSurface The Video Shell Surface object to move up
+* @param[in] sibling The sibling Video Shell Surface object to use as reference point
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_place_above(Ecore_Wl2_VideoShell_Surface *videoShellSurface, Ecore_Wl2_VideoShell_Surface *sibling);
+
+/**
+* Places the given Video Shell Surface object below its sibling in the stacking order
+*
+* @param[in] videoShellSurface The Video Shell Surface object to move down
+* @param[in] sibling The sibling Video Shell Surface object to use as reference point
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_place_below(Ecore_Wl2_VideoShell_Surface *videoShellSurface, Ecore_Wl2_VideoShell_Surface *sibling);
+
+/**
+* Sets the position of the given Video Shell Surface object relative to its parent
+*
+* @param[in] videoShellSurface The Video Shell Surface object to set the position for
+* @param[in] x X coordinate of the position
+* @param[in] y Y coordinate of the position
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_set_position(Ecore_Wl2_VideoShell_Surface *videoShellSurface, int32_t x, int32_t y);
+
+/**
+* Sets the destination size of the given Video Shell Surface object within its parent
+*
+* @param[in] videoShellSurface The Video Shell Surface object to set the destination size for
+* @param[in] width Width of the destination area
+* @param[in] height Height of the destination area
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_set_destination(Ecore_Wl2_VideoShell_Surface *videoShellSurface, int32_t width, int32_t height);
+
+/**
+* Sets the transformation of the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to set the transformation for
+* @param[in] transform Transformation value (@see #Ecore_Wl2_Transform)
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_set_transform(Ecore_Wl2_VideoShell_Surface *videoShellSurface, int32_t transform);
+
+/**
+* Enables sync mode for the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to enable sync mode for
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_set_sync(Ecore_Wl2_VideoShell_Surface *videoShellSurface);
+
+/**
+* Enables desync mode for the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to disable sync mode for
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_set_desync(Ecore_Wl2_VideoShell_Surface *videoShellSurface);
+
+/**
+* Commits changes made to the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to commit changes for
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_commit(Ecore_Wl2_VideoShell_Surface *videoShellSurface);
+
+/**
+* Creates a wrapper around the given Video Shell Surface object
+*
+* @param[in] videoShellSurface The Video Shell Surface object to wrap
+*
+* @return A newly created Ecore_Wl2_VideoShell_Surface_Wrapper object or NULL if an error occurred
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Wrapper_Group
+* @since_tizen 9.0
+*/
+EAPI Ecore_Wl2_VideoShell_Surface_Wrapper * Ecore_Wl2_VideoShell_Surface_wrapper_new(Ecore_Wl2_VideoShell_Surface *videoShellSurface);
+
+/**
+* Destroys the given Video Shell Surface Wrapper object and releases all resources associated with it.
+* Must be destroyed before Ecore_Wl2_VideoShell_Surface is destroyed.
+*
+* @param[in] wrapper The Video Shell Surface Wrapper object to destroy
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Wrapper_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_wrapper_destroy(Ecore_Wl2_VideoShell_Surface_Wrapper *wrapper);
+
+/**
+* Updates the geometry of the given Video Shell Surface Wrapper object
+*
+* @param[in] wrapper The Video Shell Surface Wrapper object to update the geometry for
+* @param[in] x X coordinate of the top left corner of the geometry rectangle
+* @param[in] y Y coordinate of the top left corner of the geometry rectangle
+* @param[in] width Width of the geometry rectangle
+* @param[in] height Height of the geometry rectangle
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Wrapper_Group
+* @since_tizen 9.0
+*/
+EAPI void Ecore_Wl2_VideoShell_Surface_wrapper_update_geometry(Ecore_Wl2_VideoShell_Surface_Wrapper *wrapper, int32_t x, int32_t y, int32_t width, int32_t height);
+
+/**
+* Commits changes made to the given Video Shell Surface Wrapper object
+*
+* @param[in] wrapper The Video Shell Surface Wrapper object to commit changes for
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Wrapper_Group
+* @since_tizen 9.0
+*/
+void Ecore_Wl2_VideoShell_Surface_wrapper_commit(Ecore_Wl2_VideoShell_Surface_Wrapper *wrapper);
+
+/**
+* Retrieves the handle associated with the given Video Shell Surface Wrapper object
+*
+* @param[in] videoShellSurface The Video Shell Surface Wrapper object to retrieve the handle from
+*
+* @return The handle associated with the given Video Shell Surface Wrapper object
+*
+* @ingroup Ecore_Wl2_VideoShell_Surface_Wrapper_Group
+* @since_tizen 9.0
+*/
+EAPI char * Ecore_Wl2_VideoShell_Surface_wrapper_handle_get(Ecore_Wl2_VideoShell_Surface_Wrapper *wrapper);
+
 # undef EAPI
 # define EAPI
 
index 4649688..c87b319 100644 (file)
@@ -1132,6 +1132,14 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const
                            &wtz_blur_manager_interface, 1);
      }
 //
+   // TIZEN_ONLY(20230801) : support video shell
+      else if (!strcmp(interface, "wtz_video_shell"))
+        {
+           ewd->wl.video_shell =
+             wl_registry_bind(registry, id,
+                              &wtz_video_shell_interface, version);
+        }
+   //
    //
 
 event:
@@ -1260,6 +1268,8 @@ _ecore_wl2_display_globals_cleanup(Ecore_Wl2_Display *ewd)
    if (ewd->wl.pointer_constraints)
      zwp_pointer_constraints_v1_destroy(ewd->wl.pointer_constraints);
    if (ewd->wl.tz_blur_manager) wtz_blur_manager_destroy(ewd->wl.tz_blur_manager);
+   if (ewd->wl.video_shell)
+     wtz_video_shell_destroy(ewd->wl.video_shell);
 //
 
    if (ewd->wl.registry) wl_registry_destroy(ewd->wl.registry);
index 9f88cc0..a09814e 100644 (file)
 
 #include <wtz-blur-client-protocol.h>
 
+// TIZEN_ONLY(20240604) : video shell
+#include <wayland-extension/wtz-video-shell-client-protocol.h>
+
+//
+
 extern int _ecore_wl2_log_dom;
 extern Eina_Bool no_session_recovery;
 
@@ -179,6 +184,8 @@ struct _Ecore_Wl2_Display
         struct zwp_pointer_constraints_v1 *pointer_constraints;
         //
         struct wtz_blur_manager *tz_blur_manager;
+        // TIZEN_ONLY(20240604) : support video shell
+        struct wtz_video_shell *video_shell;
      } wl;
 
    uint32_t serial;
@@ -254,6 +261,41 @@ struct _Ecore_Wl2_Subsurface
    Eina_Bool sync : 1;
 };
 
+struct _Ecore_Wl2_VideoShell_Surface
+{
+   EINA_INLIST;
+   Ecore_Wl2_Window *parent;
+
+   int32_t x, y, width, height;
+   struct
+     {
+        struct wl_surface *surface;
+        struct wl_subsurface *subsurface;
+        struct wtz_video_exported_viewport *resource;
+        char *handle;
+     } wl;
+
+   int32_t transform;
+   Eina_Bool sync : 1;
+   Eina_Bool map : 1;
+};
+
+struct _Ecore_Wl2_VideoShell_Surface_Wrapper
+{
+   int32_t x, y, width, height;
+   struct
+     {
+        struct wl_surface *surface;
+        struct wl_subsurface *subsurface;
+        struct wtz_video_exported_viewport *resource;
+        char *handle;
+     } wl;
+
+   int32_t transform;
+   Eina_Bool sync : 1;
+   Eina_Bool map : 1;
+};
+
 struct _Ecore_Wl2_Aux_Hint
 {
    EINA_INLIST;
@@ -353,6 +395,7 @@ struct _Ecore_Wl2_Window
    } weight;
 
    Eina_Inlist *subsurfs;
+   Eina_Inlist *videoshell_subsurfs;
    Eina_List *supported_aux_hints;
    Eina_Inlist *frame_callbacks;
 
index 6f28496..23f6b27 100644 (file)
@@ -645,3 +645,363 @@ ecore_wl2_subsurface_aux_hint_set(Ecore_Wl2_Subsurface *subsurface, const char *
      tizen_policy_add_aux_hint(display->wl.tz_policy, subsurface->wl.surface, id, hint, val);
 }
 //
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/// Support Video Shell (2024-06-05)
+
+static void
+video_exported_viewport_cb_handle(void *data, struct wtz_video_exported_viewport *wtz_video_exported_viewport, const char *handle)
+{
+    Ecore_Wl2_VideoShell_Surface *subSurface = data;
+    ERR("%s: call video_exported_viewport_cb_handle\n",__FUNCTION__);
+
+    if (subSurface->wl.handle)
+        free(subSurface->wl.handle);
+
+    subSurface->wl.handle = strdup(handle);
+    ERR("%s: get video shell handle %s\n",__FUNCTION__, subSurface->wl.handle);
+}
+
+static const struct wtz_video_exported_viewport_listener video_exported_viewport_listener = {
+    video_exported_viewport_cb_handle,
+};
+
+EAPI Ecore_Wl2_VideoShell_Surface *
+Ecore_Wl2_VideoShell_Surface_new(Ecore_Wl2_Window *window)
+{
+   Ecore_Wl2_Display *display;
+   Ecore_Wl2_VideoShell_Surface *videoShellSurface;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(window->surface, NULL);
+
+   display = window->display;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.compositor, NULL);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.subcompositor, NULL);
+
+   videoShellSurface = calloc(1, sizeof(Ecore_Wl2_VideoShell_Surface));
+   if (!videoShellSurface) return NULL;
+
+   videoShellSurface->parent = window;
+
+   videoShellSurface->wl.surface = wl_compositor_create_surface(display->wl.compositor);
+   if (!videoShellSurface->wl.surface)
+     {
+        ERR("Failed to create surface");
+        goto surf_err;
+     }
+
+   videoShellSurface->wl.subsurface =
+     wl_subcompositor_get_subsurface(display->wl.subcompositor,
+                                     videoShellSurface->wl.surface, window->surface);
+   if (!videoShellSurface->wl.subsurface)
+     {
+        ERR("Could not create subsurface");
+        goto sub_surf_err;
+     }
+
+   ERR("%s: create video shell wayland subsurface: %p\n",__FUNCTION__,videoShellSurface->wl.subsurface );
+
+   videoShellSurface->wl.resource = wtz_video_shell_export_viewport(display->wl.video_shell, videoShellSurface->wl.subsurface);
+   wtz_video_exported_viewport_add_listener(videoShellSurface->wl.resource, &video_exported_viewport_listener, videoShellSurface);
+
+   /* A video shell surface is initially in the synchronized mode. */
+   videoShellSurface->sync = EINA_TRUE;
+
+   window->videoshell_subsurfs =
+     eina_inlist_append(window->videoshell_subsurfs, EINA_INLIST_GET(videoShellSurface));
+
+   wl_display_roundtrip(display->wl.display);
+
+   ERR("%s: create video shell surface: %p\n",__FUNCTION__,videoShellSurface);
+   return videoShellSurface;
+
+sub_surf_err:
+   wl_surface_destroy(videoShellSurface->wl.surface);
+
+surf_err:
+   free(videoShellSurface);
+   return NULL;
+}
+
+void
+_Ecore_Wl2_VideoShell_Surface_free(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+   Ecore_Wl2_Window *parent;
+
+   if(videoShellSurface->wl.resource)
+   {
+     wtz_video_exported_viewport_destroy(videoShellSurface->wl.resource);
+   }
+
+   if(videoShellSurface->wl.subsurface)
+   {
+     wl_subsurface_destroy(videoShellSurface->wl.subsurface);
+   }
+
+   if(videoShellSurface->wl.surface)
+   {
+     wl_surface_destroy(videoShellSurface->wl.surface);
+   }
+
+   if(videoShellSurface->wl.handle)
+   {
+     ERR("%s: free video shell handle %s\n",__FUNCTION__, videoShellSurface->wl.handle);
+     free((char *)videoShellSurface->wl.handle);
+   }
+
+   Ecore_Wl2_VideoShell_Surface_unmap(videoShellSurface);
+
+   parent = videoShellSurface->parent;
+   if (parent)
+     {
+        parent->videoshell_subsurfs =
+          eina_inlist_remove(parent->videoshell_subsurfs, EINA_INLIST_GET(videoShellSurface));
+     }
+
+   ERR("%s: free video shell surface: %p\n",__FUNCTION__,videoShellSurface);
+   free(videoShellSurface);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_del(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+   EINA_SAFETY_ON_NULL_RETURN(videoShellSurface);
+
+   _Ecore_Wl2_VideoShell_Surface_free(videoShellSurface);
+}
+
+EAPI const char *
+Ecore_Wl2_VideoShell_Surface_handle_get(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(videoShellSurface, NULL);
+
+   ERR("%s: videoShellSurface : %p, handle(%p): %s\n",__FUNCTION__, videoShellSurface, videoShellSurface->wl.handle, videoShellSurface->wl.handle);
+   return videoShellSurface->wl.handle;
+}
+
+EAPI struct wl_surface *
+Ecore_Wl2_VideoShell_Surface_surface_get(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+   EINA_SAFETY_ON_NULL_RETURN_VAL(videoShellSurface, NULL);
+
+   return videoShellSurface->wl.surface;
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_map(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+  if (videoShellSurface->map)
+  {
+    return;
+  }
+
+  videoShellSurface->map = EINA_TRUE;
+  ERR("%s: map with  video shell surface: %p\n",__FUNCTION__,videoShellSurface);
+  wtz_video_exported_viewport_map(videoShellSurface->wl.resource);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_unmap(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+  if (videoShellSurface->map)
+  {
+    return;
+  }
+
+  videoShellSurface->map = EINA_FALSE;
+  ERR("%s: unmap with  video shell surface: %p\n",__FUNCTION__,videoShellSurface);
+  wtz_video_exported_viewport_unmap(videoShellSurface->wl.resource);
+}
+
+
+void
+_Ecore_Wl2_VideoShell_Surface_place_surface_stack(Ecore_Wl2_VideoShell_Surface *videoShellSurface, Ecore_Wl2_VideoShell_Surface *sibling, Eina_Bool above)
+{
+   struct wl_surface *psurface;
+
+   EINA_SAFETY_ON_NULL_RETURN(videoShellSurface);
+
+   /* every subsurface is created by window base now,
+      someday we could use another subsurface as a parent */
+   if (sibling)
+     {
+         if (videoShellSurface->parent != sibling->parent)
+          {
+             ERR("Check parent of subsurf(%p) and other(%p)", videoShellSurface, sibling);
+             return;
+          }
+        if (above)
+          wl_subsurface_place_above(videoShellSurface->wl.subsurface, sibling->wl.surface);
+        else
+          wl_subsurface_place_below(videoShellSurface->wl.subsurface, sibling->wl.surface);
+     }
+   else
+     {
+        psurface = ecore_wl2_window_surface_get(videoShellSurface->parent);
+        if (above)
+          wl_subsurface_place_above(videoShellSurface->wl.subsurface, psurface);
+        else
+          wl_subsurface_place_below(videoShellSurface->wl.subsurface, psurface);
+     }
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_place_above(Ecore_Wl2_VideoShell_Surface *videoShellSurface, Ecore_Wl2_VideoShell_Surface *sibling)
+{
+  _Ecore_Wl2_VideoShell_Surface_place_surface_stack(videoShellSurface, sibling, EINA_TRUE);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_place_below(Ecore_Wl2_VideoShell_Surface *videoShellSurface, Ecore_Wl2_VideoShell_Surface *sibling)
+{
+  ERR("%s: Ecore_Wl2_VideoShell_Surface_place_below  videoShellSurface: %p, sibling: %p\n",__FUNCTION__, videoShellSurface, sibling);
+  _Ecore_Wl2_VideoShell_Surface_place_surface_stack(videoShellSurface, sibling, EINA_FALSE);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_set_position(Ecore_Wl2_VideoShell_Surface *videoShellSurface, int32_t x, int32_t y)
+{
+    if (videoShellSurface->x == x && videoShellSurface->y == y)
+    {
+        return;
+    }
+
+    videoShellSurface->x = x;
+    videoShellSurface->y = y;
+
+    wl_subsurface_set_position(videoShellSurface->wl.subsurface, x, y);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_set_destination(Ecore_Wl2_VideoShell_Surface *videoShellSurface,int32_t width, int32_t height)
+{
+    if ((width <= 0 || height <= 0) ||
+        (videoShellSurface->width == width && videoShellSurface->height == height)) {
+        return;
+    }
+
+    videoShellSurface->width = width;
+    videoShellSurface->height = height;
+
+    wtz_video_exported_viewport_set_destination(videoShellSurface->wl.resource, width, height);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_set_transform(Ecore_Wl2_VideoShell_Surface *videoShellSurface, int32_t transform)
+{
+    if ((transform < 0 ||
+        transform > 3) ||
+        (videoShellSurface->transform == transform))
+    {
+        return;
+    }
+
+    videoShellSurface->transform = transform;
+    wtz_video_exported_viewport_set_transform(videoShellSurface->wl.resource, transform);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_set_sync(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+    if (videoShellSurface->sync)
+    {
+        return;
+    }
+
+    videoShellSurface->sync = true;
+
+    wl_subsurface_set_sync(videoShellSurface->wl.subsurface);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_set_desync(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+    if (!videoShellSurface->sync)
+    {
+        return;
+    }
+
+    videoShellSurface->sync = false;
+
+    wl_subsurface_set_desync(videoShellSurface->wl.subsurface);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_commit(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+    wl_surface_commit(videoShellSurface->wl.surface);
+}
+
+// Must be destroyed before struct video_exported_viewport is destroyed.
+EAPI Ecore_Wl2_VideoShell_Surface_Wrapper *
+Ecore_Wl2_VideoShell_Surface_wrapper_new(Ecore_Wl2_VideoShell_Surface *videoShellSurface)
+{
+    Ecore_Wl2_VideoShell_Surface_Wrapper *wrapper;
+
+    wrapper = calloc(1, sizeof(Ecore_Wl2_VideoShell_Surface));
+    if (!wrapper) return NULL;
+
+    wrapper->x = videoShellSurface->x;
+    wrapper->y = videoShellSurface->y;
+    wrapper->width = videoShellSurface->width;
+    wrapper->height = videoShellSurface->height;
+    wrapper->transform = videoShellSurface->transform;
+    wrapper->map = videoShellSurface->map;
+    wrapper->sync = videoShellSurface->sync;
+
+    wrapper->wl.handle = strdup(videoShellSurface->wl.handle);
+    wrapper->wl.surface = wl_proxy_create_wrapper(videoShellSurface->wl.surface);
+    wrapper->wl.subsurface = wl_proxy_create_wrapper(videoShellSurface->wl.subsurface);
+    wrapper->wl.resource = wl_proxy_create_wrapper(videoShellSurface->wl.resource);
+
+    ERR("%s: create wrapper %p\n",__FUNCTION__, wrapper);
+    ERR("%s: wrapper handle %s\n",__FUNCTION__, wrapper->wl.handle);
+    ERR("%s: wrapper surface %p\n",__FUNCTION__, wrapper->wl.surface);
+    ERR("%s: wrapper sub surface %p\n",__FUNCTION__, wrapper->wl.subsurface);
+    ERR("%s: wrapper resource %p\n",__FUNCTION__, wrapper->wl.resource);
+    return wrapper;
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_wrapper_destroy(Ecore_Wl2_VideoShell_Surface_Wrapper *wrapper)
+{
+    ERR("%s: destroy wrapper %p\n",__FUNCTION__, wrapper);
+    wl_proxy_wrapper_destroy(wrapper->wl.resource);
+    wl_proxy_wrapper_destroy(wrapper->wl.subsurface);
+    wl_proxy_wrapper_destroy(wrapper->wl.surface);
+    free(wrapper->wl.handle);
+    free(wrapper);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_wrapper_update_geometry(Ecore_Wl2_VideoShell_Surface_Wrapper *wrapper, int32_t x, int32_t y, int32_t width, int32_t height)
+{
+    wrapper->x = x;
+    wrapper->y = y;
+    wrapper->width = width;
+    wrapper->height = height;
+    ERR("%s: update wrapper geometry %p, x[%d], y[%d], w[%d], h[%d]\n",__FUNCTION__, wrapper, x, y, width, height);
+}
+
+EAPI void
+Ecore_Wl2_VideoShell_Surface_wrapper_commit(Ecore_Wl2_VideoShell_Surface_Wrapper *wrapper)
+{
+    ERR("%s: call wl_subsurface_set_position, subsurface: %p, x[%d], y[%d]\n",__FUNCTION__, wrapper->wl.subsurface, wrapper->x, wrapper->y);
+    wl_subsurface_set_position(wrapper->wl.subsurface, wrapper->x, wrapper->y);
+    ERR("%s: call wtz_video_exported_viewport_set_destination, resource: %p, w[%d], h[%d]\n",__FUNCTION__, wrapper->wl.resource, wrapper->width, wrapper->height);
+    wtz_video_exported_viewport_set_destination(wrapper->wl.resource, wrapper->width, wrapper->height);
+    ERR("%s: call wl_surface_commit, %p, wayland surfce: %p\n",__FUNCTION__, wrapper, wrapper->wl.subsurface);
+    wl_surface_commit(wrapper->wl.surface);
+}
+
+EAPI char *
+Ecore_Wl2_VideoShell_Surface_wrapper_handle_get(Ecore_Wl2_VideoShell_Surface_Wrapper *wrapper)
+{
+    EINA_SAFETY_ON_NULL_RETURN_VAL(wrapper, NULL);
+
+    ERR("%s: videoShellSurfaceWrapper : %p, handle(%p): %s\n",__FUNCTION__, wrapper, wrapper->wl.handle, wrapper->wl.handle);
+    return wrapper->wl.handle;
+}
index a2139f3..d04b31c 100644 (file)
@@ -1569,6 +1569,7 @@ ecore_wl2_window_free(Ecore_Wl2_Window *window)
    Ecore_Wl2_Display *display;
    Ecore_Wl2_Input *input;
    Ecore_Wl2_Subsurface *subsurf;
+   Ecore_Wl2_VideoShell_Surface *videoShellSurface;
    Eina_Inlist *tmp;
    Ecore_Wl2_Window_Aux_Hint *hint;
 
@@ -1599,6 +1600,9 @@ ecore_wl2_window_free(Ecore_Wl2_Window *window)
    EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp, subsurf)
      _ecore_wl2_subsurf_free(subsurf);
 
+   EINA_INLIST_FOREACH_SAFE(window->videoshell_subsurfs, tmp, videoShellSurface)
+     _Ecore_Wl2_VideoShell_Surface_free(videoShellSurface);
+
    _ecore_wl2_window_aux_hint_free(window);
 
    // TIZEN_ONLY(20171112) : support tizen protocols
index 0e68a89..16f97d4 100644 (file)
@@ -36,6 +36,7 @@ ecore_wl2_ext_deps += [
   dependency('wtz-foreign-client'),
   dependency('wtz-screen-client'),
   dependency('wtz-shell-client'),
+  dependency('wtz-video-shell-client'),
   dependency('relative-pointer-unstable-v1-client'),
   dependency('pointer-constraints-unstable-v1-client'),
   dependency('wtz-blur-client'),