From 5254b6bd6ffb22c9a1e223acb7948a3a307c4856 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 8 Nov 2017 18:59:27 +0900 Subject: [PATCH] tpl_wayland_egl_thread: Modified the buffer_info to wait for draw done without using sub-thread. - 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 --- src/tpl_wayland_egl_thread.c | 105 +++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 59 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 7f12646..661b64b 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -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; } -- 2.7.4