tpl_wayland_egl_thread: Modified the buffer_info to wait for draw done without using... 75/161975/3
authorjoonbum.ko <joonbum.ko@samsung.com>
Wed, 8 Nov 2017 09:59:27 +0000 (18:59 +0900)
committerjoonbum.ko <joonbum.ko@samsung.com>
Tue, 28 Nov 2017 11:17:28 +0000 (20:17 +0900)
 - twe_thread can not process any events while it is waiting for buffer draw done.
 - This is a temporary structure for guaranteeing buffer sync,
  and is not the best solution, so there are many parts to be improved.

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

index 7f12646..661b64b 100644 (file)
@@ -132,8 +132,6 @@ struct _twe_wl_buffer_info {
        int *rects;
        tpl_bool_t need_to_commit;
 
-       GThread *fence_waiting_thread;
-
        /* for checking draw done */
        tpl_bool_t draw_done;
        tbm_fd draw_done_fence;
@@ -1243,11 +1241,6 @@ __cb_twe_buffer_free_callback(twe_wl_buffer_info *buf_info)
 
        wl_display_flush(disp_source->disp);
 
-       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;
@@ -1434,6 +1427,7 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source,
                TPL_WARN("Failed to create TBM sync timeline: %d(%s)", errno, buf);
        }
 
+       buf_info->draw_done_fence = -1;
        buf_info->sync_timestamp = 0;
        buf_info->surf_source = surf_source;
        buf_info->num_rects = 0;
@@ -1512,9 +1506,6 @@ __cb_tbm_queue_acquirable_callback(tbm_surface_queue_h surface_queue,
        uint64_t value = 1;
        int ret;
 
-       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)",
@@ -1632,6 +1623,46 @@ _twe_surface_wait_vblank(twe_wl_surf_source *surf_source)
        return TPL_ERROR_NONE;
 }
 
+static tpl_result_t
+_twe_surface_wait_draw_done(tbm_surface_h tbm_surface)
+{
+       twe_wl_buffer_info *buf_info = NULL;
+
+       if (!tbm_surface || !tbm_surface_internal_is_valid(tbm_surface)) {
+               TPL_ERR("Invalid tbm_surface(%p)", tbm_surface);
+               return TPL_ERROR_INVALID_PARAMETER;
+       }
+
+       tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO,
+                                                                          (void **)&buf_info);
+       if (!buf_info) {
+               TPL_ERR("Failed to get twe_wl_buffer_info from tbm_surface(%p)",
+                               tbm_surface);
+               return TPL_ERROR_INVALID_OPERATION;
+       }
+
+       if (buf_info->draw_done_fence == -1) {
+               TPL_WARN("tbm_surface(%p) will be presented immediately.", tbm_surface);
+               return TPL_ERROR_NONE;
+       }
+
+       TRACE_BEGIN("Fence waiting. BO(%d)",
+                           tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
+       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(%d). | error: %d(%s)",
+                               buf_info->draw_done_fence, errno, buf);
+       }
+       TRACE_END();
+
+       close(buf_info->draw_done_fence);
+       buf_info->draw_done_fence = -1;
+       buf_info->draw_done = TPL_TRUE;
+
+       return TPL_ERROR_NONE;
+}
+
 static void
 _twe_thread_wl_vk_surface_commit(twe_wl_surf_source *surf_source,
                                                                 tbm_surface_h tbm_surface)
@@ -1804,16 +1835,15 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source)
                        return;
                }
 
-               TRACE_ASYNC_END((int)tbm_surface, "DRAWING BO(%d)",
-                                               tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
-
                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;
+
+               if (!buf_info->draw_done && buf_info->draw_done_fence != -1) {
+                       /* wait until draw done. */
+                       if (_twe_surface_wait_draw_done(tbm_surface) != TPL_ERROR_NONE)
+                               TPL_ERR("Failed to wait drawing complete.");
                }
 
                if (!disp_source->is_vulkan_dpy) { /* wayland_egl */
@@ -2570,41 +2600,6 @@ 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)
 {
@@ -2622,20 +2617,12 @@ twe_surface_set_sync_fd(tbm_surface_h tbm_surface, tbm_fd sync_fd)
                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;
 }