// TIZEN_ONLY(20171114): support a pointer warp
EAPI Eina_Bool ecore_wl2_window_pointer_warp(Ecore_Wl2_Window *win, int x, int y);
//
+// TIZEN_ONLY(20200601): support sync between ui and video
+/*
+ * @typedef Ecore_Wl2_Window_Render_Sync_Type
+ * Type for Ecore_Wl2_Window_Render_Sync_Type to create a file descriptor
+ * which is used for informing render event on the native surface
+ *
+ * @see ecore_wl2_window_render_sync_fd_create
+ *
+ * @ingroup Ecore_Wl2_Window_Group
+ * @since_tizen 6.0
+ */
+typedef enum _Ecore_Wl2_Window_Render_Sync_Type
+{
+ ECORE_WL2_WINDOW_RENDER_SYNC_COMMIT = 0, /**< To get commit event emitted after calling wl_surface_commit */
+ ECORE_WL2_WINDOW_RENDER_SYNC_PRESENT = 1 /**< To get presentation event emitted after the compositor draws */
+} Ecore_Wl2_Window_Render_Sync_Type;
+
+/**
+ * @brief Create a video surface for a given window
+ *
+ * @param win The window to create a video surface
+ * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise
+ *
+ * @ingroup Ecore_Wl2_Window_Group
+ * @since_tizen 6.0
+ */
+EAPI Eina_Bool ecore_wl2_window_video_surface_create(Ecore_Wl2_Window *win);
+
+/**
+ * @brief Get video surface for a given window
+ *
+ * @param win The window to get video surface
+ * @return The wl_surface which is used by this window as a video surface
+ * It provided as void type
+ *
+ * @ingroup Ecore_Wl2_Window_Group
+ * @since_tizen 6.0
+ */
+EAPI void *ecore_wl2_window_video_surface_get(Ecore_Wl2_Window *win);
+
+/**
+ * @brief Destroy a video surface for a given window
+ *
+ * @param win The window to destroy a video surface
+ * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise
+ *
+ * @ingroup Ecore_Wl2_Window_Group
+ * @since_tizen 6.0
+ */
+EAPI Eina_Bool ecore_wl2_window_video_surface_destroy(Ecore_Wl2_Window *win);
+
+/**
+ * @brief Set video surface for a given window to synchronized mode
+ * the default commit behaviour is desynchronized mode.
+ *
+ * @param win The window to set video surface to synchronized mode
+ * @param sync EINA_TRUE to set video surface to synchronized mode,
+ * EINA_FALSE to set video surface to desynchronized mode
+ * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise
+ *
+ * @ingroup Ecore_Wl2_Window_Group
+ * @since_tizen 6.0
+ */
+EAPI Eina_Bool ecore_wl2_window_video_surface_sync_set(Ecore_Wl2_Window *win, Eina_Bool sync);
+
+/**
+ * @brief Set destination area of video surface for a given window
+ *
+ * @param win The window to set destination area of video surface
+ * @param x X position of destination area
+ * @param y Y position of destination area
+ * @param w Width of destination area
+ * @param h Height of destination area
+ * @return @c EINA_TRUE on success, @c EINA_FALSE otherwise
+ *
+ * @ingroup Ecore_Wl2_Window_Group
+ * @since_tizen 6.0
+ */
+EAPI Eina_Bool ecore_wl2_window_video_surface_destination_set(Ecore_Wl2_Window *win, int x, int y, int w, int h);
+
+
+/**
+ * @brief Create a file descriptor for rendering sync for a given window
+ *
+ * @param win The window to create a file descriptor for rendering sync
+ * @param sync_type The Ecore_Wl2_Window_Render_Sync_Type to create a file descriptor
+ * ECORE_WL2_WINDOW_RENDER_SYNC_COMMIT to get commit event,
+ * ECORE_WL2_WINDOW_RENDER_SYNC_PRESENT to get presentation event
+ * @return The file descriptor. It must be closed manually by the caller using `close`
+ *
+ * @see Ecore_Wl2_Window_Group
+ *
+ * @ingroup Ecore_Wl2_Window_Group
+ * @since_tizen 6.0
+ */
+EAPI int ecore_wl2_window_render_sync_fd_create(Ecore_Wl2_Window *win, Ecore_Wl2_Window_Render_Sync_Type sync_type);
+//
//TIZEN_ONLY(20171108): add a new API to ecore_wl2_sync
/** @internal */
#include "ecore_wl2_private.h"
#include "efl-hints-client-protocol.h"
+// TIZEN_ONLY(20200601): support sync between ui and video
+#include <wayland-tbm-client.h>
+//
+
//TIZEN_ONLY(20171216): add ecore_wl2_window_find
/* local variables */
static Eina_Hash *_windows = NULL;
window->tz_resource = NULL;
//
+ // TIZEN_ONLY(20200601): support sync between ui and video
+ if (window->video.viewport) tizen_viewport_destroy(window->video.viewport);
+ if (window->video.subsurface) wl_subsurface_destroy(window->video.subsurface);
+ if (window->video.surface) wl_surface_destroy(window->video.surface);
+ //
+
if (window->callback) wl_callback_destroy(window->callback);
window->callback = NULL;
}
//
+// TIZEN_ONLY(20200601): support sync between ui and video
+/* The video surface created in ecore_wl2 is used for informing the video area.
+ And there is another video surface created on the player side. The player
+ video surface is filled with video data, and the garbage data of ecore_wl2
+ video surface can interfere with video data. So fill it with zero here. */
+void
+buffer_fill_zero(tbm_surface_h surface)
+{
+ tbm_surface_info_s info;
+ int *img;
+ unsigned int height, stride;
+ unsigned int i, j;
+
+ tbm_surface_map(surface, TBM_OPTION_WRITE, &info);
+
+ img = (int *)info.planes[0].ptr;
+ height = tbm_surface_get_height(surface);
+ stride = info.planes[0].stride;
+
+ memset(img, 0x0, sizeof(int) * stride * height);
+
+ tbm_surface_unmap(surface);
+}
+
+
+EAPI Eina_Bool
+ecore_wl2_window_video_surface_create(Ecore_Wl2_Window *win)
+{
+ Ecore_Wl2_Display *display;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
+ if (win->video.surface) return EINA_TRUE;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, EINA_FALSE);
+ display = win->display;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.compositor, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.subcompositor, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(display->wl.tz_policy, EINA_FALSE);
+
+ win->video.surface = wl_compositor_create_surface(display->wl.compositor);
+
+ if (!win->video.surface)
+ {
+ ERR("Failed to create video surface");
+ return EINA_FALSE;
+ }
+
+ win->video.subsurface =
+ wl_subcompositor_get_subsurface(display->wl.subcompositor,
+ win->video.surface, win->surface);
+
+ if (!win->video.subsurface)
+ {
+ ERR("Failed to create video subsurface");
+ wl_surface_destroy(win->video.surface);
+ win->video.surface = NULL;
+ return EINA_FALSE;
+ }
+
+ tizen_policy_place_subsurface_below_parent(display->wl.tz_policy, win->video.subsurface);
+
+ struct wayland_tbm_client *tbm_client;
+ tbm_surface_h surface;
+ struct wl_buffer *wl_buffer;
+
+ tbm_client = wayland_tbm_client_init(display->wl.display);
+ surface = tbm_surface_create(2, 2, TBM_FORMAT_ARGB8888);
+ wl_buffer = wayland_tbm_client_create_buffer(tbm_client, surface);
+ buffer_fill_zero(surface);
+
+ /* need to attach surface */
+ wl_surface_attach(win->video.surface, wl_buffer, 0, 0);
+ wl_surface_commit(win->video.surface);
+
+ return EINA_TRUE;
+}
+
+EAPI void *
+ecore_wl2_window_video_surface_get(Ecore_Wl2_Window *win)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win, NULL);
+ return win->video.surface;
+}
+
+EAPI Eina_Bool
+ecore_wl2_window_video_surface_destroy(Ecore_Wl2_Window *win)
+{
+ Ecore_Wl2_Display *display;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, EINA_FALSE);
+
+ display = win->display;
+
+ if (display->wl.tz_video)
+ {
+ tizen_video_destroy(display->wl.tz_video);
+ display->wl.tz_video = NULL;
+ }
+
+ if (win->video.viewport)
+ {
+ tizen_viewport_destroy(win->video.viewport);
+ win->video.viewport = NULL;
+ }
+
+ if (win->video.subsurface)
+ {
+ wl_subsurface_destroy(win->video.subsurface);
+ win->video.subsurface = NULL;
+ }
+
+ if (win->video.surface)
+ {
+ wl_surface_destroy(win->video.surface);
+ win->video.surface = NULL;
+ }
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_wl2_window_video_surface_sync_set(Ecore_Wl2_Window *win, Eina_Bool sync)
+{
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win->video.subsurface, EINA_FALSE);
+
+ sync = !!sync;
+ if (win->video.sync == sync) return EINA_TRUE;
+
+ win->video.sync = sync;
+
+ if (sync)
+ wl_subsurface_set_sync(win->video.subsurface);
+ else
+ wl_subsurface_set_desync(win->video.subsurface);
+
+ return EINA_TRUE;
+}
+
+EAPI Eina_Bool
+ecore_wl2_window_video_surface_destination_set(Ecore_Wl2_Window *win, int x, int y, int w, int h)
+{
+ Ecore_Wl2_Display *display;
+ struct wl_registry *registry;
+ Eina_Iterator *globals;
+ Ecore_Wl2_Global *global;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win->display, EINA_FALSE);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win->video.surface, EINA_FALSE);
+
+ display = win->display;
+
+ if (!win->video.viewport)
+ {
+ if (!display->wl.tz_video)
+ {
+ registry = ecore_wl2_display_registry_get(display);
+ if (!registry) return EINA_FALSE;
+
+ globals = ecore_wl2_display_globals_get(display);
+ if (!globals) return EINA_FALSE;
+
+ EINA_ITERATOR_FOREACH(globals, global)
+ {
+ if (strcmp(global->interface, "tizen_video") == 0)
+ {
+ display->wl.tz_video = wl_registry_bind(registry, global->id, &tizen_video_interface, 1);
+ break;
+ }
+ }
+ }
+
+ if (!display->wl.tz_video)
+ {
+ ERR("Failed to bind tizen video interface");
+ return EINA_FALSE;
+ }
+
+ win->video.viewport = tizen_video_get_viewport(display->wl.tz_video, win->video.surface);
+ }
+
+ if (!win->video.viewport)
+ {
+ ERR("Failed to get video viewport");
+ return EINA_FALSE;
+ }
+
+ tizen_viewport_set_destination(win->video.viewport, x, y, w, h);
+ wl_surface_commit(win->video.surface);
+
+ return EINA_TRUE;
+}
+
+EAPI int
+ecore_wl2_window_render_sync_fd_create(Ecore_Wl2_Window *win, Ecore_Wl2_Window_Render_Sync_Type sync_type)
+{
+ int sync_fd = -1;
+
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win, sync_fd);
+ EINA_SAFETY_ON_NULL_RETURN_VAL(win->egl_win, sync_fd);
+
+ switch (sync_type)
+ {
+ case ECORE_WL2_WINDOW_RENDER_SYNC_COMMIT:
+ sync_fd = wl_egl_window_tizen_create_commit_sync_fd(win->egl_win->native_win);
+ break;
+ case ECORE_WL2_WINDOW_RENDER_SYNC_PRESENT:
+ sync_fd = wl_egl_window_tizen_create_presentation_sync_fd(win->egl_win->native_win);
+ break;
+ default:
+ break;
+ }
+
+ return sync_fd;
+}
+//
//TIZEN_ONLY: ecore_wl2: add ecore_wl_window_video_has
EAPI void