tpl_wayland_egl_thread: Added an internal API to set sync fence fd to buffer. 68/161968/2
authorjoonbum.ko <joonbum.ko@samsung.com>
Wed, 11 Oct 2017 08:53:58 +0000 (17:53 +0900)
committerjoonbum.ko <joonbum.ko@samsung.com>
Tue, 28 Nov 2017 10:46:53 +0000 (19:46 +0900)
 - The newly created sub-thread waits for draw_done via sync fence fd
  and sends the acquirable event to eventfd of surf_source
  when the drawing is completed.
 - The newly created  sub-thread will be destroyed after sending the acquirable event.

Change-Id: I9740b46ab8cdfab3e3ed289c6c073de836eeb5d6
Signed-off-by: joonbum.ko <joonbum.ko@samsung.com>
src/tpl_wayland_egl_thread.c
src/tpl_wayland_egl_thread.h

index 91d25f4..921cb71 100644 (file)
@@ -30,11 +30,11 @@ typedef struct _twe_tdm_source                      twe_tdm_source;
 typedef struct _twe_del_source                 twe_del_source;
 
 struct _twe_thread_context {
-       int ref_cnt;
-
        GThread *twe_thread;
        GMainLoop *twe_loop;
 
+       int ref_cnt;
+
        twe_tdm_source *tdm_source;
 
        GMutex thread_mutex;
@@ -129,8 +129,11 @@ struct _twe_wl_buffer_info {
 
        GThread *fence_waiting_thread;
 
+       /* for checking draw done */
        tpl_bool_t draw_done;
        tbm_fd draw_done_fence;
+
+       /* for checking released from display server */
        tbm_fd sync_timeline;
        unsigned int sync_timestamp;
 
@@ -1496,14 +1499,17 @@ static void
 __cb_tbm_queue_acquirable_callback(tbm_surface_queue_h surface_queue,
                                                                   void *data)
 {
-       twe_wl_surf_source *source = (twe_wl_surf_source *)data;
+       twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data;
        uint64_t value = 1;
        int ret;
 
-       ret = write(source->event_fd, &value, sizeof(uint64_t));
+       if (surf_source->disp_source->is_vulkan_dpy)
+               return;
+
+       ret = write(surf_source->event_fd, &value, sizeof(uint64_t));
        if (ret == -1) {
                TPL_ERR("failed to send acquirable event. twe_wl_surf_source(%p)",
-                               source);
+                               surf_source);
                return;
        }
 }
@@ -1673,6 +1679,7 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source)
 {
        tbm_surface_h tbm_surface = NULL;
        tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE;
+       twe_wl_buffer_info *buf_info = NULL;
 
        TPL_OBJECT_LOCK(&surf_source->obj);
 
@@ -1695,6 +1702,13 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source)
 
                        tbm_surface_internal_ref(tbm_surface);
 
+                       tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
+                                                                                          (void **)&buf_info);
+                       if (buf_info && buf_info->fence_waiting_thread) {
+                               g_thread_join(buf_info->fence_waiting_thread);
+                               buf_info->fence_waiting_thread = NULL;
+                       }
+
                        TPL_LOG_T("WL_EGL", "[ACQ] tbm_surface(%p) bo(%d)",
                                          tbm_surface,
                                          tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
@@ -2372,6 +2386,77 @@ twe_surface_commit_without_enqueue(twe_surface_h twe_surface,
        TPL_OBJECT_UNLOCK(&surf_source->obj);
 }
 
+static gpointer
+_twe_sync_fence_waiting(gpointer data)
+{
+       twe_wl_buffer_info *buf_info = (twe_wl_buffer_info *)data;
+       twe_wl_surf_source *surf_source = buf_info->surf_source;
+       uint64_t value = 1;
+       int ret;
+
+       if (buf_info->draw_done_fence == -1)
+               return data;
+
+       TRACE_BEGIN("Fence waiting. BO(%d)",
+                           tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
+       /* non worker thread mode */
+       /* TODO: set max wait time */
+       if (tbm_sync_fence_wait(buf_info->draw_done_fence, -1) != 1) {
+               char buf[1024];
+               strerror_r(errno, buf, sizeof(buf));
+               TPL_ERR("Failed to wait sync fence. | error: %d(%s)", errno, buf);
+       }
+       TRACE_END();
+
+       close(buf_info->draw_done_fence);
+       buf_info->draw_done_fence = -1;
+       buf_info->draw_done = TPL_TRUE;
+
+       ret = write(surf_source->event_fd, &value, sizeof(uint64_t));
+       if (ret == -1) {
+               TPL_ERR("failed to send acquirable event. twe_wl_surf_source(%p)",
+                               surf_source);
+       }
+
+       return data;
+}
+
+tpl_result_t
+twe_surface_set_sync_fd(tbm_surface_h tbm_surface, tbm_fd sync_fd)
+{
+       twe_wl_buffer_info *buf_info = NULL;
+
+       tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
+                                                                          (void **)&buf_info);
+       if (!buf_info) {
+               TPL_ERR("wl_buffer_info is not existed in tbm_surface(%p)",
+                               tbm_surface);
+               return TPL_ERROR_INVALID_OPERATION;
+       }
+
+       if (sync_fd == -1) {
+               TPL_WARN("It will be managed with async mode.");
+       }
+
+       if (buf_info->fence_waiting_thread) {
+               g_thread_join(buf_info->fence_waiting_thread);
+               buf_info->fence_waiting_thread = NULL;
+       }
+
+       if (buf_info->draw_done_fence != -1) {
+               close(buf_info->draw_done_fence);
+               buf_info->draw_done_fence = -1;
+       }
+
+       buf_info->draw_done_fence = sync_fd;
+
+       buf_info->fence_waiting_thread = g_thread_new("fence_waiting_thread",
+                                                                                                 _twe_sync_fence_waiting,
+                                                                                                 buf_info);
+
+       return TPL_ERROR_NONE;
+}
+
 tpl_result_t
 twe_check_native_handle_is_wl_display(tpl_handle_t display)
 {
index c366b43..631ac8c 100644 (file)
@@ -84,6 +84,9 @@ twe_surface_set_damage_region(tbm_surface_h tbm_surface,
                                                          int num_rects, const int *rects);
 
 tpl_result_t
+twe_surface_set_sync_fd(tbm_surface_h tbm_surface, tbm_fd wait_fd);
+
+tpl_result_t
 twe_check_native_handle_is_wl_display(tpl_handle_t display);
 
 tpl_result_t