From b10f7affa7b35d135f6f4cc821fe3d40a3cf47d4 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 11 May 2021 11:05:26 +0900 Subject: [PATCH 01/16] Fix so that wl_buffer is not added to the listener with null. Change-Id: I346a97a4dcb3dfe11413919efacac1c904cfc096 Signed-off-by: Joonbum Ko --- src/tpl_wl_vk_thread.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 735c808..20baea3 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -2145,16 +2145,16 @@ _thread_surface_queue_acquire(tpl_wl_vk_surface_t *wl_vk_surface) TPL_WARN("Failed to create wl_buffer. wl_tbm_client(%p) tbm_surface(%p)", wl_vk_display->wl_tbm_client, tbm_surface); } else { + if (wl_vk_buffer->acquire_fence_fd == -1 || + wl_vk_display->use_explicit_sync == TPL_FALSE) { + wl_buffer_add_listener(wl_vk_buffer->wl_buffer, + &wl_buffer_release_listener, wl_vk_buffer); + } + TPL_LOG_T("WL_VK", "[WL_BUFFER_CREATE] wl_vk_buffer(%p) wl_buffer(%p) tbm_surface(%p)", wl_vk_buffer, wl_vk_buffer->wl_buffer, tbm_surface); } - - if (wl_vk_buffer->acquire_fence_fd == -1 || - wl_vk_display->use_explicit_sync == TPL_FALSE) { - wl_buffer_add_listener(wl_vk_buffer->wl_buffer, - &wl_buffer_release_listener, wl_vk_buffer); - } } if (!wl_vk_display->use_wait_vblank || wl_vk_surface->vblank_done) -- 2.7.4 From 31acedf6a32aa0afa005577184731e3986dfdda7 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 11 May 2021 15:08:19 +0900 Subject: [PATCH 02/16] Fix to prevent thread conflict. Change-Id: I946bd6bce80a3e6188ff9e6c060abb7634a7e9b0 Signed-off-by: Joonbum Ko --- src/tpl_wl_egl_thread.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index 1f2a63e..7913614 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -1959,7 +1959,9 @@ __tpl_wl_egl_surface_fini(tpl_surface_t *surface) wl_egl_surface, wl_egl_surface->wl_surface, wl_egl_surface->tbm_queue); + tpl_gmutex_lock(&wl_egl_surface->surf_mutex); _tpl_wl_egl_surface_buffer_clear(wl_egl_surface); + tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); if (wl_egl_surface->surf_source) tpl_gsource_destroy(wl_egl_surface->surf_source, TPL_TRUE); -- 2.7.4 From d27b77481ca5bd71e81691c00de161c817f0fba7 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 11 May 2021 11:06:01 +0900 Subject: [PATCH 03/16] Package version up to 1.8.7 Change-Id: I7cc41929a6be41e85a6d7f205411217339cdeb6a 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 d8ac59c..795b5b2 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 8 -%define TPL_VERSION_PATCH 6 +%define TPL_VERSION_PATCH 7 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From db90e71f23b23d30bbea125d2789ae7dde7c083b Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Mon, 17 May 2021 14:37:14 +0900 Subject: [PATCH 04/16] Add tpl_surface_vblank_t to manage vblank object Change-Id: I56b54ccf7c22c9ef03c6973483ba1c0cb52b959d Signed-off-by: Joonbum Ko --- src/tpl_wl_egl_thread.c | 178 ++++++++++++++++++++++++++++-------------------- 1 file changed, 104 insertions(+), 74 deletions(-) diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index 7913614..7463197 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -37,6 +37,7 @@ static int wl_egl_buffer_key; typedef struct _tpl_wl_egl_display tpl_wl_egl_display_t; typedef struct _tpl_wl_egl_surface tpl_wl_egl_surface_t; typedef struct _tpl_wl_egl_buffer tpl_wl_egl_buffer_t; +typedef struct _surface_vblank tpl_surface_vblank_t; struct _tpl_wl_egl_display { tpl_gsource *disp_source; @@ -48,17 +49,19 @@ struct _tpl_wl_egl_display { struct wayland_tbm_client *wl_tbm_client; int last_error; /* errno of the last wl_display error*/ - tpl_bool_t wl_initialized; - tpl_bool_t tdm_initialized; - - tdm_client *tdm_client; - tpl_gsource *tdm_source; - int tdm_display_fd; + tpl_bool_t wl_initialized; tpl_bool_t use_wait_vblank; tpl_bool_t use_explicit_sync; tpl_bool_t prepared; + struct { + tdm_client *tdm_client; + tpl_gsource *tdm_source; + int tdm_display_fd; + tpl_bool_t tdm_initialized; + } tdm; + struct tizen_surface_shm *tss; /* used for surface buffer_flush */ struct wp_presentation *presentation; /* for presentation feedback */ struct zwp_linux_explicit_synchronization_v1 *explicit_sync; /* for explicit fence sync */ @@ -74,7 +77,7 @@ struct _tpl_wl_egl_surface { struct zwp_linux_surface_synchronization_v1 *surface_sync; /* for explicit fence sync */ struct tizen_surface_shm_flusher *tss_flusher; /* used for surface buffer_flush */ - tdm_client_vblank *vblank; + tpl_surface_vblank_t *vblank; /* surface information */ int render_done_cnt; @@ -95,7 +98,6 @@ struct _tpl_wl_egl_surface { int buffer_cnt; /* the number of using wl_egl_buffers */ tpl_gmutex buffers_mutex; - tpl_list_t *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */ tpl_list_t *presentation_feedbacks; /* for tracing presentation feedbacks */ struct { @@ -121,6 +123,12 @@ struct _tpl_wl_egl_surface { tpl_bool_t set_serial_is_used; }; +struct _surface_vblank { + tdm_client_vblank *tdm_vblank; + tpl_wl_egl_surface_t *wl_egl_surface; + tpl_list_t *waiting_buffers; /* for FIFO/FIFO_RELAXED modes */ +}; + typedef enum buffer_status { RELEASED = 0, // 0 DEQUEUED, // 1 @@ -269,7 +277,7 @@ __thread_func_tdm_dispatch(tpl_gsource *gsource, uint64_t message) return TPL_FALSE; } - tdm_err = tdm_client_handle_events(wl_egl_display->tdm_client); + tdm_err = tdm_client_handle_events(wl_egl_display->tdm.tdm_client); /* 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, @@ -283,7 +291,7 @@ __thread_func_tdm_dispatch(tpl_gsource *gsource, uint64_t message) tpl_gsource_destroy(gsource, TPL_FALSE); - wl_egl_display->tdm_source = NULL; + wl_egl_display->tdm.tdm_source = NULL; return TPL_FALSE; } @@ -300,15 +308,16 @@ __thread_func_tdm_finalize(tpl_gsource *gsource) TPL_LOG_T("WL_EGL", "tdm_destroy| wl_egl_display(%p) tdm_client(%p) tpl_gsource(%p)", - wl_egl_display, wl_egl_display->tdm_client, gsource); + wl_egl_display, wl_egl_display->tdm.tdm_client, gsource); - if (wl_egl_display->tdm_client) { - tdm_client_destroy(wl_egl_display->tdm_client); - wl_egl_display->tdm_client = NULL; - wl_egl_display->tdm_display_fd = -1; + if (wl_egl_display->tdm.tdm_client) { + tdm_client_destroy(wl_egl_display->tdm.tdm_client); + wl_egl_display->tdm.tdm_client = NULL; + wl_egl_display->tdm.tdm_display_fd = -1; + wl_egl_display->tdm.tdm_source = NULL; } - wl_egl_display->tdm_initialized = TPL_FALSE; + wl_egl_display->tdm.tdm_initialized = TPL_FALSE; } static tpl_gsource_functions tdm_funcs = { @@ -338,10 +347,10 @@ _thread_tdm_init(tpl_wl_egl_display_t *wl_egl_display) return TPL_ERROR_INVALID_OPERATION; } - wl_egl_display->tdm_display_fd = tdm_display_fd; - wl_egl_display->tdm_client = tdm_client; - wl_egl_display->tdm_source = NULL; - wl_egl_display->tdm_initialized = TPL_TRUE; + wl_egl_display->tdm.tdm_display_fd = tdm_display_fd; + wl_egl_display->tdm.tdm_client = tdm_client; + wl_egl_display->tdm.tdm_source = NULL; + wl_egl_display->tdm.tdm_initialized = TPL_TRUE; TPL_INFO("[TDM_CLIENT_INIT]", "wl_egl_display(%p) tdm_client(%p) tdm_display_fd(%d)", @@ -617,7 +626,8 @@ _thread_init(void *data) wl_egl_display, wl_egl_display->wl_display); } - if (_thread_tdm_init(wl_egl_display) != TPL_ERROR_NONE) { + if (wl_egl_display->use_wait_vblank && + _thread_tdm_init(wl_egl_display) != TPL_ERROR_NONE) { TPL_WARN("Failed to initialize tdm-client. TPL_WAIT_VLANK:DISABLED"); } @@ -770,7 +780,11 @@ __tpl_wl_egl_display_init(tpl_display_t *display) display->backend.data = wl_egl_display; display->bufmgr_fd = -1; - wl_egl_display->tdm_initialized = TPL_FALSE; + wl_egl_display->tdm.tdm_initialized = TPL_FALSE; + wl_egl_display->tdm.tdm_client = NULL; + wl_egl_display->tdm.tdm_display_fd = -1; + wl_egl_display->tdm.tdm_source = NULL; + wl_egl_display->wl_initialized = TPL_FALSE; wl_egl_display->ev_queue = NULL; @@ -815,15 +829,21 @@ __tpl_wl_egl_display_init(tpl_display_t *display) goto free_display; } - wl_egl_display->tdm_source = tpl_gsource_create(wl_egl_display->thread, - (void *)wl_egl_display, - wl_egl_display->tdm_display_fd, - &tdm_funcs, SOURCE_TYPE_NORMAL); - if (!wl_egl_display->tdm_source) { - TPL_ERR("Failed to create tdm_gsource\n"); - goto free_display; + if (wl_egl_display->use_wait_vblank && + wl_egl_display->tdm.tdm_initialized) { + wl_egl_display->tdm.tdm_source = tpl_gsource_create(wl_egl_display->thread, + (void *)wl_egl_display, + wl_egl_display->tdm.tdm_display_fd, + &tdm_funcs, SOURCE_TYPE_NORMAL); + if (!wl_egl_display->tdm.tdm_source) { + TPL_ERR("Failed to create tdm_gsource\n"); + goto free_display; + } } + wl_egl_display->use_wait_vblank = (wl_egl_display->tdm.tdm_initialized && + (wl_egl_display->tdm.tdm_source != NULL)); + TPL_INFO("[DISPLAY_INIT]", "wl_egl_display(%p) tpl_gthread(%p) wl_display(%p)", wl_egl_display, @@ -840,8 +860,8 @@ __tpl_wl_egl_display_init(tpl_display_t *display) free_display: if (wl_egl_display->thread) { - if (wl_egl_display->tdm_source) - tpl_gsource_destroy(wl_egl_display->tdm_source, TPL_TRUE); + if (wl_egl_display->tdm.tdm_source) + tpl_gsource_destroy(wl_egl_display->tdm.tdm_source, TPL_TRUE); if (wl_egl_display->disp_source) tpl_gsource_destroy(wl_egl_display->disp_source, TPL_TRUE); @@ -870,9 +890,9 @@ __tpl_wl_egl_display_fini(tpl_display_t *display) wl_egl_display->thread, wl_egl_display->wl_display); - if (wl_egl_display->tdm_source && wl_egl_display->tdm_initialized) { - tpl_gsource_destroy(wl_egl_display->tdm_source, TPL_TRUE); - wl_egl_display->tdm_source = NULL; + if (wl_egl_display->tdm.tdm_source && wl_egl_display->tdm.tdm_initialized) { + tpl_gsource_destroy(wl_egl_display->tdm.tdm_source, TPL_TRUE); + wl_egl_display->tdm.tdm_source = NULL; } if (wl_egl_display->disp_source) { @@ -1431,9 +1451,9 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface) wl_egl_surface->presentation_sync.fd = -1; } - if (wl_egl_surface->vblank_waiting_buffers) { - __tpl_list_free(wl_egl_surface->vblank_waiting_buffers, NULL); - wl_egl_surface->vblank_waiting_buffers = NULL; + if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) { + __tpl_list_free(wl_egl_surface->vblank->waiting_buffers, NULL); + wl_egl_surface->vblank->waiting_buffers = NULL; } tpl_gmutex_unlock(&wl_egl_surface->presentation_sync.mutex); @@ -1455,10 +1475,16 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface) } if (wl_egl_surface->vblank) { + tpl_surface_vblank_t *vblank = wl_egl_surface->vblank; TPL_INFO("[VBLANK_DESTROY]", - "wl_egl_surface(%p) vblank(%p)", - wl_egl_surface, wl_egl_surface->vblank); - tdm_client_vblank_destroy(wl_egl_surface->vblank); + "wl_egl_surface(%p) surface_vblank(%p) tdm_vblank(%p)", + wl_egl_surface, vblank, + vblank->tdm_vblank); + tdm_client_vblank_destroy(vblank->tdm_vblank); + vblank->tdm_vblank = NULL; + vblank->wl_egl_surface = NULL; + free(vblank); + wl_egl_surface->vblank = NULL; } @@ -1738,7 +1764,7 @@ _thread_create_tbm_queue(tpl_wl_egl_surface_t *wl_egl_surface, static tdm_client_vblank* _thread_create_tdm_client_vblank(tdm_client *tdm_client) { - tdm_client_vblank *vblank = NULL; + tdm_client_vblank *tdm_vblank = NULL; tdm_client_output *tdm_output = NULL; tdm_error tdm_err = TDM_ERROR_NONE; @@ -1753,22 +1779,23 @@ _thread_create_tdm_client_vblank(tdm_client *tdm_client) return NULL; } - vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err); - if (!vblank || tdm_err != TDM_ERROR_NONE) { - TPL_ERR("Failed to create vblank. tdm_err(%d)", tdm_err); + tdm_vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err); + if (!tdm_vblank || tdm_err != TDM_ERROR_NONE) { + TPL_ERR("Failed to create tdm_vblank. tdm_err(%d)", tdm_err); return NULL; } - tdm_client_vblank_set_enable_fake(vblank, 1); - tdm_client_vblank_set_sync(vblank, 0); + tdm_client_vblank_set_enable_fake(tdm_vblank, 1); + tdm_client_vblank_set_sync(tdm_vblank, 0); - return vblank; + return tdm_vblank; } static void _thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface) { tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display; + tpl_surface_vblank_t *vblank = NULL; wl_egl_surface->tbm_queue = _thread_create_tbm_queue( wl_egl_surface, @@ -1792,15 +1819,30 @@ _thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface) CLIENT_QUEUE_SIZE, wl_egl_surface->format); - wl_egl_surface->vblank = _thread_create_tdm_client_vblank( - wl_egl_display->tdm_client); - if (wl_egl_surface->vblank) { - TPL_INFO("[VBLANK_INIT]", - "wl_egl_surface(%p) tdm_client(%p) vblank(%p)", - wl_egl_surface, wl_egl_display->tdm_client, - wl_egl_surface->vblank); + if (wl_egl_display->use_wait_vblank) { + vblank = (tpl_surface_vblank_t *)calloc(1, sizeof(tpl_surface_vblank_t)); + if (vblank) { + vblank->tdm_vblank = _thread_create_tdm_client_vblank( + wl_egl_display->tdm.tdm_client); + if (!vblank->tdm_vblank) { + TPL_ERR("Failed to create tdm_vblank from tdm_client(%p)", + wl_egl_display->tdm.tdm_client); + free(vblank); + vblank = NULL; + } else { + vblank->waiting_buffers = __tpl_list_alloc(); + vblank->wl_egl_surface = wl_egl_surface; + + TPL_INFO("[VBLANK_INIT]", + "wl_egl_surface(%p) tdm_client(%p) tdm_vblank(%p)", + wl_egl_surface, wl_egl_display->tdm.tdm_client, + vblank->tdm_vblank); + } + } } + wl_egl_surface->vblank = vblank; + if (wl_egl_display->tss) { wl_egl_surface->tss_flusher = tizen_surface_shm_get_flusher(wl_egl_display->tss, @@ -1831,7 +1873,6 @@ _thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface) } } - wl_egl_surface->vblank_waiting_buffers = __tpl_list_alloc(); wl_egl_surface->presentation_feedbacks = __tpl_list_alloc(); } @@ -2572,7 +2613,6 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message) tpl_wl_egl_buffer_t *wl_egl_buffer = (tpl_wl_egl_buffer_t *)tpl_gsource_get_data(gsource); tpl_wl_egl_surface_t *wl_egl_surface = wl_egl_buffer->wl_egl_surface; - tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display; tbm_surface_h tbm_surface = wl_egl_buffer->tbm_surface; wl_egl_surface->render_done_cnt++; @@ -2590,10 +2630,10 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message) tpl_gmutex_lock(&wl_egl_surface->surf_mutex); - if (!wl_egl_display->use_wait_vblank || wl_egl_surface->vblank_done) + if (wl_egl_surface->vblank == NULL || wl_egl_surface->vblank_done) _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer); else - __tpl_list_push_back(wl_egl_surface->vblank_waiting_buffers, + __tpl_list_push_back(wl_egl_surface->vblank->waiting_buffers, wl_egl_buffer); tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); @@ -2696,11 +2736,11 @@ _thread_surface_queue_acquire(tpl_wl_egl_surface_t *wl_egl_surface) } if (ready_to_commit) { - if (!wl_egl_display->use_wait_vblank || wl_egl_surface->vblank_done) + if (wl_egl_surface->vblank == NULL || wl_egl_surface->vblank_done) ready_to_commit = TPL_TRUE; else { wl_egl_buffer->status = WAITING_VBLANK; - __tpl_list_push_back(wl_egl_surface->vblank_waiting_buffers, wl_egl_buffer); + __tpl_list_push_back(wl_egl_surface->vblank->waiting_buffers, wl_egl_buffer); ready_to_commit = TPL_FALSE; } } @@ -2734,7 +2774,7 @@ __cb_tdm_client_vblank(tdm_client_vblank *vblank, tdm_error error, tpl_gmutex_lock(&wl_egl_surface->surf_mutex); wl_egl_buffer = (tpl_wl_egl_buffer_t *)__tpl_list_pop_front( - wl_egl_surface->vblank_waiting_buffers, + wl_egl_surface->vblank->waiting_buffers, NULL); if (wl_egl_buffer) _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer); @@ -3012,19 +3052,9 @@ static tpl_result_t _thread_surface_vblank_wait(tpl_wl_egl_surface_t *wl_egl_surface) { tdm_error tdm_err = TDM_ERROR_NONE; - tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display; + tpl_surface_vblank_t *vblank = wl_egl_surface->vblank; - if (wl_egl_surface->vblank == NULL) { - wl_egl_surface->vblank = - _thread_create_tdm_client_vblank(wl_egl_display->tdm_client); - if (!wl_egl_surface->vblank) { - TPL_WARN("Failed to create vblank. wl_egl_surface(%p)", - wl_egl_surface); - return TPL_ERROR_OUT_OF_MEMORY; - } - } - - tdm_err = tdm_client_vblank_wait(wl_egl_surface->vblank, + tdm_err = tdm_client_vblank_wait(vblank->tdm_vblank, wl_egl_surface->post_interval, __cb_tdm_client_vblank, (void *)wl_egl_surface); @@ -3198,7 +3228,7 @@ _thread_wl_surface_commit(tpl_wl_egl_surface_t *wl_egl_surface, wl_egl_buffer, wl_egl_buffer->wl_buffer, wl_egl_buffer->tbm_surface, wl_egl_buffer->bo_name); - if (wl_egl_display->use_wait_vblank && + if (wl_egl_surface->vblank != NULL && _thread_surface_vblank_wait(wl_egl_surface) != TPL_ERROR_NONE) TPL_ERR("Failed to set wait vblank."); -- 2.7.4 From 4d622ed273db503b8eec82435aee9f73bcc248a7 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Mon, 17 May 2021 16:23:49 +0900 Subject: [PATCH 05/16] Added surface_vblanks list for safe destroy. - If an error occurs in tdm_client_display, it is a problem that cannot be recovered, but it should not affect rendering. - In this case, destroy tdm_client and stop using wait_vblank. - However, a problem occurs when accessing vblank after tdm_client_destroy. - Therefore, the created vblanks must be destroyed first and then destroy the tdm_client. - The added surface_vblanks list is to trace the created vblanks. Change-Id: I3eae60842761dd6cda0042ff941e0f0736633b4c Signed-off-by: Joonbum Ko --- src/tpl_wl_egl_thread.c | 52 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 11 deletions(-) diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index 7463197..deba3b6 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -60,6 +60,7 @@ struct _tpl_wl_egl_display { tpl_gsource *tdm_source; int tdm_display_fd; tpl_bool_t tdm_initialized; + tpl_list_t *surface_vblanks; } tdm; struct tizen_surface_shm *tss; /* used for surface buffer_flush */ @@ -238,6 +239,8 @@ _thread_surface_queue_acquire(tpl_wl_egl_surface_t *wl_egl_surface); static void _thread_wl_surface_commit(tpl_wl_egl_surface_t *wl_egl_surface, tpl_wl_egl_buffer_t *wl_egl_buffer); +static void +__cb_surface_vblank_free(void *data); static tpl_bool_t _check_native_handle_is_wl_display(tpl_handle_t display) @@ -311,12 +314,20 @@ __thread_func_tdm_finalize(tpl_gsource *gsource) wl_egl_display, wl_egl_display->tdm.tdm_client, gsource); if (wl_egl_display->tdm.tdm_client) { + + if (wl_egl_display->tdm.surface_vblanks) { + __tpl_list_free(wl_egl_display->tdm.surface_vblanks, + __cb_surface_vblank_free); + wl_egl_display->tdm.surface_vblanks = NULL; + } + tdm_client_destroy(wl_egl_display->tdm.tdm_client); wl_egl_display->tdm.tdm_client = NULL; wl_egl_display->tdm.tdm_display_fd = -1; wl_egl_display->tdm.tdm_source = NULL; } + wl_egl_display->use_wait_vblank = TPL_FALSE; wl_egl_display->tdm.tdm_initialized = TPL_FALSE; } @@ -351,6 +362,7 @@ _thread_tdm_init(tpl_wl_egl_display_t *wl_egl_display) wl_egl_display->tdm.tdm_client = tdm_client; wl_egl_display->tdm.tdm_source = NULL; wl_egl_display->tdm.tdm_initialized = TPL_TRUE; + wl_egl_display->tdm.surface_vblanks = __tpl_list_alloc(); TPL_INFO("[TDM_CLIENT_INIT]", "wl_egl_display(%p) tdm_client(%p) tdm_display_fd(%d)", @@ -1475,17 +1487,10 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface) } if (wl_egl_surface->vblank) { - tpl_surface_vblank_t *vblank = wl_egl_surface->vblank; - TPL_INFO("[VBLANK_DESTROY]", - "wl_egl_surface(%p) surface_vblank(%p) tdm_vblank(%p)", - wl_egl_surface, vblank, - vblank->tdm_vblank); - tdm_client_vblank_destroy(vblank->tdm_vblank); - vblank->tdm_vblank = NULL; - vblank->wl_egl_surface = NULL; - free(vblank); - - wl_egl_surface->vblank = NULL; + __tpl_list_remove_data(wl_egl_display->tdm.surface_vblanks, + (void *)wl_egl_surface->vblank, + TPL_FIRST, + __cb_surface_vblank_free); } if (wl_egl_surface->tbm_queue) { @@ -1792,6 +1797,28 @@ _thread_create_tdm_client_vblank(tdm_client *tdm_client) } static void +__cb_surface_vblank_free(void *data) +{ + TPL_CHECK_ON_NULL_RETURN(data); + + tpl_surface_vblank_t *vblank = (tpl_surface_vblank_t *)data; + tpl_wl_egl_surface_t *wl_egl_surface = vblank->wl_egl_surface; + + TPL_INFO("[VBLANK_DESTROY]", + "wl_egl_surface(%p) surface_vblank(%p) tdm_vblank(%p)", + wl_egl_surface, vblank, + vblank->tdm_vblank); + + tdm_client_vblank_destroy(vblank->tdm_vblank); + vblank->tdm_vblank = NULL; + vblank->wl_egl_surface = NULL; + + free(vblank); + + wl_egl_surface->vblank = NULL; +} + +static void _thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface) { tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display; @@ -1833,6 +1860,9 @@ _thread_wl_egl_surface_init(tpl_wl_egl_surface_t *wl_egl_surface) vblank->waiting_buffers = __tpl_list_alloc(); vblank->wl_egl_surface = wl_egl_surface; + __tpl_list_push_back(wl_egl_display->tdm.surface_vblanks, + (void *)vblank); + TPL_INFO("[VBLANK_INIT]", "wl_egl_surface(%p) tdm_client(%p) tdm_vblank(%p)", wl_egl_surface, wl_egl_display->tdm.tdm_client, -- 2.7.4 From 3fc8687e11ef6428f6f9f2b70b931be65ce272b4 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 18 May 2021 15:38:21 +0900 Subject: [PATCH 06/16] Enhanced protection against fence waiting buffers. - timeout value up to 50ms. - Modified to guarantee until the waiting buffer completes the operation through surf_mutex. Change-Id: If0fd6de234f5f79369dee23d9cddda9cd961f882 Signed-off-by: Joonbum Ko --- src/tpl_wl_egl_thread.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index deba3b6..91d6e65 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -1959,17 +1959,19 @@ _tpl_wl_egl_surface_buffer_clear(tpl_wl_egl_surface_t *wl_egl_surface) tpl_gmutex_unlock(&wl_egl_display->wl_event_mutex); wait_result = tpl_cond_timed_wait(&wl_egl_buffer->cond, &wl_egl_buffer->mutex, - 16); /* 16ms */ + 50); /* 50ms */ tpl_gmutex_lock(&wl_egl_display->wl_event_mutex); - status = wl_egl_buffer->status; - if (wait_result == TPL_ERROR_TIME_OUT) TPL_WARN("timeout occured waiting signaled. wl_egl_buffer(%p)", wl_egl_buffer); } } + tpl_gmutex_lock(&wl_egl_surface->surf_mutex); + + status = wl_egl_buffer->status; /* update status */ + /* ACQUIRED, WAITING_SIGNALED, WAITING_VBLANK, COMMITTED */ /* It has been acquired but has not yet been released, so this * buffer must be released. */ @@ -1995,6 +1997,8 @@ _tpl_wl_egl_surface_buffer_clear(tpl_wl_egl_surface_t *wl_egl_surface) wl_egl_buffer->tbm_surface, tsq_err); } + tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); + wl_egl_buffer->status = RELEASED; tpl_gmutex_unlock(&wl_egl_buffer->mutex); @@ -2030,9 +2034,7 @@ __tpl_wl_egl_surface_fini(tpl_surface_t *surface) wl_egl_surface, wl_egl_surface->wl_surface, wl_egl_surface->tbm_queue); - tpl_gmutex_lock(&wl_egl_surface->surf_mutex); _tpl_wl_egl_surface_buffer_clear(wl_egl_surface); - tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); if (wl_egl_surface->surf_source) tpl_gsource_destroy(wl_egl_surface->surf_source, TPL_TRUE); -- 2.7.4 From 5dc1cd788f0f152d67b262d9b5a4d075b9a445cf Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 18 May 2021 17:28:29 +0900 Subject: [PATCH 07/16] Expand the condition of need_to_wait in buffer_clear. - AS-IS : The need_to_wait flags is set to true under different conditions according to the use of explicit_sync. - PROBLEMS : A buffer that is not included in the condition may cause thread conflict. - TO-BE : The buffers whose status is from ENQUEUED to COMMITTED will be cleared after waiting until wl_surface_commit. Change-Id: Ic75de641182cfcfec2df71b57a982e1e63a52fe8 Signed-off-by: Joonbum Ko --- src/tpl_wl_egl_thread.c | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index 91d6e65..d6f37f2 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -1463,11 +1463,6 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface) wl_egl_surface->presentation_sync.fd = -1; } - if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) { - __tpl_list_free(wl_egl_surface->vblank->waiting_buffers, NULL); - wl_egl_surface->vblank->waiting_buffers = NULL; - } - tpl_gmutex_unlock(&wl_egl_surface->presentation_sync.mutex); if (wl_egl_surface->surface_sync) { @@ -1486,11 +1481,17 @@ _thread_wl_egl_surface_fini(tpl_wl_egl_surface_t *wl_egl_surface) wl_egl_surface->tss_flusher = NULL; } + if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) { + __tpl_list_free(wl_egl_surface->vblank->waiting_buffers, NULL); + wl_egl_surface->vblank->waiting_buffers = NULL; + } + if (wl_egl_surface->vblank) { __tpl_list_remove_data(wl_egl_display->tdm.surface_vblanks, (void *)wl_egl_surface->vblank, TPL_FIRST, __cb_surface_vblank_free); + wl_egl_surface->vblank = NULL; } if (wl_egl_surface->tbm_queue) { @@ -1947,13 +1948,7 @@ _tpl_wl_egl_surface_buffer_clear(tpl_wl_egl_surface_t *wl_egl_surface) tpl_bool_t need_to_wait = TPL_FALSE; tpl_result_t wait_result = TPL_ERROR_NONE; - if (!wl_egl_display->use_explicit_sync && - status < WAITING_VBLANK) - need_to_wait = TPL_TRUE; - - if (wl_egl_display->use_explicit_sync && - status < COMMITTED) - need_to_wait = TPL_TRUE; + need_to_wait = (status < COMMITTED); if (need_to_wait) { tpl_gmutex_unlock(&wl_egl_display->wl_event_mutex); @@ -2657,7 +2652,6 @@ __thread_func_waiting_source_dispatch(tpl_gsource *gsource, uint64_t message) tpl_gmutex_lock(&wl_egl_buffer->mutex); wl_egl_buffer->status = WAITING_VBLANK; - tpl_gcond_signal(&wl_egl_buffer->cond); tpl_gmutex_unlock(&wl_egl_buffer->mutex); tpl_gmutex_lock(&wl_egl_surface->surf_mutex); @@ -2805,11 +2799,14 @@ __cb_tdm_client_vblank(tdm_client_vblank *vblank, tdm_error error, wl_egl_surface->vblank_done = TPL_TRUE; tpl_gmutex_lock(&wl_egl_surface->surf_mutex); - wl_egl_buffer = (tpl_wl_egl_buffer_t *)__tpl_list_pop_front( - wl_egl_surface->vblank->waiting_buffers, - NULL); - if (wl_egl_buffer) - _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer); + if (wl_egl_surface->vblank && wl_egl_surface->vblank->waiting_buffers) { + wl_egl_buffer = (tpl_wl_egl_buffer_t *)__tpl_list_pop_front( + wl_egl_surface->vblank->waiting_buffers, + NULL); + + if (wl_egl_buffer) + _thread_wl_surface_commit(wl_egl_surface, wl_egl_buffer); + } tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); } /* -- END -- tdm_client vblank callback function */ -- 2.7.4 From 13033eb1e54fb67b19643cc22fe7f4814191761c Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 20 May 2021 14:37:32 +0900 Subject: [PATCH 08/16] Package version up to 1.8.8 Change-Id: I32040f47e2a577cffcb248fcc2fa0c0dc9d16e93 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 795b5b2..0698e6f 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 8 -%define TPL_VERSION_PATCH 7 +%define TPL_VERSION_PATCH 8 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From 709d66fc80e2a8f2146df23f10e52cee3cc324aa Mon Sep 17 00:00:00 2001 From: Tianhao Ni Date: Fri, 4 Jun 2021 13:42:48 +0800 Subject: [PATCH 09/16] Fix ws-testcase build issue: - Issue: undefined reference to '__tpl_display_choose_backend_wl_egl_thread' undefined refetence to '__tpl_display_choose_backend_wayland_vk_wsi' - Fix: Replace __tpl_display_choose_backend_wl_egl_thread() with __tpl_display_choose_backend_wl_egl_thread2() Replace __tpl_display_choose_backend_wayland_vk_wsi() with __tpl_display_choose_backend_wayland_vk_wsi_thread() Change-Id: I1d562bbaf37c4c45b238e221b125bdb42cc6db1a Signed-off-by: Tianhao Ni --- src/tpl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tpl.c b/src/tpl.c index f40889d..5482bc1 100644 --- a/src/tpl.c +++ b/src/tpl.c @@ -274,14 +274,14 @@ __tpl_display_choose_backend(tpl_handle_t native_dpy) if (__tpl_display_choose_backend_tbm(native_dpy) == TPL_TRUE) return TPL_BACKEND_TBM; if (wl_egl_thread) { - if (__tpl_display_choose_backend_wl_egl_thread(native_dpy)) + if (__tpl_display_choose_backend_wl_egl_thread2(native_dpy)) return TPL_BACKEND_WAYLAND_THREAD; } else { if (__tpl_display_choose_backend_wayland_egl(native_dpy)) return TPL_BACKEND_WAYLAND; } - if (__tpl_display_choose_backend_wayland_vk_wsi(native_dpy) == TPL_TRUE) - return TPL_BACKEND_WAYLAND_VULKAN_WSI; + if (__tpl_display_choose_backend_wayland_vk_wsi_thread(native_dpy) == TPL_TRUE) + return TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD; #endif #ifdef TPL_WINSYS_DRI2 if (__tpl_display_choose_backend_x11_dri2(native_dpy) == TPL_TRUE) -- 2.7.4 From 80dd92be4a4af352449a0a13870fcd61ff4537c5 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 27 May 2021 20:14:47 +0900 Subject: [PATCH 10/16] Clarified thread message and corrected some bugs. Change-Id: I63fec57eb66104c87757cf5f665e8160859bddc8 Signed-off-by: Joonbum Ko --- src/tpl_wl_egl_thread.c | 36 +++++++++++++++++++--------- src/tpl_wl_vk_thread.c | 64 +++++++++++++++++++++++++++++++------------------ 2 files changed, 66 insertions(+), 34 deletions(-) diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index d6f37f2..c564ae1 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -68,6 +68,12 @@ struct _tpl_wl_egl_display { struct zwp_linux_explicit_synchronization_v1 *explicit_sync; /* for explicit fence sync */ }; +typedef enum surf_message { + NONE_MESSAGE = 0, + INIT_SURFACE, + ACQUIRABLE, +} surf_message; + struct _tpl_wl_egl_surface { tpl_gsource *surf_source; @@ -114,6 +120,8 @@ struct _tpl_wl_egl_surface { tpl_gmutex surf_mutex; tpl_gcond surf_cond; + surf_message sent_message; + /* for waiting draw done */ tpl_bool_t use_render_done_fence; tpl_bool_t is_activated; @@ -1415,9 +1423,11 @@ __cb_tbm_queue_acquirable_callback(tbm_surface_queue_h tbm_queue, TPL_CHECK_ON_NULL_RETURN(wl_egl_surface); tpl_gmutex_lock(&wl_egl_surface->surf_mutex); - - tpl_gsource_send_message(wl_egl_surface->surf_source, 2); - + if (wl_egl_surface->sent_message == NONE_MESSAGE) { + wl_egl_surface->sent_message = ACQUIRABLE; + tpl_gsource_send_message(wl_egl_surface->surf_source, + wl_egl_surface->sent_message); + } tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); } /* -- END -- tbm_surface_queue callback funstions */ @@ -1512,22 +1522,22 @@ __thread_func_surf_dispatch(tpl_gsource *gsource, uint64_t message) wl_egl_surface = (tpl_wl_egl_surface_t *)tpl_gsource_get_data(gsource); - /* Initialize surface */ - if (message == 1) { - tpl_gmutex_lock(&wl_egl_surface->surf_mutex); + tpl_gmutex_lock(&wl_egl_surface->surf_mutex); + if (message == INIT_SURFACE) { /* Initialize surface */ TPL_DEBUG("wl_egl_surface(%p) initialize message received!", wl_egl_surface); _thread_wl_egl_surface_init(wl_egl_surface); tpl_gcond_signal(&wl_egl_surface->surf_cond); - tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); - } else if (message == 2) { - tpl_gmutex_lock(&wl_egl_surface->surf_mutex); + } else if (message == ACQUIRABLE) { /* Acquirable */ TPL_DEBUG("wl_egl_surface(%p) acquirable message received!", wl_egl_surface); _thread_surface_queue_acquire(wl_egl_surface); - tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); } + wl_egl_surface->sent_message = NONE_MESSAGE; + + tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); + return TPL_TRUE; } @@ -1627,6 +1637,8 @@ __tpl_wl_egl_surface_init(tpl_surface_t *surface) wl_egl_surface->commit_sync.fd = -1; wl_egl_surface->presentation_sync.fd = -1; + wl_egl_surface->sent_message = NONE_MESSAGE; + { int i = 0; for (i = 0; i < BUFFER_ARRAY_SIZE; i++) @@ -1669,7 +1681,9 @@ __tpl_wl_egl_surface_init(tpl_surface_t *surface) /* Initialize in thread */ tpl_gmutex_lock(&wl_egl_surface->surf_mutex); - tpl_gsource_send_message(wl_egl_surface->surf_source, 1); + wl_egl_surface->sent_message = INIT_SURFACE; + tpl_gsource_send_message(wl_egl_surface->surf_source, + wl_egl_surface->sent_message); tpl_gcond_wait(&wl_egl_surface->surf_cond, &wl_egl_surface->surf_mutex); tpl_gmutex_unlock(&wl_egl_surface->surf_mutex); diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 20baea3..4ae5b55 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -82,6 +82,14 @@ struct _tpl_wl_vk_swapchain { tpl_util_atomic_uint ref_cnt; }; +typedef enum surf_message { + NONE_MESSAGE = 0, + INIT_SURFACE, + CREATE_QUEUE, + DESTROY_QUEUE, + ACQUIRABLE, +} surf_message; + struct _tpl_wl_vk_surface { tpl_gsource *surf_source; @@ -113,6 +121,8 @@ struct _tpl_wl_vk_surface { tpl_bool_t reset; /* TRUE if queue reseted by external */ tpl_bool_t vblank_done; + surf_message sent_message; + int post_interval; }; @@ -1101,15 +1111,13 @@ __thread_func_surf_dispatch(tpl_gsource *gsource, uint64_t message) wl_vk_surface = (tpl_wl_vk_surface_t *)tpl_gsource_get_data(gsource); - if (message == 1) { /* Initialize surface */ - tpl_gmutex_lock(&wl_vk_surface->surf_mutex); + tpl_gmutex_lock(&wl_vk_surface->surf_mutex); + if (message == INIT_SURFACE) { /* Initialize surface */ TPL_DEBUG("wl_vk_surface(%p) initialize message received!", wl_vk_surface); _thread_wl_vk_surface_init(wl_vk_surface); - tpl_gcond_signal(&wl_vk_surface->surf_cond); - tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); - } else if (message == 2) { /* Create tbm_surface_queue */ - tpl_gmutex_lock(&wl_vk_surface->surf_mutex); + tpl_gcond_signal(&wl_vk_surface->surf_cond); + } else if (message == CREATE_QUEUE) { /* Create tbm_surface_queue */ TPL_DEBUG("wl_vk_surface(%p) queue creation message received!", wl_vk_surface); if (_thread_swapchain_create_tbm_queue(wl_vk_surface) @@ -1118,9 +1126,12 @@ __thread_func_surf_dispatch(tpl_gsource *gsource, uint64_t message) wl_vk_surface); } tpl_gcond_signal(&wl_vk_surface->surf_cond); - tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); - } else if (message == 3) { /* Acquirable message */ - tpl_gmutex_lock(&wl_vk_surface->surf_mutex); + } else if (message == DESTROY_QUEUE) { /* swapchain destroy */ + TPL_DEBUG("wl_vk_surface(%p) swapchain destroy message received!", + wl_vk_surface); + _thread_swapchain_destroy_tbm_queue(wl_vk_surface); + tpl_gcond_signal(&wl_vk_surface->surf_cond); + } else if (message == ACQUIRABLE) { /* Acquirable message */ TPL_DEBUG("wl_vk_surface(%p) acquirable message received!", wl_vk_surface); if (_thread_surface_queue_acquire(wl_vk_surface) @@ -1128,16 +1139,13 @@ __thread_func_surf_dispatch(tpl_gsource *gsource, uint64_t message) TPL_ERR("Failed to acquire from tbm_queue. wl_vk_surface(%p)", wl_vk_surface); } - tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); - } else if (message == 4) { /* swapchain destroy */ - tpl_gmutex_lock(&wl_vk_surface->surf_mutex); - TPL_DEBUG("wl_vk_surface(%p) swapchain destroy message received!", - wl_vk_surface); - _thread_swapchain_destroy_tbm_queue(wl_vk_surface); - tpl_gcond_signal(&wl_vk_surface->surf_cond); - tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); } + /* init to NONE_MESSAGE */ + wl_vk_surface->sent_message = NONE_MESSAGE; + + tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); + return TPL_TRUE; } @@ -1214,6 +1222,8 @@ __tpl_wl_vk_surface_init(tpl_surface_t *surface) wl_vk_surface->vblank = NULL; wl_vk_surface->surface_sync = NULL; + wl_vk_surface->sent_message = NONE_MESSAGE; + wl_vk_surface->post_interval = surface->post_interval; { @@ -1230,7 +1240,9 @@ __tpl_wl_vk_surface_init(tpl_surface_t *surface) /* Initialize in thread */ tpl_gmutex_lock(&wl_vk_surface->surf_mutex); - tpl_gsource_send_message(wl_vk_surface->surf_source, 1); + wl_vk_surface->sent_message = INIT_SURFACE; + tpl_gsource_send_message(wl_vk_surface->surf_source, + wl_vk_surface->sent_message); tpl_gcond_wait(&wl_vk_surface->surf_cond, &wl_vk_surface->surf_mutex); tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); @@ -1389,9 +1401,11 @@ __cb_tbm_queue_acquirable_callback(tbm_surface_queue_h tbm_queue, TPL_CHECK_ON_NULL_RETURN(wl_vk_surface); tpl_gmutex_lock(&wl_vk_surface->surf_mutex); - - tpl_gsource_send_message(wl_vk_surface->surf_source, 3); - + if (wl_vk_surface->sent_message == NONE_MESSAGE) { + wl_vk_surface->sent_message = ACQUIRABLE; + tpl_gsource_send_message(wl_vk_surface->surf_source, + wl_vk_surface->sent_message); + } tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); } @@ -1580,7 +1594,9 @@ __tpl_wl_vk_surface_create_swapchain(tpl_surface_t *surface, tpl_gmutex_lock(&wl_vk_surface->surf_mutex); /* send swapchain create tbm_queue message */ - tpl_gsource_send_message(wl_vk_surface->surf_source, 2); + wl_vk_surface->sent_message = CREATE_QUEUE; + tpl_gsource_send_message(wl_vk_surface->surf_source, + wl_vk_surface->sent_message); tpl_gcond_wait(&wl_vk_surface->surf_cond, &wl_vk_surface->surf_mutex); tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); @@ -1664,7 +1680,9 @@ __tpl_wl_vk_surface_destroy_swapchain(tpl_surface_t *surface) _tpl_wl_vk_surface_buffer_clear(wl_vk_surface); tpl_gmutex_lock(&wl_vk_surface->surf_mutex); - tpl_gsource_send_message(wl_vk_surface->surf_source, 4); + wl_vk_surface->sent_message = DESTROY_QUEUE; + tpl_gsource_send_message(wl_vk_surface->surf_source, + wl_vk_surface->sent_message); tpl_gcond_wait(&wl_vk_surface->surf_cond, &wl_vk_surface->surf_mutex); tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); -- 2.7.4 From 93ba663e8f4b9ca339de5ec5bb4e3d9d4dd6e4be Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 25 May 2021 18:22:55 +0900 Subject: [PATCH 11/16] Add null checking to prevent problem. Change-Id: Icd94a00b015b5100e6beaa59d435731836a2d376 Signed-off-by: Joonbum Ko --- src/tpl_wl_egl_thread.c | 8 ++++++-- src/tpl_wl_vk_thread.c | 5 +++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index c564ae1..7813981 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -2548,12 +2548,16 @@ __tpl_wl_egl_surface_enqueue_buffer(tpl_surface_t *surface, return TPL_ERROR_INVALID_PARAMETER; } + wl_egl_buffer = _get_wl_egl_buffer(tbm_surface); + if (!wl_egl_buffer) { + TPL_ERR("Failed to get wl_egl_buffer from tbm_surface(%p)", tbm_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + bo_name = _get_tbm_surface_bo_name(tbm_surface); TRACE_MARK("[ENQ] BO_NAME:%d", bo_name); - wl_egl_buffer = _get_wl_egl_buffer(tbm_surface); - tpl_gmutex_lock(&wl_egl_buffer->mutex); /* If there are received region information, save it to wl_egl_buffer */ diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 4ae5b55..4ea1a68 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -2067,6 +2067,11 @@ __tpl_wl_vk_surface_enqueue_buffer(tpl_surface_t *surface, TPL_ERROR_INVALID_PARAMETER); wl_vk_buffer = _get_wl_vk_buffer(tbm_surface); + if (!wl_vk_buffer) { + TPL_ERR("Failed to get wl_vk_buffer from tbm_surface(%p)", tbm_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + bo_name = wl_vk_buffer->bo_name; tpl_gmutex_lock(&wl_vk_buffer->mutex); -- 2.7.4 From 49497c55dbce81af89175d8b1b3fe7a61abd6d8d Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 27 May 2021 19:56:35 +0900 Subject: [PATCH 12/16] Remove duplicate initialize. Change-Id: Iebcb9c25dd42fe487dec172327f5161ff56ea0f1 Signed-off-by: Joonbum Ko --- src/tpl_wl_vk_thread.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 4ea1a68..12ecfca 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -1854,6 +1854,9 @@ _wl_vk_buffer_create(tpl_wl_vk_surface_t *wl_vk_surface, wl_vk_buffer->rects = NULL; wl_vk_buffer->num_rects = 0; + wl_vk_buffer->need_to_commit = TPL_FALSE; + wl_vk_buffer->buffer_release = NULL; + tpl_gmutex_init(&wl_vk_buffer->mutex); tpl_gcond_init(&wl_vk_buffer->cond); @@ -1897,9 +1900,6 @@ _wl_vk_buffer_create(tpl_wl_vk_surface_t *wl_vk_surface, wl_vk_buffer->bo_name); } - wl_vk_buffer->need_to_commit = TPL_FALSE; - wl_vk_buffer->buffer_release = NULL; - return wl_vk_buffer; } -- 2.7.4 From 498cfcf676a285d387de27171c155ca013a5b69d Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Fri, 4 Jun 2021 15:55:36 +0900 Subject: [PATCH 13/16] Package version up to 1.8.9 Change-Id: I68bc650bfe937a7e80c0ea73fa4b5a013cf020fd 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 0698e6f..fad9c16 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 8 -%define TPL_VERSION_PATCH 8 +%define TPL_VERSION_PATCH 9 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From 47717e62e7f81dfb292a7f2050dc618d25f0c78b Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Tue, 8 Jun 2021 18:35:18 +0900 Subject: [PATCH 14/16] Add magic check to confirm WL_EGL_TIZEN private. Change-Id: I0f3663c027c4c3e2d14843296b94d81345b3580e Signed-off-by: Joonbum Ko --- src/wayland-egl-tizen/wayland-egl-tizen-priv.h | 9 +++- src/wayland-egl-tizen/wayland-egl-tizen.c | 63 ++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h index caeb5b0..af307da 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen-priv.h +++ b/src/wayland-egl-tizen/wayland-egl-tizen-priv.h @@ -9,7 +9,12 @@ extern "C" { #include #include +#ifndef WL_EGL_TIZEN_MAGIC +#define WL_EGL_TIZEN_MAGIC 0xDEF00123 +#endif + struct tizen_private { + unsigned int magic; int rotation; int frontbuffer_mode; int transform; @@ -27,11 +32,13 @@ struct tizen_private { int (*merge_sync_fds)(void *, int, int); }; -static struct tizen_private* tizen_private_create() +static struct tizen_private* +tizen_private_create() { struct tizen_private *private = NULL; private = (struct tizen_private *)calloc(1, sizeof(struct tizen_private)); if (private) { + private->magic = WL_EGL_TIZEN_MAGIC; private->rotation = 0; private->frontbuffer_mode = 0; private->transform = 0; diff --git a/src/wayland-egl-tizen/wayland-egl-tizen.c b/src/wayland-egl-tizen/wayland-egl-tizen.c index 2fb876c..ff16603 100644 --- a/src/wayland-egl-tizen/wayland-egl-tizen.c +++ b/src/wayland-egl-tizen/wayland-egl-tizen.c @@ -21,6 +21,15 @@ #define WL_EGL_ERR(f, x...) LOGE(FONT_RED f FONT_DEFAULT, ##x) #define WL_EGL_WARN(f, x...) LOGW(FONT_YELLOW f FONT_DEFAULT, ##x) +static int +_wl_egl_tizen_magic_check(struct tizen_private *private) +{ + if (private->magic != WL_EGL_TIZEN_MAGIC) + return 0; + + return 1; +} + void wl_egl_window_tizen_set_rotation(struct wl_egl_window *egl_window, int rotation) @@ -41,6 +50,11 @@ wl_egl_window_tizen_set_rotation(struct wl_egl_window *egl_window, egl_window->driver_private = (void *)private; } else { private = (struct tizen_private *)egl_window->driver_private; + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return; + } } if (private->rotation == rotation) { @@ -76,6 +90,11 @@ wl_egl_window_tizen_get_capabilities(struct wl_egl_window *egl_window) egl_window->driver_private = (void *)private; } else { private = (struct tizen_private *)egl_window->driver_private; + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return -1; + } } if (private->get_rotation_capability) @@ -106,6 +125,11 @@ wl_egl_window_tizen_set_buffer_transform(struct wl_egl_window *egl_window, egl_window->driver_private = (void *)private; } else { private = (struct tizen_private *)egl_window->driver_private; + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return; + } } if (private->transform == wl_output_transform) { @@ -137,6 +161,11 @@ wl_egl_window_tizen_set_frontbuffer_mode(struct wl_egl_window *egl_window, egl_window->driver_private = (void *)private; } else { private = (struct tizen_private *)egl_window->driver_private; + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return; + } } private->frontbuffer_mode = set; @@ -166,6 +195,11 @@ wl_egl_window_tizen_set_window_transform(struct wl_egl_window *egl_window, egl_window->driver_private = (void *)private; } else { private = (struct tizen_private *)egl_window->driver_private; + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return; + } } if (private->window_transform == window_transform) { @@ -196,6 +230,11 @@ wl_egl_window_tizen_get_window_serial(struct wl_egl_window *egl_window) egl_window->driver_private = (void *)private; } else { private = (struct tizen_private *)egl_window->driver_private; + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return 0; + } } return private->serial; @@ -217,6 +256,12 @@ wl_egl_window_tizen_set_window_serial(struct wl_egl_window *egl_window, return; } + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return; + } + if (private->set_window_serial_callback) private->set_window_serial_callback(egl_window, egl_window->driver_private, serial); @@ -238,6 +283,12 @@ wl_egl_window_tizen_create_commit_sync_fd(struct wl_egl_window *egl_window) return -1; } + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return -1; + } + if (private->create_commit_sync_fd) return private->create_commit_sync_fd(egl_window, egl_window->driver_private); @@ -260,6 +311,12 @@ wl_egl_window_tizen_create_presentation_sync_fd(struct wl_egl_window *egl_window return -1; } + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return -1; + } + if (private->create_presentation_sync_fd) return private->create_presentation_sync_fd(egl_window, egl_window->driver_private); @@ -283,6 +340,12 @@ wl_egl_window_tizen_merge_sync_fds(struct wl_egl_window *egl_window, return -1; } + if (!_wl_egl_tizen_magic_check(private)) { + WL_EGL_WARN("driver_private of wl_egl_window(%p) is not tizen_private", + egl_window); + return -1; + } + if (private->merge_sync_fds) return private->merge_sync_fds(egl_window->driver_private, sync_fd1, sync_fd2); -- 2.7.4 From 25a167d511b9f02e8ae2e7462f7f631ae3393b14 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 9 Jun 2021 12:20:44 +0900 Subject: [PATCH 15/16] Resolve build warning related to backend init functions. Change-Id: I08419d24c1411051029d4db6406682be0628db15 Signed-off-by: Joonbum Ko --- src/tpl.c | 2 +- src/tpl_internal.h | 3 ++- src/tpl_wl_egl_thread.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/tpl.c b/src/tpl.c index 5482bc1..1f2bd4e 100644 --- a/src/tpl.c +++ b/src/tpl.c @@ -274,7 +274,7 @@ __tpl_display_choose_backend(tpl_handle_t native_dpy) if (__tpl_display_choose_backend_tbm(native_dpy) == TPL_TRUE) return TPL_BACKEND_TBM; if (wl_egl_thread) { - if (__tpl_display_choose_backend_wl_egl_thread2(native_dpy)) + if (__tpl_display_choose_backend_wl_egl_thread(native_dpy)) return TPL_BACKEND_WAYLAND_THREAD; } else { if (__tpl_display_choose_backend_wayland_egl(native_dpy)) diff --git a/src/tpl_internal.h b/src/tpl_internal.h index 97a07ef..0fa3988 100755 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -219,7 +219,8 @@ tpl_backend_type_t __tpl_display_choose_backend(tpl_handle_t native_dpy); tpl_bool_t __tpl_display_choose_backend_tbm(tpl_handle_t native_dpy); tpl_bool_t __tpl_display_choose_backend_wayland_egl(tpl_handle_t native_dpy); tpl_bool_t __tpl_display_choose_backend_wl_egl_thread(tpl_handle_t native_dpy); -tpl_bool_t __tpl_display_choose_backend_wayland_vk_wsi(tpl_handle_t native_dpy); +tpl_bool_t __tpl_display_choose_backend_wayland_vk_wsi_thread(tpl_handle_t native_dpy); +//tpl_bool_t __tpl_display_choose_backend_wayland_vk_wsi(tpl_handle_t native_dpy); //tpl_bool_t __tpl_display_choose_backend_x11_dri2(tpl_handle_t native_dpy); //unused //tpl_bool_t __tpl_display_choose_backend_x11_dri3(tpl_handle_t native_dpy); //unused void __tpl_display_init_backend(tpl_display_t *display, diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index 7813981..32d5f22 100755 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -1053,7 +1053,7 @@ __tpl_wl_egl_display_get_buffer_from_native_pixmap(tpl_handle_t pixmap) } tpl_bool_t -__tpl_display_choose_backend_wl_egl_thread2(tpl_handle_t native_dpy) +__tpl_display_choose_backend_wl_egl_thread(tpl_handle_t native_dpy) { struct wl_interface *wl_egl_native_dpy = *(void **) native_dpy; -- 2.7.4 From 72ff58eedf23fdacd5676da22b6aa9baf3a06e47 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 10 Jun 2021 14:36:02 +0900 Subject: [PATCH 16/16] Fix incorrect use of can_dequeue return value. Change-Id: Iac9ca1b9cd0a8d4749f10ee4dfd97f45a7f1a39a Signed-off-by: Joonbum Ko --- src/tpl_wl_vk_thread.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 12ecfca..f883334 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -1933,8 +1933,7 @@ __tpl_wl_vk_surface_dequeue_buffer(tpl_surface_t *surface, tsq_err = tbm_surface_queue_can_dequeue_wait_timeout( swapchain->tbm_queue, timeout_ns/1000); } else { - tsq_err = tbm_surface_queue_can_dequeue( - swapchain->tbm_queue, 1); + tbm_surface_queue_can_dequeue(swapchain->tbm_queue, 1); } TRACE_END(); TPL_OBJECT_LOCK(surface); -- 2.7.4