From 36d17df9abb534c242acb37c29a5703f1efc2117 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 18 Mar 2020 14:50:19 +0900 Subject: [PATCH 01/16] tpl_wayland_egl_thread: Deleted unnecessary sub_thread for vk_display. - vk_sub_thread has created to wait for the buffer to render done. - The definition of how to wait for render done was lacking, so it was temporarily operated. - In the future, when we need to know the render done for the vulkan, we will use the explicit fence fd feature. Change-Id: Ic9284cbfbd90a0fdb35311c701d2a01749d77a47 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 273 +------------------------------------------ 1 file changed, 5 insertions(+), 268 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 0176383..4950c7d 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -34,7 +34,6 @@ typedef struct _twe_wl_surf_source twe_wl_surf_source; typedef struct _twe_wl_buffer_info twe_wl_buffer_info; typedef struct _twe_tdm_source twe_tdm_source; typedef struct _twe_del_source twe_del_source; -typedef struct _vk_sync_draw_source twe_sync_draw_source; struct _twe_thread_context { GThread *twe_thread; @@ -141,13 +140,6 @@ struct _twe_wl_surf_source { /* for waiting draw done */ tpl_bool_t use_sync_fence; - /* Temporary sub worker thread */ - GThread *vk_sub_thread; - GMainLoop *vk_sub_loop; - GMutex sub_thread_mutex; - GCond sub_thread_cond; - int draw_done_count; - int post_interval; }; @@ -177,9 +169,6 @@ struct _twe_wl_buffer_info { tbm_fd sync_fd; tpl_bool_t is_vk_image; - /* for waiting draw done */ - twe_sync_draw_source *sync_draw_source; - tbm_surface_h tbm_surface; twe_wl_surf_source *surf_source; @@ -188,16 +177,6 @@ struct _twe_wl_buffer_info { unsigned int serial; }; -struct _vk_sync_draw_source { - GSource gsource; - gpointer tag; - int event_fd; - int draw_done_signal_fd; - tbm_fd draw_fence_fd; - tbm_surface_h tbm_surface; - twe_wl_buffer_info *buf_info; -}; - static twe_thread_context *_twe_ctx; static twe_tdm_source * _twe_thread_tdm_source_create(void); @@ -1613,7 +1592,6 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info->need_to_commit = TPL_TRUE; buf_info->draw_done = TPL_FALSE; buf_info->tbm_surface = tbm_surface; - buf_info->sync_draw_source = NULL; buf_info->sync_fd = -1; buf_info->sync_timeline = -1; buf_info->is_vk_image = surf_source->disp_source->is_vulkan_dpy; @@ -2220,10 +2198,6 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) * to commit or pending, depending on whether vblank_done * after acquire as much as possible. */ while (tbm_surface_queue_can_acquire(surf_source->tbm_queue, 0)) { - /* If its backend is vulkan, it should be checked with draw_done_count. - * Because vulkan surface's [enqueue] doesn't mean render done state */ - if (disp_source->is_vulkan_dpy && surf_source->draw_done_count <= 0) - return; tsq_err = tbm_surface_queue_acquire(surf_source->tbm_queue, &tbm_surface); if (!tbm_surface || tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { @@ -2266,8 +2240,6 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); - surf_source->draw_done_count--; - switch (surf_source->swapchain_properties.present_mode) { case TPL_DISPLAY_PRESENT_MODE_IMMEDIATE: _twe_thread_wl_vk_surface_commit(surf_source, tbm_surface); @@ -2333,14 +2305,8 @@ _twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer data) TPL_ERR("Failed to read from event_fd(%d)", surf_source->event_fd); - if (surf_source->disp_source->is_vulkan_dpy && - surf_source->use_sync_fence) { - g_mutex_lock(&surf_source->sub_thread_mutex); - _twe_thread_wl_surface_acquire_and_commit(surf_source); - g_mutex_unlock(&surf_source->sub_thread_mutex); - } else { - _twe_thread_wl_surface_acquire_and_commit(surf_source); - } + _twe_thread_wl_surface_acquire_and_commit(surf_source); + } else { TPL_ERR("eventfd(%d) cannot wake up with other condition. cond(%d)", surf_source->event_fd, cond); @@ -2659,23 +2625,6 @@ _twe_thread_wl_surf_source_destroy(void *source) g_source_unref(&surf_source->gsource); } -static gpointer -_vk_sub_thread_loop(gpointer data) -{ - twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data; - - g_mutex_lock(&surf_source->sub_thread_mutex); - /* Do nothing */ - TPL_DEBUG("vk_sub_thread(%p) vk_sub_loop(%p) run", - surf_source->vk_sub_thread, surf_source->vk_sub_loop); - g_cond_signal(&surf_source->sub_thread_cond); - g_mutex_unlock(&surf_source->sub_thread_mutex); - - g_main_loop_run(surf_source->vk_sub_loop); - - return surf_source->vk_sub_thread; -} - twe_surface_h twe_surface_add(twe_thread* thread, twe_display_h twe_display, @@ -2741,10 +2690,6 @@ twe_surface_add(twe_thread* thread, source->vblank_waiting_buffers = NULL; source->draw_done_buffer = NULL; - source->vk_sub_loop = NULL; - source->vk_sub_thread = NULL; - source->draw_done_count = 0; - source->set_serial_is_used = TPL_FALSE; source->serial = 0; @@ -2868,7 +2813,6 @@ twe_surface_create_swapchain(twe_surface_h twe_surface, { twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface; twe_wl_disp_source *disp_source = NULL; - GMainContext *context; tbm_bufmgr bufmgr = NULL; unsigned int capability; @@ -2997,22 +2941,6 @@ twe_surface_create_swapchain(twe_surface_h twe_surface, "[SWAPCHAIN_CREATE][2/2] w(%d) h(%d) f(%d) p(%d) b_cnt(%d)", width, height, format, present_mode, buffer_count); - /* TODO : Below lines about sub_thread will be deleted. - * It is temporary code for sync_drawing. */ - - g_mutex_init(&surf_source->sub_thread_mutex); - g_cond_init(&surf_source->sub_thread_cond); - - context = g_main_context_new(); - surf_source->vk_sub_loop = g_main_loop_new(context, FALSE); - - g_main_context_unref(context); - g_mutex_lock(&surf_source->sub_thread_mutex); - surf_source->vk_sub_thread = g_thread_new("twe_sub_thread", _vk_sub_thread_loop, - surf_source); - g_cond_wait(&surf_source->sub_thread_cond, &surf_source->sub_thread_mutex); - g_mutex_unlock(&surf_source->sub_thread_mutex); - return TPL_ERROR_NONE; } @@ -3029,29 +2957,6 @@ twe_surface_destroy_swapchain(twe_surface_h twe_surface) TPL_LOG_T(BACKEND, "[SWAPCHAIN_DESTROY] twe_surface(%p) tbm_queue(%p)", twe_surface, surf_source->tbm_queue); - while (surf_source->vk_sub_loop && - !g_main_loop_is_running(surf_source->vk_sub_loop)) { - /* Do nothing */ - } - - if (surf_source->vk_sub_thread) { - TPL_DEBUG("vk_sub_thread(%p) exit.", surf_source->vk_sub_thread); - g_mutex_lock(&surf_source->sub_thread_mutex); - - g_main_loop_quit(surf_source->vk_sub_loop); - /* Waiting for all drawing buffers. */ - g_thread_join(surf_source->vk_sub_thread); - g_main_loop_unref(surf_source->vk_sub_loop); - - g_mutex_unlock(&surf_source->sub_thread_mutex); - - surf_source->vk_sub_thread = NULL; - surf_source->vk_sub_loop = NULL; - - g_mutex_clear(&surf_source->sub_thread_mutex); - g_cond_clear(&surf_source->sub_thread_cond); - } - /* Waiting for vblank to commit all draw done buffers.*/ while (surf_source->vblank_waiting_buffers && !__tpl_list_is_empty(surf_source->vblank_waiting_buffers)) { @@ -3274,181 +3179,13 @@ twe_surface_commit_without_enqueue(twe_surface_h twe_surface, g_mutex_unlock(&surf_source->surf_mutex); } -static gboolean -_twe_thread_sync_draw_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) -{ - twe_sync_draw_source *sync_draw_source = (twe_sync_draw_source *)source; - GIOCondition cond; - - if (g_source_is_destroyed(source)) { - TPL_ERR("del_source(%p) already destroyed.", source); - return G_SOURCE_REMOVE; - } - - cond = g_source_query_unix_fd(source, sync_draw_source->tag); - - if (cond & G_IO_IN) { - ssize_t s; - uint64_t u; - int ret; - uint64_t value = 1; - tbm_surface_h tbm_surface = sync_draw_source->tbm_surface; - twe_wl_surf_source *surf_source = sync_draw_source->buf_info->surf_source; - - tbm_surface_internal_ref(tbm_surface); - - s = read(sync_draw_source->event_fd, &u, sizeof(uint64_t)); - if (s != sizeof(uint64_t)) - TPL_ERR("Failed to read from event_fd(%d)", - sync_draw_source->event_fd); - - TRACE_BEGIN("Fence waiting. BO(%d)", - tbm_bo_export( - tbm_surface_internal_get_bo(tbm_surface, 0))); - /* Below API is blocking call. - * It is waiting for drawing complete in GPU. */ - if (tbm_sync_fence_wait(sync_draw_source->draw_fence_fd, -1) != 1) { - char buf[1024]; - strerror_r(errno, buf, sizeof(buf)); - TPL_ERR("Failed to wait sync fence(%d). | error: %d(%s)", - sync_draw_source->draw_fence_fd, errno, buf); - } - - g_mutex_lock(&surf_source->sub_thread_mutex); - surf_source->draw_done_count++; - g_mutex_unlock(&surf_source->sub_thread_mutex); - - /* Draw done */ - /* Send event to twe_wl_surf_source */ - ret = write(sync_draw_source->draw_done_signal_fd, - &value, sizeof(uint64_t)); - if (ret == -1) { - TPL_ERR("failed to send acquirable event. tbm_surface(%p)", - tbm_surface); - } - TRACE_END(); - - tbm_surface_internal_unref(tbm_surface); - } - - return G_SOURCE_REMOVE; -} - -static void -_twe_thread_sync_draw_source_finalize(GSource *source) -{ - twe_sync_draw_source *sync_draw_source = (twe_sync_draw_source *)source; - twe_wl_buffer_info *buf_info = sync_draw_source->buf_info; - - TPL_LOG_T(BACKEND, "gsource(%p) event_fd(%d)", - source, sync_draw_source->event_fd); - - close(sync_draw_source->event_fd); - close(sync_draw_source->draw_fence_fd); - - buf_info->sync_draw_source = NULL; - sync_draw_source->draw_fence_fd = -1; - sync_draw_source->tag = NULL; - sync_draw_source->event_fd = -1; - sync_draw_source->draw_done_signal_fd = -1; - sync_draw_source->buf_info = NULL; - sync_draw_source->tbm_surface = NULL; -} - -static GSourceFuncs _twe_sync_draw_source_funcs = { - .prepare = NULL, - .check = NULL, - .dispatch = _twe_thread_sync_draw_source_dispatch, - .finalize = _twe_thread_sync_draw_source_finalize, -}; - -static twe_sync_draw_source * -_twe_sync_draw_source_attach(twe_wl_surf_source *surf_source, - twe_wl_buffer_info *buf_info, - tbm_fd sync_fd) -{ - twe_sync_draw_source *source = NULL; - - if (!surf_source->vk_sub_thread || !surf_source->vk_sub_loop) { - TPL_ERR("Invalid parameter. vk_sub_thread is not initialized."); - return NULL; - } - - if (!buf_info) { - TPL_ERR("Invalid parameter. buf_info is NULL"); - return NULL; - } - - source = (twe_sync_draw_source *)g_source_new(&_twe_sync_draw_source_funcs, - sizeof(twe_sync_draw_source)); - if (!source) { - TPL_ERR("[THREAD] Failed to create GSource"); - return NULL; - } - - source->event_fd = eventfd(0, EFD_CLOEXEC); - if (source->event_fd < 0) { - TPL_ERR("[THREAD] Failed to create eventfd. errno(%d)", errno); - g_source_unref(&source->gsource); - return NULL; - } - - source->tag = g_source_add_unix_fd(&source->gsource, - source->event_fd, - G_IO_IN); - source->draw_done_signal_fd = surf_source->event_fd; - source->draw_fence_fd = sync_fd; - source->buf_info = buf_info; - source->tbm_surface = buf_info->tbm_surface; - - g_source_attach(&source->gsource, g_main_loop_get_context(surf_source->vk_sub_loop)); - g_source_unref(&source->gsource); - - return source; -} - tpl_result_t twe_surface_set_sync_fd(twe_surface_h twe_surface, tbm_surface_h tbm_surface, tbm_fd sync_fd) { - twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface; - twe_wl_buffer_info *buf_info = NULL; - twe_sync_draw_source *sync_draw_source = NULL; - int ret; - uint64_t value = 1; - - 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); - surf_source->use_sync_fence = TPL_FALSE; - return TPL_ERROR_INVALID_OPERATION; - } - - sync_draw_source = _twe_sync_draw_source_attach(surf_source, - buf_info, sync_fd); - if (!sync_draw_source) { - TPL_ERR("Failed to create and attach sync_draw_source."); - surf_source->use_sync_fence = TPL_FALSE; - return TPL_ERROR_INVALID_OPERATION; - } - - /* Draw done */ - /* Send event to twe_wl_surf_source */ - ret = write(sync_draw_source->event_fd, - &value, sizeof(uint64_t)); - if (ret == -1) { - TPL_ERR("failed to send event to wait sync_fd(%d). twe_wl_surf_source(%p)", - sync_fd, surf_source); - g_source_remove_unix_fd(&sync_draw_source->gsource, - sync_draw_source->tag); - g_source_destroy(&sync_draw_source->gsource); - surf_source->use_sync_fence = TPL_FALSE; - return TPL_ERROR_INVALID_OPERATION; - } - - surf_source->use_sync_fence = TPL_TRUE; + TPL_IGNORE(twe_surface); + TPL_IGNORE(tbm_surface); + TPL_IGNORE(sync_fd); return TPL_ERROR_NONE; } -- 2.7.4 From cc2b14875786b34d9782cbd918e20ebbb4a2c07d Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 18 Mar 2020 15:26:59 +0900 Subject: [PATCH 02/16] tpl_wayland_egl_thread: Added struct twe_fence_wait_source to wait draw done fence. Change-Id: I4a55e917c552af29a7005c3c07ef95ebe4200b65 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 4950c7d..e8b68ac 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -34,6 +34,7 @@ typedef struct _twe_wl_surf_source twe_wl_surf_source; typedef struct _twe_wl_buffer_info twe_wl_buffer_info; typedef struct _twe_tdm_source twe_tdm_source; typedef struct _twe_del_source twe_del_source; +typedef struct _twe_fence_wait_source twe_fence_wait_source; struct _twe_thread_context { GThread *twe_thread; @@ -177,6 +178,14 @@ struct _twe_wl_buffer_info { unsigned int serial; }; +struct _twe_fence_wait_source { + GSource gsource; + gpointer tag; + tbm_fd fence_fd; + tbm_surface_h tbm_surface; + twe_wl_surf_source *surf_source; +}; + static twe_thread_context *_twe_ctx; static twe_tdm_source * _twe_thread_tdm_source_create(void); -- 2.7.4 From b5c2f21b24acb5edd1581bdf4c8ee3307fb14ad2 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 18 Mar 2020 18:01:00 +0900 Subject: [PATCH 03/16] wayland_egl_thread: Implemented the function waiting sync_fence to render done. - In the case of mesa, tbm_surface with guaranteed 'render done' is not enqueued. - To compensate for this, fence fd is delivered to the platform side from mesa driver, but libtpl-egl did not have the function to use it. - The added function ensures the following operation. 1. When __tpl_wl_egl_surface_enqueue_buffer is called, if sync_fd (!=-1) is received. 2. This is the case when the buffer is not complete. 3. Create gsource to poll sync_fd in twe_thread. 4. Attach it to twe_thread. (poll starting) 5. If G_IO_IN occurs in sync_fd, it is known as render_done and acquire_and_commit is performed. (twe_thread) 6. After completing just one role, the created source will be removed. Change-Id: I16558f700df98afd372bbc83613a8633062953c0 Signed-off-by: Joonbum Ko --- .vscode/settings.json | 5 -- src/tpl_wayland_egl_thread.c | 113 ++++++++++++++++++++++++++++++++++++++++--- src/tpl_wayland_egl_thread.h | 2 +- src/tpl_wl_egl_thread.c | 8 ++- 4 files changed, 114 insertions(+), 14 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index d10fd7e..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files.associations": { - "tpl_utils.h": "c" - } -} \ No newline at end of file diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index e8b68ac..8abbd6d 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1712,8 +1712,7 @@ __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 - || !surf_source->use_sync_fence) { + if (!surf_source->use_sync_fence) { 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)", @@ -3188,15 +3187,117 @@ twe_surface_commit_without_enqueue(twe_surface_h twe_surface, g_mutex_unlock(&surf_source->surf_mutex); } +static gboolean +_twe_thread_fence_wait_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) +{ + twe_fence_wait_source *wait_source = (twe_fence_wait_source *)source; + twe_wl_surf_source *surf_source = wait_source->surf_source; + tbm_surface_h tbm_surface = wait_source->tbm_surface; + GIOCondition cond = g_source_query_unix_fd(source, wait_source->tag); + + if (cond & G_IO_IN) { + TPL_LOG_T(BACKEND, "[RENDER DONE] wait_source(%p) tbm_surface(%p) fence_fd(%d)", + wait_source, tbm_surface, wait_source->fence_fd); + } else { + /* When some io errors occur, it is not considered as a critical error. + * There may be problems with the screen, but it does not affect the operation. */ + TPL_WARN("Invalid GIOCondition occured. fd(%d) cond(%d)", + wait_source->fence_fd, cond); + } + + /* Since this source is going to be removed, acquire_and_commit must be + * executed even in a situation other than G_IO_IN. + * Nevertheless, there may be room for improvement. */ + _twe_thread_wl_surface_acquire_and_commit(surf_source); + tbm_surface_internal_unref(tbm_surface); + + /* This source is used only once and does not allow reuse. + * So finalize will be executed immediately. */ + g_source_remove_unix_fd(&wait_source->gsource, wait_source->tag); + g_source_destroy(&wait_source->gsource); + g_source_unref(&wait_source->gsource); + + return G_SOURCE_REMOVE; +} + +static void +_twe_thread_fence_wait_source_finalize(GSource *source) +{ + twe_fence_wait_source *wait_source = (twe_fence_wait_source *)source; + + TPL_DEBUG("[FINALIZE] wait_source(%p) fence_fd(%d)", + wait_source, wait_source->fence_fd); + + close(wait_source->fence_fd); + + wait_source->fence_fd = -1; + wait_source->surf_source = NULL; + wait_source->tbm_surface = NULL; + wait_source->tag = NULL; +} + +static GSourceFuncs _twe_fence_wait_source_funcs = { + .prepare = NULL, + .check = NULL, + .dispatch = _twe_thread_fence_wait_source_dispatch, + .finalize = _twe_thread_fence_wait_source_finalize, +}; + +tpl_result_t +_twe_thread_fence_wait_source_attach(twe_wl_surf_source *surf_source, + tbm_surface_h tbm_surface, tbm_fd sync_fd) +{ + twe_fence_wait_source *wait_source = NULL; + + wait_source = (twe_fence_wait_source *)g_source_new(&_twe_fence_wait_source_funcs, + sizeof(twe_fence_wait_source)); + if (!wait_source) { + TPL_ERR("[WAIT_SOURCE] Failed to create GSource"); + return TPL_ERROR_OUT_OF_MEMORY; + } + + tbm_surface_internal_ref(tbm_surface); + + wait_source->fence_fd = sync_fd; + wait_source->surf_source = surf_source; + wait_source->tbm_surface = tbm_surface; + + wait_source->tag = g_source_add_unix_fd(&wait_source->gsource, + wait_source->fence_fd, + G_IO_IN); + g_source_attach(&wait_source->gsource, g_main_loop_get_context(_twe_ctx->twe_loop)); + + return TPL_ERROR_NONE; +} + tpl_result_t twe_surface_set_sync_fd(twe_surface_h twe_surface, tbm_surface_h tbm_surface, tbm_fd sync_fd) { - TPL_IGNORE(twe_surface); - TPL_IGNORE(tbm_surface); - TPL_IGNORE(sync_fd); + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface; + tpl_result_t ret = TPL_ERROR_NONE; - return TPL_ERROR_NONE; + if (!surf_source) { + TPL_ERR("Invalid parameter. twe_surface(%p)", twe_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (!tbm_surface || !tbm_surface_internal_is_valid(tbm_surface)) { + TPL_ERR("Invalid parameter. tbm_surface(%p)", tbm_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + ret = _twe_thread_fence_wait_source_attach(surf_source, tbm_surface, sync_fd); + if (ret != TPL_ERROR_NONE) { + TPL_ERR("Failed to attach source with fence_fd(%d) ret(%d)", + sync_fd, ret); + surf_source->use_sync_fence = TPL_FALSE; + return ret; + } + + surf_source->use_sync_fence = TPL_TRUE; + + return ret; } tbm_fd diff --git a/src/tpl_wayland_egl_thread.h b/src/tpl_wayland_egl_thread.h index 067def1..3a17305 100755 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -90,7 +90,7 @@ twe_surface_set_damage_region(tbm_surface_h tbm_surface, tpl_result_t twe_surface_set_sync_fd(twe_surface_h twe_surface, - tbm_surface_h tbm_surface, tbm_fd wait_fd); + tbm_surface_h tbm_surface, tbm_fd sync_fd); tbm_fd twe_surface_create_sync_fd(tbm_surface_h tbm_surface); diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index 92c7ef0..e20801a 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -583,8 +583,12 @@ __tpl_wl_egl_surface_enqueue_buffer(tpl_surface_t *surface, } if (sync_fence != -1) { - tbm_sync_fence_wait(sync_fence, -1); - close(sync_fence); + ret = twe_surface_set_sync_fd(wayland_egl_surface->twe_surface, + tbm_surface, sync_fence); + if (ret != TPL_ERROR_NONE) { + TPL_WARN("Failed to set sync fd (%d). But it will continue.", + sync_fence); + } } tsq_err = tbm_surface_queue_enqueue(wayland_egl_surface->tbm_queue, -- 2.7.4 From 37461d48803e58acc73d2079a33dbfd002af9ab1 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 19 Mar 2020 19:21:40 +0900 Subject: [PATCH 04/16] Added render_done_cnt to check whether it is actually acquireable - queue_acquire should be performed only when render_done_cnt is greater than 0 when using sync_fence even in the case of queue_can_acquire. Change-Id: I3b11e32eecc22ffded539f6bb9215584c4584752 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 8abbd6d..71aa8fd 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -113,6 +113,8 @@ struct _twe_wl_surf_source { tpl_list_t *in_use_buffers; tpl_list_t *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */ tbm_surface_h draw_done_buffer; /* for MAILBOX mode */ + int render_done_cnt; + tdm_client_vblank *vblank; tpl_bool_t vblank_done; tpl_bool_t is_destroying; @@ -2207,6 +2209,13 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) * after acquire as much as possible. */ while (tbm_surface_queue_can_acquire(surf_source->tbm_queue, 0)) { + /* queue_acquire should be performed only when render_done_cnt + * is greater than 0 when using sync_fence even in the case of + * queue_can_acquire. */ + if (surf_source->use_sync_fence && !(surf_source->render_done_cnt > 0)) { + return; + } + tsq_err = tbm_surface_queue_acquire(surf_source->tbm_queue, &tbm_surface); if (!tbm_surface || tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("Failed to acquire from tbm_queue(%p)", @@ -2214,6 +2223,8 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) return; } + surf_source->render_done_cnt--; + tbm_surface_internal_ref(tbm_surface); tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO, @@ -2689,6 +2700,8 @@ twe_surface_add(twe_thread* thread, source->is_destroying = TPL_FALSE; source->committed_buffers = __tpl_list_alloc(); source->in_use_buffers = __tpl_list_alloc(); + source->render_done_cnt = 0; + source->cb_data = NULL; source->rotate_cb = NULL; source->format = format; @@ -3205,6 +3218,8 @@ _twe_thread_fence_wait_source_dispatch(GSource *source, GSourceFunc cb, gpointer wait_source->fence_fd, cond); } + surf_source->render_done_cnt++; + /* Since this source is going to be removed, acquire_and_commit must be * executed even in a situation other than G_IO_IN. * Nevertheless, there may be room for improvement. */ -- 2.7.4 From fe2179cfdf7dd9df4be753e1442197313bf066a5 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 19 Mar 2020 19:38:52 +0900 Subject: [PATCH 05/16] Added ttrace point to trace fence waiting time. Change-Id: I79764f225b785d12cbb43d90d9e46f38b9dc4744 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 71aa8fd..1aab901 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -3220,6 +3220,8 @@ _twe_thread_fence_wait_source_dispatch(GSource *source, GSourceFunc cb, gpointer surf_source->render_done_cnt++; + TRACE_ASYNC_END((int)wait_source, "FENCE WAIT fd(%d)", wait_source->fence_fd); + /* Since this source is going to be removed, acquire_and_commit must be * executed even in a situation other than G_IO_IN. * Nevertheless, there may be room for improvement. */ @@ -3271,6 +3273,8 @@ _twe_thread_fence_wait_source_attach(twe_wl_surf_source *surf_source, return TPL_ERROR_OUT_OF_MEMORY; } + TRACE_ASYNC_BEGIN((int)wait_source, "FENCE WAIT fd(%d)", sync_fd); + tbm_surface_internal_ref(tbm_surface); wait_source->fence_fd = sync_fd; -- 2.7.4 From 549eda9fc1b1a3d244db0d5cd3cfea1560b8f2bc Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 24 Mar 2020 18:38:07 +0900 Subject: [PATCH 06/16] Added some comments about the lists. Change-Id: I9fb0f70281704a13237aee7c921908a997ab7140 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 1aab901..3837417 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -109,8 +109,8 @@ struct _twe_wl_surf_source { } swapchain_properties; tpl_surface_cb_func_t rotate_cb; tpl_bool_t rotation_capability; - tpl_list_t *committed_buffers; - tpl_list_t *in_use_buffers; + tpl_list_t *committed_buffers; /* Trace tbm_surface from wl_surface_commit() to RELEASE */ + tpl_list_t *in_use_buffers; /* Trace tbm_surface from DEQUEUE to ENQUEUE */ tpl_list_t *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */ tbm_surface_h draw_done_buffer; /* for MAILBOX mode */ int render_done_cnt; -- 2.7.4 From f8fe6dd8f502c29c4372ef2e99cf46f0e2b066a0 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 25 Mar 2020 16:35:30 +0900 Subject: [PATCH 07/16] Added fence_waiting_sources list to trace fence_wait_sources. Change-Id: Ib70a80a94be9f507adea71e13957adca87e41f9e Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 3837417..ce46b07 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -111,6 +111,7 @@ struct _twe_wl_surf_source { tpl_bool_t rotation_capability; tpl_list_t *committed_buffers; /* Trace tbm_surface from wl_surface_commit() to RELEASE */ tpl_list_t *in_use_buffers; /* Trace tbm_surface from DEQUEUE to ENQUEUE */ + tpl_list_t *fence_waiting_sources; /* Trace fence_wait_source from ENQUEUE to fence signaled */ tpl_list_t *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */ tbm_surface_h draw_done_buffer; /* for MAILBOX mode */ int render_done_cnt; @@ -2595,6 +2596,25 @@ _twe_thread_wl_surf_source_destroy(void *source) surf_source->vblank_waiting_buffers = NULL; } + if (surf_source->use_sync_fence && surf_source->fence_waiting_sources) { + while (!__tpl_list_is_empty(surf_source->fence_waiting_sources)) { + twe_fence_wait_source *wait_source = + __tpl_list_pop_front(surf_source->fence_waiting_sources, + NULL); + if (!g_source_is_destroyed(&wait_source->gsource)) { + tbm_surface_internal_unref(wait_source->tbm_surface); + wait_source->tbm_surface = NULL; + + close(wait_source->fence_fd); + wait_source->fence_fd = -1; + + g_source_remove_unix_fd(&wait_source->gsource, wait_source->tag); + g_source_destroy(&wait_source->gsource); + g_source_unref(&wait_source->gsource); + } + } + } + _twe_surface_buffer_flusher_fini(surf_source); if (surf_source->tbm_queue) { @@ -2700,6 +2720,7 @@ twe_surface_add(twe_thread* thread, source->is_destroying = TPL_FALSE; source->committed_buffers = __tpl_list_alloc(); source->in_use_buffers = __tpl_list_alloc(); + source->fence_waiting_sources = __tpl_list_alloc(); source->render_done_cnt = 0; source->cb_data = NULL; @@ -3228,6 +3249,11 @@ _twe_thread_fence_wait_source_dispatch(GSource *source, GSourceFunc cb, gpointer _twe_thread_wl_surface_acquire_and_commit(surf_source); tbm_surface_internal_unref(tbm_surface); + g_mutex_lock(&surf_source->surf_mutex); + __tpl_list_remove_data(surf_source->fence_waiting_sources, + (void *)wait_source, TPL_FIRST, NULL); + g_mutex_unlock(&surf_source->surf_mutex); + /* This source is used only once and does not allow reuse. * So finalize will be executed immediately. */ g_source_remove_unix_fd(&wait_source->gsource, wait_source->tag); @@ -3284,6 +3310,12 @@ _twe_thread_fence_wait_source_attach(twe_wl_surf_source *surf_source, wait_source->tag = g_source_add_unix_fd(&wait_source->gsource, wait_source->fence_fd, G_IO_IN); + + /* When waiting is over, it will be removed from the list. */ + g_mutex_lock(&surf_source->surf_mutex); + __tpl_list_push_back(surf_source->fence_waiting_sources, (void *)wait_source); + g_mutex_unlock(&surf_source->surf_mutex); + g_source_attach(&wait_source->gsource, g_main_loop_get_context(_twe_ctx->twe_loop)); return TPL_ERROR_NONE; -- 2.7.4 From b963d7b5fb1a71e886606cf3b0e7b813f51c44ee Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 25 Mar 2020 16:37:11 +0900 Subject: [PATCH 08/16] Package version up to 1.7.4 Change-Id: I3f0c29f36603646865fba76d4f4f7e363fc53ced Signed-off-by: Joonbum Ko --- packaging/libtpl-egl.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 542be2b..36cbfca 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -4,7 +4,7 @@ #TPL VERSION MACROS %define TPL_VERSION_MAJOR 1 %define TPL_VERSION_MINOR 7 -%define TPL_VERSION_PATCH 3 +%define TPL_VERSION_PATCH 4 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From 1946f1ce6ed71ce3ca9a180651439d38c38413e5 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 26 Mar 2020 15:57:29 +0900 Subject: [PATCH 09/16] Fixed tdm_source to destroy when error occurs in tdm. - If an error occurs in tdm_client_handle_events, it cannot be recovered. When tdm_source is no longer available due to an unexpected situation, twe_thread must remove it from the thread and destroy it. - In that case, tdm_vblank can no longer be used for surfaces and display that used the tdm_source. Change-Id: I1e19e12847a03ef03e5ce7562a4e992952c4fdbb Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index ce46b07..47ba4c1 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -378,7 +378,7 @@ static gboolean _twe_thread_tdm_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) { twe_tdm_source *tdm_source = (twe_tdm_source *)source; - tdm_error tdm_err; + tdm_error tdm_err = TDM_ERROR_NONE; GIOCondition cond; if (!source || g_source_is_destroyed(source)) { @@ -390,7 +390,30 @@ _twe_thread_tdm_source_dispatch(GSource *source, GSourceFunc cb, gpointer data) if (cond & G_IO_IN) { tdm_err = tdm_client_handle_events(tdm_source->tdm_client); - TPL_ASSERT(tdm_err == TDM_ERROR_NONE); + } + + /* If an error occurs in tdm_client_handle_events, it cannot be recovered. + * When tdm_source is no longer available due to an unexpected situation, + * twe_thread must remove it from the thread and destroy it. + * In that case, tdm_vblank can no longer be used for surfaces and displays + * that used this tdm_source. */ + if (tdm_err != TDM_ERROR_NONE) { + TPL_ERR("Error occured in tdm_client_handle_events. tdm_err(%d)", + tdm_err); + TPL_WARN("tdm_source(%p) will be removed from thread.", tdm_source); + + g_source_remove_unix_fd(&tdm_source->gsource, tdm_source->tag); + g_source_destroy(&tdm_source->gsource); + g_source_unref(&tdm_source->gsource); + + _twe_ctx->tdm_source = NULL; + + if (_twe_ctx->tdm_del_source) { + _twe_del_source_fini(_twe_ctx->tdm_del_source); + _twe_ctx->tdm_del_source = NULL; + } + + return G_SOURCE_REMOVE; } return G_SOURCE_CONTINUE; @@ -545,9 +568,10 @@ twe_thread_destroy(twe_thread* thread) if (_twe_ctx->tdm_source) { g_mutex_lock(&_twe_ctx->thread_mutex); - if (tdm_del_source) + if (tdm_del_source) { _twe_thread_del_source_trigger(tdm_del_source); - g_cond_wait(&_twe_ctx->thread_cond, &_twe_ctx->thread_mutex); + g_cond_wait(&_twe_ctx->thread_cond, &_twe_ctx->thread_mutex); + } g_mutex_unlock(&_twe_ctx->thread_mutex); } -- 2.7.4 From b0ef631b94e8447603fbb02cce65de9768f6c895 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 26 Mar 2020 16:06:05 +0900 Subject: [PATCH 10/16] Renamed vblank callback function to be more clearly. Change-Id: I9700162590997a584bf69413142928324fb2cf89 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 47ba4c1..ceef070 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1794,7 +1794,7 @@ static void _twe_thread_wl_vk_surface_commit(twe_wl_surf_source *surf_source, tbm_surface_h tbm_surface); static void -__cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, +__cb_tdm_client_vblank(tdm_client_vblank *vblank, tdm_error error, unsigned int sequence, unsigned int tv_sec, unsigned int tv_usec, void *user_data) { @@ -1883,7 +1883,7 @@ _twe_surface_wait_vblank(twe_wl_surf_source *surf_source) tdm_err = tdm_client_vblank_wait(surf_source->vblank, surf_source->post_interval, /* TODO: interval */ - __cb_tdm_client_wait_vblank, + __cb_tdm_client_vblank, (void *)surf_source); if (tdm_err == TDM_ERROR_NONE) { @@ -2210,7 +2210,7 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, /* The following function _twe_thread_wl_surface_acquire_and_commit can be * called in both situations. * One is when acquirable event is received from the main thread, - * and the other is when __cb_tdm_client_wait_vblank callback is called. + * and the other is when __cb_tdm_client_vblank callback is called. * The reason for calling the next function in the two situations described * above is to make only one commit for one vblank. */ -- 2.7.4 From 3cb906ff21a420f70aa9805327c23132a2b224e2 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 26 Mar 2020 18:08:15 +0900 Subject: [PATCH 11/16] Make to operate normally even when tdm_source was unexpectedly destroyed. Change-Id: If3a39100b1922a840a16b1860ff427c532883102 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index ceef070..b1c1f4e 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1868,6 +1868,13 @@ _twe_surface_wait_vblank(twe_wl_surf_source *surf_source) if (!_twe_ctx->tdm_source) { TPL_WARN("tdm_vblank feature is disabled."); + + if (surf_source->vblank) { + tdm_client_vblank_destroy(surf_source->vblank); + surf_source->vblank = NULL; + surf_source->vblank_done = TPL_TRUE; + } + return TPL_ERROR_INVALID_OPERATION; } @@ -1967,7 +1974,8 @@ _twe_thread_wl_vk_surface_commit(twe_wl_surf_source *surf_source, == TPL_DISPLAY_PRESENT_MODE_FIFO_RELAXED || surf_source->swapchain_properties.present_mode == TPL_DISPLAY_PRESENT_MODE_FIFO) { - if (_twe_surface_wait_vblank(surf_source) != TPL_ERROR_NONE) + if ((_twe_ctx->tdm_source || surf_source->vblank) && + _twe_surface_wait_vblank(surf_source) != TPL_ERROR_NONE) TPL_ERR("Failed to set wait vblank"); } @@ -2187,7 +2195,8 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, buf_info->wl_buffer, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); - if (_twe_surface_wait_vblank(surf_source) != TPL_ERROR_NONE) + if ((_twe_ctx->tdm_source || surf_source->vblank) && + _twe_surface_wait_vblank(surf_source) != TPL_ERROR_NONE) TPL_ERR("Failed to set wait vblank."); @@ -2303,7 +2312,8 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) surf_source->draw_done_buffer = tbm_surface; if (surf_source->vblank_done) { - if (_twe_surface_wait_vblank(surf_source) != TPL_ERROR_NONE) + if ((_twe_ctx->tdm_source || surf_source->vblank) && + _twe_surface_wait_vblank(surf_source) != TPL_ERROR_NONE) TPL_ERR("Failed to set wait vblank"); } break; @@ -2650,6 +2660,7 @@ _twe_thread_wl_surf_source_destroy(void *source) TPL_LOG_T(BACKEND, "[VBLANK FINI] twe_wl_surf_source(%p) vblank(%p)", surf_source, surf_source->vblank); tdm_client_vblank_destroy(surf_source->vblank); + surf_source->vblank = NULL; } surf_source->cb_data = NULL; -- 2.7.4 From 838d2950e4b755a548e80b73fc7c56009cbbfd8b Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 31 Mar 2020 18:11:10 +0900 Subject: [PATCH 12/16] tpl_tbm: Added reset callback for tbm_queue. Change-Id: Ic9c331d82525ad05fae9818970f60ed6853907d5 Signed-off-by: Joonbum Ko --- src/tpl_tbm.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/tpl_tbm.c b/src/tpl_tbm.c index b38c7c5..cabdf9d 100644 --- a/src/tpl_tbm.c +++ b/src/tpl_tbm.c @@ -21,6 +21,7 @@ struct _tpl_tbm_display { struct _tpl_tbm_surface { tbm_surface_queue_h tbm_queue; + tpl_bool_t need_reset; }; static tpl_result_t @@ -165,6 +166,22 @@ __tpl_tbm_display_get_buffer_from_native_pixmap(tpl_handle_t pixmap) return (tbm_surface_h)pixmap; } +static void +__cb_tbm_queue_reset_callback(tbm_surface_queue_h tbm_queue, + void *data) +{ + tpl_tbm_surface_t *tpl_tbm_surface = (tpl_tbm_surface_t *)data; + + if (!tpl_tbm_surface) { + TPL_ERR("Invalid parameter. tpl_tbm_surface(%p)", tpl_tbm_surface); + return; + } + + TPL_LOG_B("TBM", "tbm_queue(%p) has been reset!", tbm_queue); + + tpl_tbm_surface->need_reset = TPL_TRUE; +} + static tpl_result_t __tpl_tbm_surface_init(tpl_surface_t *surface) { @@ -179,8 +196,15 @@ __tpl_tbm_surface_init(tpl_surface_t *surface) surface->backend.data = (void *)tpl_tbm_surface; + tpl_tbm_surface->need_reset = TPL_FALSE; + tpl_tbm_surface->tbm_queue = (tbm_surface_queue_h)surface->native_handle; + /* Set reset_callback to tbm_queue */ + tbm_surface_queue_add_reset_cb(tpl_tbm_surface->tbm_queue, + __cb_tbm_queue_reset_callback, + (void *)tpl_tbm_surface); + TPL_LOG_B("TBM", "[INIT] tpl_surface(%p) tpl_tbm_surface_t(%p) tbm_surface_queue(%p)", surface, tpl_tbm_surface, surface->native_handle); @@ -252,7 +276,12 @@ __tpl_tbm_surface_enqueue_buffer(tpl_surface_t *surface, static tpl_bool_t __tpl_tbm_surface_validate(tpl_surface_t *surface) { - return TPL_TRUE; + tpl_tbm_surface_t *tpl_tbm_surface = (tpl_tbm_surface_t *)surface->backend.data; + tpl_bool_t ret = TPL_TRUE; + + ret = !tpl_tbm_surface->need_reset; + + return ret; } static tbm_surface_h @@ -286,6 +315,8 @@ __tpl_tbm_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, /* It will be dec when before tbm_surface_queue_enqueue called */ tbm_surface_internal_ref(tbm_surface); + tpl_tbm_surface->need_reset = TPL_FALSE; + TPL_LOG_B("TBM", "[DEQ] tpl_surface(%p) tbm_queue(%p) tbm_surface(%p) bo(%d)", surface, tpl_tbm_surface->tbm_queue, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); -- 2.7.4 From 830b7e8b7157a9cb57f76d39012c20501b4ab1e4 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 8 Apr 2020 15:38:56 +0900 Subject: [PATCH 13/16] Package version up to 1.7.5 Change-Id: I2800f5fdebb3a2278344774599ba53f69a2b09f1 Signed-off-by: Joonbum Ko --- packaging/libtpl-egl.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 36cbfca..98712ac 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -4,7 +4,7 @@ #TPL VERSION MACROS %define TPL_VERSION_MAJOR 1 %define TPL_VERSION_MINOR 7 -%define TPL_VERSION_PATCH 4 +%define TPL_VERSION_PATCH 5 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From 79a72b5fc4544c977a36e587f0abcef3356d8be5 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 9 Apr 2020 13:15:52 +0900 Subject: [PATCH 14/16] Added missing destroy of bound presentation interface. Change-Id: I61344fb95eba06ec5b3a281bf09a3756edc6e460 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index b1c1f4e..4f6acf1 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -924,6 +924,13 @@ _twe_display_wayland_fini(twe_wl_disp_source *disp_source) if (disp_source->wl_vk_client) { TPL_LOG_T(BACKEND, "wl_vk_client(%p) fini.", disp_source->wl_vk_client); wayland_vulkan_destroy(disp_source->wl_vk_client); + disp_source->wl_vk_client = NULL; + } + + if (disp_source->presentation) { + TPL_LOG_T(BACKEND, "wp_presentation(%p) fini.", disp_source->presentation); + wp_presentation_destroy(disp_source->presentation); + disp_source->presentation = NULL; } } -- 2.7.4 From 0f9bdedeaac4bcd2f7f537a707decfce2ab2f4fd Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 9 Apr 2020 18:13:15 +0900 Subject: [PATCH 15/16] Changed to do not print error logs when last_error is already set. Change-Id: Ib5b4ec852930a55089864eeaf28e7b095295bc50 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl_thread.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 4f6acf1..48c9507 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -81,6 +81,7 @@ struct _twe_wl_disp_source { twe_thread *thread; GMutex wl_event_mutex; + int last_error; /* errno of the last wl_display error*/ /* TODO : surface list */ }; @@ -606,6 +607,9 @@ _twe_display_print_err(twe_wl_disp_source *disp_source, char buf[1024]; strerror_r(errno, buf, sizeof(buf)); + if (disp_source->last_error == errno) + return; + TPL_ERR("falied to %s. error:%d(%s)", func_name, errno, buf); dpy_err = wl_display_get_error(disp_source->disp); @@ -618,6 +622,8 @@ _twe_display_print_err(twe_wl_disp_source *disp_source, TPL_ERR("[Protocol Error] interface: %s, error_code: %d, proxy_id: %d", err_interface->name, err_code, err_proxy_id); } + + disp_source->last_error = errno; } static gboolean @@ -1000,6 +1006,7 @@ twe_display_add(twe_thread* thread, } source->disp = display; + source->last_error = 0; source->ev_queue = ev_queue; source->wl_tbm_client = wl_tbm_client; source->prepared = TPL_FALSE; -- 2.7.4 From 155d98f2a79866bce7b3ebf307e3e6c959d50c1a Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Fri, 17 Apr 2020 15:56:10 +0900 Subject: [PATCH 16/16] Added an error type to tpl_result_t to indicate display error. - new error type TPL_ERROR_INVALID_CONNECTION /* Invalid display connection */ - When some error occurs in the wayland display, it will be used to distinguish the error. Change-Id: I9f0813d64d10b522dae1224a0bf699328d479f27 Signed-off-by: Joonbum Ko --- src/tpl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tpl.h b/src/tpl.h index aaf6998..7250315 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -209,7 +209,8 @@ typedef enum { TPL_ERROR_INVALID_PARAMETER, /* Invalid parmeter */ TPL_ERROR_INVALID_OPERATION, /* Invalid operation */ TPL_ERROR_OUT_OF_MEMORY, /* Out of memory */ - TPL_ERROR_TIME_OUT /* Time out error */ + TPL_ERROR_TIME_OUT, /* Time out error */ + TPL_ERROR_INVALID_CONNECTION /* Invalid display connection */ } tpl_result_t; /** -- 2.7.4