From f1ff0db5be8282566901f70fbbfd979300105eb4 Mon Sep 17 00:00:00 2001 From: Hoyub Lee Date: Wed, 3 Jan 2018 22:39:41 +0900 Subject: [PATCH 01/16] tc: Add test cases for tpl_surface Add below tests for tpl_surface. TEST CASE | TEST ------------------------------------------------------------------ DEFAULT_tpl_surface_get_rotation | success_1 DEFAULT_tpl_surface_get_rotation | success_2 DEFAULT_tpl_surface_get_rotation | failure DEFAULT_tpl_surface_dequeue_enqueue | deq_enq_dmg_1 DEFAULT_tpl_surface_dequeue_enqueue | deq_enq_dmg_2 DEFAULT_tpl_surface_cancel_dequeued_buff | success DEFAULT_tpl_surface_cancel_dequeued_buff | failure_null_surface DEFAULT_tpl_surface_cancel_dequeued_buff | failure_null_tbm_surf EXTRA_tpl_surface_get_swapchain_buffers | failure_invalid_surface EXTRA_tpl_surface_get_swapchain_buffers | failure_invalid_buffer_count EXTRA_tpl_surface_destroy_swapchain | failure_invalid_surface DEFAULT_tpl_surface_set_frontbuffer_mode | success_activate DEFAULT_tpl_surface_set_frontbuffer_mode | success_deactivate DEFAULT_tpl_surface_set_frontbuffer_mode | failure_null_surface DEFAULT_tpl_surface_set_reset_cb | success DEFAULT_tpl_surface_set_reset_cb | failure DEFAULT_tpl_surface_set_rotation_capabil | success DEFAULT_tpl_surface_set_rotation_capabil | failure Change-Id: I324a2d02aa823712c64c5643d7cb77dd3c17bc0f Signed-off-by: Hoyub Lee --- tc/test/tpl-test_surface_test.cpp | 250 +++++++++++++++++++++++++++++++++++--- 1 file changed, 233 insertions(+), 17 deletions(-) diff --git a/tc/test/tpl-test_surface_test.cpp b/tc/test/tpl-test_surface_test.cpp index ae52edb..d419bae 100644 --- a/tc/test/tpl-test_surface_test.cpp +++ b/tc/test/tpl-test_surface_test.cpp @@ -9,23 +9,6 @@ #include "src/tpl-test_base.h" -typedef TPLTestBase DEFAULT_tpl_surface_validate; - -TEST_F(DEFAULT_tpl_surface_validate, success) -{ - tpl_bool_t result = tpl_surface_validate(backend->tpl_surface); - - ASSERT_EQ(TPL_TRUE, result); -} - -TEST_F(DEFAULT_tpl_surface_validate, failure_invalid_surface) -{ - tpl_bool_t result = tpl_surface_validate(NULL); - - ASSERT_EQ(TPL_FALSE, result); -} - - typedef TPLTestBase DEFAULT_tpl_surface_get_display; TEST_F(DEFAULT_tpl_surface_get_display, success) @@ -107,6 +90,51 @@ TEST_F(DEFAULT_tpl_surface_get_size, failure_invalid_surface) } +typedef TPLTestBase DEFAULT_tpl_surface_get_rotation; + +TEST_F(DEFAULT_tpl_surface_get_rotation, success_1) +{ + tpl_bool_t result; + int rotation; + + result = tpl_surface_get_rotation(backend->tpl_surface, &rotation); + ASSERT_EQ(TPL_ERROR_NONE, result); +} + +TEST_F(DEFAULT_tpl_surface_get_rotation, success_2) +{ + tpl_bool_t result; + + result = tpl_surface_get_rotation(backend->tpl_surface, NULL); + ASSERT_EQ(TPL_ERROR_NONE, result); +} + +TEST_F(DEFAULT_tpl_surface_get_rotation, failure) +{ + tpl_bool_t result; + int rotation; + + result = tpl_surface_get_rotation(NULL, &rotation); + ASSERT_EQ(TPL_ERROR_INVALID_PARAMETER, result); +} + +typedef TPLTestBase DEFAULT_tpl_surface_validate; + +TEST_F(DEFAULT_tpl_surface_validate, success) +{ + tpl_bool_t result = tpl_surface_validate(backend->tpl_surface); + + ASSERT_EQ(TPL_TRUE, result); +} + +TEST_F(DEFAULT_tpl_surface_validate, failure_invalid_surface) +{ + tpl_bool_t result = tpl_surface_validate(NULL); + + ASSERT_EQ(TPL_FALSE, result); +} + + typedef TPLTestBase DEFAULT_tpl_surface_dequeue_enqueue; // Tests simple normal buffer flow: @@ -132,6 +160,93 @@ TEST_F(DEFAULT_tpl_surface_dequeue_enqueue, deq_enq) ASSERT_EQ(TPL_ERROR_NONE, result); } +// Same with 'deq_enq' test but use tpl_surface_enqueue_buffer_with_damage +TEST_F(DEFAULT_tpl_surface_dequeue_enqueue, deq_enq_dmg_1) +{ + // dequeue + tbm_surface_h tbm_surf = NULL; + tbm_surf = tpl_surface_dequeue_buffer(backend->tpl_surface); + ASSERT_NE((void *)NULL, tbm_surf); + + // set and get interval + int interval_set = 2; + tpl_surface_set_post_interval(backend->tpl_surface, interval_set); + int interval_get = tpl_surface_get_post_interval(backend->tpl_surface); + ASSERT_EQ(interval_set, interval_get); + + // enqueue + tpl_result_t result = TPL_ERROR_INVALID_PARAMETER; + result = tpl_surface_enqueue_buffer_with_damage(backend->tpl_surface, + tbm_surf, 0, NULL); + ASSERT_EQ(TPL_ERROR_NONE, result); +} + +TEST_F(DEFAULT_tpl_surface_dequeue_enqueue, deq_enq_dmg_2) +{ + // dequeue + tbm_surface_h tbm_surf = NULL; + tbm_surf = tpl_surface_dequeue_buffer(backend->tpl_surface); + ASSERT_NE((void *)NULL, tbm_surf); + + // set and get interval + int interval_set = 2; + tpl_surface_set_post_interval(backend->tpl_surface, interval_set); + int interval_get = tpl_surface_get_post_interval(backend->tpl_surface); + ASSERT_EQ(interval_set, interval_get); + + // enqueue + tpl_result_t result = TPL_ERROR_INVALID_PARAMETER; + int rects[4 * 2] = {0, 0, 10, 10, + 1, 1, 10, 10}; + result = tpl_surface_enqueue_buffer_with_damage(backend->tpl_surface, + tbm_surf, 2, rects); + ASSERT_EQ(TPL_ERROR_NONE, result); +} + +typedef TPLTestBase DEFAULT_tpl_surface_cancel_dequeued_buffer; + +TEST_F(DEFAULT_tpl_surface_cancel_dequeued_buffer, success) +{ + tpl_bool_t result; + tbm_surface_h tbm_surf; + + // dequeue + tbm_surf = tpl_surface_dequeue_buffer(backend->tpl_surface); + ASSERT_NE((void *)NULL, tbm_surf); + + // cancel dequeued buffer + result = tpl_surface_cancel_dequeued_buffer(backend->tpl_surface, tbm_surf); + ASSERT_EQ(TPL_ERROR_NONE, result); +} + +TEST_F(DEFAULT_tpl_surface_cancel_dequeued_buffer, failure_null_surface) +{ + tpl_bool_t result; + tbm_surface_h tbm_surf; + + // dequeue + tbm_surf = tpl_surface_dequeue_buffer(backend->tpl_surface); + ASSERT_NE((void *)NULL, tbm_surf); + + // cancel dequeued buffer + result = tpl_surface_cancel_dequeued_buffer(NULL, tbm_surf); + ASSERT_EQ(TPL_ERROR_INVALID_PARAMETER, result); +} + +TEST_F(DEFAULT_tpl_surface_cancel_dequeued_buffer, failure_null_tbm_surf) +{ + tpl_bool_t result; + tbm_surface_h tbm_surf; + + // dequeue + tbm_surf = tpl_surface_dequeue_buffer(backend->tpl_surface); + ASSERT_NE((void *)NULL, tbm_surf); + + // cancel dequeued buffer + result = tpl_surface_cancel_dequeued_buffer(NULL, NULL); + ASSERT_EQ(TPL_ERROR_INVALID_PARAMETER, result); +} + typedef TPLTestBase EXTRA_tpl_surface_swapchain; @@ -170,3 +285,104 @@ TEST_F(EXTRA_tpl_surface_swapchain, success) ASSERT_EQ(TPL_ERROR_NONE, result); } + +typedef TPLTestBase EXTRA_tpl_surface_get_swapchain_buffers; + +TEST_F(EXTRA_tpl_surface_get_swapchain_buffers, failure_invalid_surface) +{ + tpl_result_t result; + tbm_surface_h **buffers = NULL; + int buffer_get; + + // Get swapchain buffers + result = tpl_surface_get_swapchain_buffers(NULL, buffers, &buffer_get); + ASSERT_EQ(TPL_ERROR_INVALID_PARAMETER, result); +} + +TEST_F(EXTRA_tpl_surface_get_swapchain_buffers, failure_invalid_buffer_count) +{ + tpl_result_t result; + tbm_surface_h **buffers = NULL; + int buffer_get; + + // Get swapchain buffers + result = tpl_surface_get_swapchain_buffers(backend->tpl_surface, buffers, + NULL); + ASSERT_EQ(TPL_ERROR_INVALID_PARAMETER, result); +} + + +typedef TPLTestBase EXTRA_tpl_surface_destroy_swapchain; + +TEST_F(EXTRA_tpl_surface_destroy_swapchain, failure_invalid_surface) +{ + tpl_result_t result; + + // Destroy swapchain buffers + result = tpl_surface_destroy_swapchain(NULL); + ASSERT_EQ(TPL_ERROR_INVALID_PARAMETER, result); +} + + +typedef TPLTestBase DEFAULT_tpl_surface_set_frontbuffer_mode; + +TEST_F(DEFAULT_tpl_surface_set_frontbuffer_mode, success_activate) +{ + tpl_result_t result; + + result = tpl_surface_set_frontbuffer_mode(backend->tpl_surface, TPL_TRUE); + ASSERT_EQ(TPL_ERROR_NONE, result); +} + +TEST_F(DEFAULT_tpl_surface_set_frontbuffer_mode, success_deactivate) +{ + tpl_result_t result; + + result = tpl_surface_set_frontbuffer_mode(backend->tpl_surface, TPL_FALSE); + ASSERT_EQ(TPL_ERROR_NONE, result); +} + +TEST_F(DEFAULT_tpl_surface_set_frontbuffer_mode, failure_null_surface) +{ + tpl_result_t result; + + result = tpl_surface_set_frontbuffer_mode(NULL, TPL_FALSE); + ASSERT_EQ(TPL_ERROR_INVALID_PARAMETER, result); +} + +typedef TPLTestBase DEFAULT_tpl_surface_set_reset_cb; + +TEST_F(DEFAULT_tpl_surface_set_reset_cb, success) +{ + tpl_result_t result; + + result = tpl_surface_set_reset_cb(backend->tpl_surface, NULL, NULL); + ASSERT_EQ(TPL_ERROR_NONE, result); +} + +TEST_F(DEFAULT_tpl_surface_set_reset_cb, failure) +{ + tpl_result_t result; + + result = tpl_surface_set_reset_cb(NULL, NULL, NULL); + ASSERT_EQ(TPL_ERROR_INVALID_PARAMETER, result); +} + + +typedef TPLTestBase DEFAULT_tpl_surface_set_rotation_capability; + +TEST_F(DEFAULT_tpl_surface_set_rotation_capability, success) +{ + tpl_result_t result; + + result = tpl_surface_set_rotation_capability(backend->tpl_surface, TPL_TRUE); + ASSERT_EQ(TPL_ERROR_NONE, result); +} + +TEST_F(DEFAULT_tpl_surface_set_rotation_capability, failure) +{ + tpl_result_t result; + + result = tpl_surface_set_rotation_capability(NULL, TPL_TRUE); + ASSERT_EQ(TPL_ERROR_INVALID_PARAMETER, result); +} -- 2.7.4 From 750b2fe32de4438d3eb8e2ce1ee9a968a511c4f7 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 18 Jan 2018 15:26:43 +0900 Subject: [PATCH 02/16] tpl_wayland_egl: Guaranteed thread safety for wl_event processing. Change-Id: I519c78d1f19303c8d99b1d72cbcb1522d4861f71 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 59 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index ab534a7..ef08f8b 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -35,6 +35,7 @@ struct _tpl_wayland_egl_display { struct wl_display *wl_dpy; struct wl_event_queue *wl_tbm_event_queue; struct tizen_surface_shm *tizen_surface_shm; /* used for surface buffer_flush */ + pthread_mutex_t wl_event_mutex; }; struct _tpl_wayland_egl_surface { @@ -193,6 +194,11 @@ __tpl_wayland_egl_display_init(tpl_display_t *display) wayland_egl_display->tdm_client = NULL; } + if (pthread_mutex_init(&wayland_egl_display->wl_event_mutex, NULL)) { + TPL_ERR("Failed to initialize wl_event_mutex."); + goto free_wl_display; + } + wayland_egl_display->wl_dpy = wl_dpy; __tpl_wayland_egl_display_buffer_flusher_init(wayland_egl_display); @@ -235,9 +241,12 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) wayland_egl_display = (tpl_wayland_egl_display_t *)display->backend.data; if (wayland_egl_display) { + int lock_res = 0; TPL_LOG_B("WL_EGL", "[FINI] tpl_wayland_egl_display_t(%p) wl_tbm_client(%p)", wayland_egl_display, wayland_egl_display->wl_tbm_client); + lock_res = pthread_mutex_lock(&wayland_egl_display->wl_event_mutex); + __tpl_wayland_egl_display_buffer_flusher_fini(wayland_egl_display); if (wayland_egl_display->tdm_client) @@ -252,6 +261,11 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) if (wayland_egl_display->wl_tbm_client) wayland_tbm_client_deinit(wayland_egl_display->wl_tbm_client); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); + if (pthread_mutex_destroy(&wayland_egl_display->wl_event_mutex)) + TPL_ERR("Failed to destroy wl_event_mutex(%p)", + &wayland_egl_display->wl_event_mutex); + wayland_egl_display->wl_tbm_event_queue = NULL; wayland_egl_display->wl_tbm_client = NULL; wayland_egl_display->tdm_client = NULL; @@ -624,15 +638,14 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) if (surface->type == TPL_SURFACE_TYPE_WINDOW) { struct wl_egl_window *wl_egl_window = (struct wl_egl_window *) surface->native_handle; + int lock_res = 0; TPL_ASSERT(wl_egl_window); /* TPL_ASSERT(wl_egl_window->surface); */ /* to be enabled once evas/gl patch is in place */ wl_egl_window->private = NULL; - wl_display_flush(wayland_egl_display->wl_dpy); - wl_display_dispatch_queue_pending(wayland_egl_display->wl_dpy, - wayland_egl_display->wl_tbm_event_queue); + __tpl_wayland_egl_surface_buffer_flusher_fini(surface); if (wayland_egl_surface->tdm_vblank) { TPL_LOG_B("WL_EGL", @@ -641,13 +654,18 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) tdm_client_vblank_destroy(wayland_egl_surface->tdm_vblank); } + wl_display_flush(wayland_egl_display->wl_dpy); + + lock_res = pthread_mutex_lock(&wayland_egl_display->wl_event_mutex); + wl_display_dispatch_queue_pending(wayland_egl_display->wl_dpy, + wayland_egl_display->wl_tbm_event_queue); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); + TPL_LOG_B("WL_EGL", "[FINI] tpl_wayland_egl_surface_t(%p) wl_egl_window(%p) tbm_queue(%p)", wayland_egl_surface, wl_egl_window, wayland_egl_surface->tbm_queue); tbm_surface_queue_destroy(wayland_egl_surface->tbm_queue); wayland_egl_surface->tbm_queue = NULL; - - __tpl_wayland_egl_surface_buffer_flusher_fini(surface); } /* When surface is destroyed, unreference tbm_surface which tracked by @@ -1008,8 +1026,9 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) wl_display_dispatch_queue_pending(wayland_egl_display->wl_dpy, wayland_egl_display->wl_tbm_event_queue); - if (tbm_surface_queue_can_dequeue(wayland_egl_surface->tbm_queue, 0)) + if (tbm_surface_queue_can_dequeue(wayland_egl_surface->tbm_queue, 0)) { return TPL_ERROR_NONE; + } TRACE_BEGIN("WAITING FOR DEQUEUEABLE"); TPL_OBJECT_UNLOCK(surface); @@ -1047,9 +1066,13 @@ __tpl_wayland_egl_surface_wait_dequeuable(tpl_surface_t *surface) } ret = TPL_ERROR_INVALID_OPERATION; - break; + TPL_OBJECT_LOCK(surface); + TRACE_END(); + + return ret; } } + TPL_OBJECT_LOCK(surface); TRACE_END(); @@ -1112,10 +1135,13 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou (struct wl_egl_window *)surface->native_handle; tbm_surface_queue_error_e tsq_err = 0; int is_activated = 0; + int lock_res = 0; if (sync_fence) *sync_fence = -1; + lock_res = pthread_mutex_lock(&wayland_egl_display->wl_event_mutex); + /* Check whether the surface was resized by wayland_egl */ if (wayland_egl_surface->resized == TPL_TRUE) { int width, height, format; @@ -1133,6 +1159,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou if (__tpl_wayland_egl_surface_wait_dequeuable(surface)) { TPL_ERR("Failed to wait dequeueable buffer"); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return NULL; } @@ -1169,6 +1196,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou TRACE_ASYNC_BEGIN((int)wayland_egl_buffer, "[DEQ]~[ENQ] BO_NAME:%d", tbm_bo_export(wayland_egl_buffer->bo)); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return surface->frontbuffer; } else surface->frontbuffer = NULL; @@ -1181,6 +1209,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou if (!tbm_surface) { TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d", tsq_err); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return NULL; } @@ -1242,6 +1271,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou wayland_egl_buffer->transform, wayland_egl_buffer->rotated ? "[TRUE]" : "[FALSE]"); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return tbm_surface; } @@ -1250,6 +1280,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou if (!wayland_egl_buffer) { TPL_ERR("Mem alloc for wayland_egl_buffer failed!"); tbm_surface_internal_unref(tbm_surface); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return NULL; } @@ -1260,6 +1291,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou TPL_ERR("Failed to create TBM client buffer!"); tbm_surface_internal_unref(tbm_surface); free(wayland_egl_buffer); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return NULL; } @@ -1328,6 +1360,7 @@ __tpl_wayland_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeou TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); } + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return tbm_surface; } @@ -1631,6 +1664,7 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, tpl_wayland_egl_surface_t *wayland_egl_surface; tpl_wayland_egl_display_t *wayland_egl_display; int ret; + int lock_res = 0; TPL_CHECK_ON_NULL_RETURN(surface); wayland_egl_surface = surface->backend.data; @@ -1643,6 +1677,8 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, TPL_CHECK_ON_NULL_RETURN(wayland_egl_display->wl_tbm_event_queue); TPL_CHECK_ON_NULL_RETURN(wayland_egl_surface->tbm_queue); + lock_res = pthread_mutex_lock(&wayland_egl_display->wl_event_mutex); + TPL_LOG_B("WL_EGL", "[FLUSH_CB] tpl_wayland_egl_surface_t(%p)", wayland_egl_surface); @@ -1655,6 +1691,7 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, if (ret == -1) { TPL_ERR("Failed to wl_display_dispatch_queue_pending ret:%d, err:%d", ret, errno); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return; } @@ -1676,6 +1713,8 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, } TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); } + + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); } static void __cb_tizen_surface_shm_flusher_free_flush_callback(void *data, @@ -1685,6 +1724,7 @@ static void __cb_tizen_surface_shm_flusher_free_flush_callback(void *data, tpl_wayland_egl_surface_t *wayland_egl_surface; tpl_wayland_egl_display_t *wayland_egl_display; int ret; + int lock_res; TPL_CHECK_ON_NULL_RETURN(surface); wayland_egl_surface = surface->backend.data; @@ -1697,6 +1737,8 @@ static void __cb_tizen_surface_shm_flusher_free_flush_callback(void *data, TPL_CHECK_ON_NULL_RETURN(wayland_egl_display->wl_tbm_event_queue); TPL_CHECK_ON_NULL_RETURN(wayland_egl_surface->tbm_queue); + lock_res = pthread_mutex_lock(&wayland_egl_display->wl_event_mutex); + TPL_LOG_B("WL_EGL", "[FLUSH_CB] tpl_wayland_egl_surface_t(%p)", wayland_egl_surface); @@ -1709,10 +1751,13 @@ static void __cb_tizen_surface_shm_flusher_free_flush_callback(void *data, if (ret == -1) { TPL_ERR("Failed to wl_display_dispatch_queue_pending ret:%d, err:%d", ret, errno); + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); return; } tbm_surface_queue_free_flush(wayland_egl_surface->tbm_queue); + + if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); } static const struct tizen_surface_shm_flusher_listener -- 2.7.4 From 743f8fc4a0a948e110e2daa68def281b2ee52112 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 19 Jan 2018 13:13:36 +0900 Subject: [PATCH 03/16] tpl_wayland_egl_thread: Changed to use wl_tbm event queue to use flusher in thread. Change-Id: I2e15a77caa1356b51532a66b9f75d6df44ddb2e8 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 70 +++++++------------------------------------- 1 file changed, 10 insertions(+), 60 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 965e5fd..48e37db 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -822,10 +822,10 @@ _twe_display_shm_init(twe_wl_disp_source *disp_source) goto fini; } - /* set tizen_surface_shm's queue as client's default queue */ + /* set tizen_surface_shm's queue as client's private queue */ if (disp_source->tss) wl_proxy_set_queue((struct wl_proxy *)disp_source->tss, - NULL); + disp_source->ev_queue); TPL_LOG_T(BACKEND, "tizen_surface_shm(%p) init.", disp_source->tss); @@ -1196,80 +1196,30 @@ static void __cb_tss_flusher_flush_callback(void *data, struct tizen_surface_shm_flusher *tss_flusher) { twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data; - twe_wl_disp_source *disp_source = surf_source->disp_source; - int ret; + tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; TPL_LOG_T(BACKEND, "[FLUSH_CB] surf_source(%p)", surf_source); - /*First distach pending queue for TPL - - dispatch buffer-release - - dispatch queue flush - */ - TPL_OBJECT_LOCK(&disp_source->obj); - ret = wl_display_dispatch_queue_pending(disp_source->disp, - disp_source->ev_queue); - if (ret == -1) { - _twe_display_print_err(disp_source, "dispatch_queue_pending"); - TPL_OBJECT_UNLOCK(&disp_source->obj); + tsq_err = tbm_surface_queue_flush(surf_source->tbm_queue); + if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to free flush tbm_queue(%p)", surf_source->tbm_queue); return; } - - tbm_surface_queue_flush(surf_source->tbm_queue); - - /* Only when client call tpl_surface_dequeue_buffer(), client can do - * unreference tbm_surface although there are release events in the event queue. - * After tbm_surface_queue_flush, queue has no tbm_surface, client can do - * unreference committed buffers using the list of committed_buffers. - * Then, client does not need to wait for release_callback to unreference - * committed buffers. - */ - if (surf_source->committed_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); - while (!__tpl_list_is_empty(surf_source->committed_buffers)) { - tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; - tbm_surface_h tbm_surface = - __tpl_list_pop_front(surf_source->committed_buffers, - (tpl_free_func_t)__cb_buffer_remove_from_list); - - TRACE_ASYNC_END((int)tbm_surface, "[COMMIT ~ RELEASE] BO(%d)", - tbm_bo_export(tbm_surface_internal_get_bo( - tbm_surface, 0))); - tsq_err = tbm_surface_queue_release(surf_source->tbm_queue, tbm_surface); - if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) - TPL_ERR("Failed to release. tbm_surface(%p) tsq_err(%d)", - tbm_surface, tsq_err); - } - TPL_OBJECT_UNLOCK(&surf_source->obj); - } - - TPL_OBJECT_UNLOCK(&disp_source->obj); } static void __cb_tss_flusher_free_flush_callback(void *data, struct tizen_surface_shm_flusher *tss_flusher) { twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data; - twe_wl_disp_source *disp_source = surf_source->disp_source; - int ret; + tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; TPL_LOG_T(BACKEND, "[FREE_FLUSH_CB] surf_source(%p)", surf_source); - /* First distach panding queue for TPL - - dispatch buffer-release - - dispatch queue flush - */ - TPL_OBJECT_LOCK(&disp_source->obj); - ret = wl_display_dispatch_queue_pending(disp_source->disp, - disp_source->ev_queue); - if (ret == -1) { - _twe_display_print_err(disp_source, "dispatch_queue_pending"); - TPL_OBJECT_UNLOCK(&disp_source->obj); + tsq_err = tbm_surface_queue_free_flush(surf_source->tbm_queue); + if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to free flush tbm_queue(%p)", surf_source->tbm_queue); return; } - - tbm_surface_queue_free_flush(surf_source->tbm_queue); - - TPL_OBJECT_UNLOCK(&disp_source->obj); } -- 2.7.4 From 90dca121b44c2784111bf30d31cdef71e4bf758d Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 22 Jan 2018 17:47:02 +0900 Subject: [PATCH 04/16] tpl_wayland_egl_thread: Modified to create timeline fd only for vulkan dpy. Change-Id: I40f7f28ce0663d04e93afa97fc3eaf5fd2448ad7 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 48e37db..4b0a3c7 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1452,13 +1452,6 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info->rotated = TPL_FALSE; } - buf_info->sync_timeline = tbm_sync_timeline_create(); - if (buf_info->sync_timeline == -1) { - char buf[1024]; - strerror_r(errno, buf, sizeof(buf)); - TPL_WARN("Failed to create TBM sync timeline: %d(%s)", errno, buf); - } - buf_info->sync_timestamp = 0; buf_info->surf_source = surf_source; buf_info->num_rects = 0; @@ -1468,12 +1461,21 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, 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; - if (buf_info->is_vk_image) + if (buf_info->is_vk_image) { + buf_info->sync_timeline = tbm_sync_timeline_create(); + if (buf_info->sync_timeline == -1) { + char buf[1024]; + strerror_r(errno, buf, sizeof(buf)); + TPL_WARN("Failed to create TBM sync timeline: %d(%s)", errno, buf); + } + wayland_tbm_client_set_sync_timeline(surf_source->disp_source->wl_tbm_client, (void *)buf_info->wl_buffer, buf_info->sync_timeline); + } wl_buffer_add_listener((void *)buf_info->wl_buffer, &wl_buffer_release_listener, tbm_surface); -- 2.7.4 From 5d8bf5e3fc1e7c395ef0f6fa28b59d9d2992091c Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 22 Jan 2018 19:34:23 +0900 Subject: [PATCH 05/16] tpl_wayland_egl_thread: Modified wrong return type. Change-Id: Icda1450b993785e41bba9b88305bc7770132be28 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 2 +- src/tpl_wayland_egl_thread.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 4b0a3c7..d48e619 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -3047,7 +3047,7 @@ twe_surface_wait_dequeueable(twe_surface_h twe_surface, uint64_t timeout_ns) } -tpl_result_t +tpl_bool_t twe_check_native_handle_is_wl_display(tpl_handle_t display) { struct wl_interface *wl_egl_native_dpy = *(void **) display; diff --git a/src/tpl_wayland_egl_thread.h b/src/tpl_wayland_egl_thread.h index ad44dd0..e89d527 100644 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -93,7 +93,7 @@ twe_surface_create_sync_fd(tbm_surface_h tbm_surface); tpl_result_t twe_surface_wait_dequeueable(twe_surface_h twe_surface, uint64_t timeout_ns); -tpl_result_t +tpl_bool_t twe_check_native_handle_is_wl_display(tpl_handle_t display); tpl_result_t -- 2.7.4 From 425b7d435a0a242e93c375cc67e136a0943adc70 Mon Sep 17 00:00:00 2001 From: "JunSeok, Kim" Date: Thu, 11 Jan 2018 19:39:50 +0900 Subject: [PATCH 06/16] tizen-surface: renew tizen-surface protocol path Change-Id: I1453b28a64cbc5942c56acf381faf0be05d48e97 --- configure.ac | 2 +- packaging/libtpl-egl.spec | 1 + src/Makefile.am | 1 - src/protocol/tizen-surface-client.h | 118 ---------------------------------- src/protocol/tizen-surface-protocol.c | 37 ----------- src/protocol/tizen-surface.xml | 16 ----- src/tpl_wayland_egl.c | 2 +- src/tpl_wayland_egl_thread.c | 2 +- worker_test/Makefile | 2 - 9 files changed, 4 insertions(+), 177 deletions(-) delete mode 100644 src/protocol/tizen-surface-client.h delete mode 100644 src/protocol/tizen-surface-protocol.c delete mode 100644 src/protocol/tizen-surface.xml diff --git a/configure.ac b/configure.ac index 8a6985c..5379baa 100644 --- a/configure.ac +++ b/configure.ac @@ -58,7 +58,7 @@ AC_ARG_WITH([wayland], [with_wayland=yes]) AS_IF([test "${with_wayland}" = "yes" || test "${with_wayland}" = "1"], - [PKG_CHECK_MODULES([TPL_WL], [gbm libtdm-client wayland-tbm-client wayland-tbm-server glib-2.0]) + [PKG_CHECK_MODULES([TPL_WL], [gbm libtdm-client wayland-tbm-client wayland-tbm-server tizen-surface-client glib-2.0]) TPL_CFLAGS+="$TPL_WL_CFLAGS" TPL_CFLAGS+=" -DTPL_WINSYS_WL=1 " TPL_LIBS+="$TPL_WL_LIBS"], diff --git a/packaging/libtpl-egl.spec b/packaging/libtpl-egl.spec index 0890369..9f1051a 100644 --- a/packaging/libtpl-egl.spec +++ b/packaging/libtpl-egl.spec @@ -76,6 +76,7 @@ BuildRequires: pkgconfig(gbm) BuildRequires: pkgconfig(libtdm-client) BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(wayland-tbm-server) +BuildRequires: pkgconfig(tizen-surface-client) BuildRequires: pkgconfig(glib-2.0) %endif diff --git a/src/Makefile.am b/src/Makefile.am index 8c4f651..bafc8fd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -26,7 +26,6 @@ libtpl_egl_la_SOURCES = tpl.c \ if WITH_WAYLAND libtpl_egl_la_SOURCES += tpl_wayland_egl.c \ tpl_gbm.c \ - protocol/tizen-surface-protocol.c \ tpl_wl_egl_thread.c \ tpl_wayland_egl_thread.c \ tpl_wayland_vk_wsi.c \ diff --git a/src/protocol/tizen-surface-client.h b/src/protocol/tizen-surface-client.h deleted file mode 100644 index 6eaa459..0000000 --- a/src/protocol/tizen-surface-client.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef TIZEN_SURFACE_CLIENT_PROTOCOL_H -#define TIZEN_SURFACE_CLIENT_PROTOCOL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include "wayland-client.h" - -struct wl_client; -struct wl_resource; - -struct tizen_surface_shm; -struct tizen_surface_shm_flusher; -struct wl_surface; - -extern const struct wl_interface tizen_surface_shm_interface; -extern const struct wl_interface tizen_surface_shm_flusher_interface; - -#define TIZEN_SURFACE_SHM_GET_FLUSHER 0 - -#define TIZEN_SURFACE_SHM_GET_FLUSHER_SINCE_VERSION 1 - -static inline void -tizen_surface_shm_set_user_data(struct tizen_surface_shm *tizen_surface_shm, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) tizen_surface_shm, user_data); -} - -static inline void * -tizen_surface_shm_get_user_data(struct tizen_surface_shm *tizen_surface_shm) -{ - return wl_proxy_get_user_data((struct wl_proxy *) tizen_surface_shm); -} - -static inline uint32_t -tizen_surface_shm_get_version(struct tizen_surface_shm *tizen_surface_shm) -{ - return wl_proxy_get_version((struct wl_proxy *) tizen_surface_shm); -} - -static inline void -tizen_surface_shm_destroy(struct tizen_surface_shm *tizen_surface_shm) -{ - wl_proxy_destroy((struct wl_proxy *) tizen_surface_shm); -} - -static inline struct tizen_surface_shm_flusher * -tizen_surface_shm_get_flusher(struct tizen_surface_shm *tizen_surface_shm, struct wl_surface *surface) -{ - struct wl_proxy *id; - - id = wl_proxy_marshal_constructor((struct wl_proxy *) tizen_surface_shm, - TIZEN_SURFACE_SHM_GET_FLUSHER, &tizen_surface_shm_flusher_interface, NULL, surface); - - return (struct tizen_surface_shm_flusher *) id; -} - -struct tizen_surface_shm_flusher_listener { - /** - * flush - (none) - */ - void (*flush)(void *data, - struct tizen_surface_shm_flusher *tizen_surface_shm_flusher); - /** - * free_flush - (none) - * @since: 2 - */ - void (*free_flush)(void *data, - struct tizen_surface_shm_flusher *tizen_surface_shm_flusher); -}; - -static inline int -tizen_surface_shm_flusher_add_listener(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher, - const struct tizen_surface_shm_flusher_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) tizen_surface_shm_flusher, - (void (**)(void)) listener, data); -} - -#define TIZEN_SURFACE_SHM_FLUSHER_DESTROY 0 - -#define TIZEN_SURFACE_SHM_FLUSHER_DESTROY_SINCE_VERSION 1 - -static inline void -tizen_surface_shm_flusher_set_user_data(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) tizen_surface_shm_flusher, user_data); -} - -static inline void * -tizen_surface_shm_flusher_get_user_data(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) -{ - return wl_proxy_get_user_data((struct wl_proxy *) tizen_surface_shm_flusher); -} - -static inline uint32_t -tizen_surface_shm_flusher_get_version(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) -{ - return wl_proxy_get_version((struct wl_proxy *) tizen_surface_shm_flusher); -} - -static inline void -tizen_surface_shm_flusher_destroy(struct tizen_surface_shm_flusher *tizen_surface_shm_flusher) -{ - wl_proxy_marshal((struct wl_proxy *) tizen_surface_shm_flusher, - TIZEN_SURFACE_SHM_FLUSHER_DESTROY); - - wl_proxy_destroy((struct wl_proxy *) tizen_surface_shm_flusher); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/protocol/tizen-surface-protocol.c b/src/protocol/tizen-surface-protocol.c deleted file mode 100644 index bd5e8a6..0000000 --- a/src/protocol/tizen-surface-protocol.c +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include "wayland-util.h" - -extern const struct wl_interface tizen_surface_shm_flusher_interface; -extern const struct wl_interface wl_surface_interface; - -static const struct wl_interface *types[] = { - &tizen_surface_shm_flusher_interface, - &wl_surface_interface, -}; - -static const struct wl_message tizen_surface_shm_requests[] = { - { "get_flusher", "no", types + 0 }, -}; - -WL_EXPORT const struct wl_interface tizen_surface_shm_interface = { - "tizen_surface_shm", 2, - 1, tizen_surface_shm_requests, - 0, NULL, -}; - -static const struct wl_message tizen_surface_shm_flusher_requests[] = { - { "destroy", "", types + 0 }, -}; - -static const struct wl_message tizen_surface_shm_flusher_events[] = { - { "flush", "", types + 0 }, - { "free_flush", "2", types + 0 }, -}; - -WL_EXPORT const struct wl_interface tizen_surface_shm_flusher_interface = { - "tizen_surface_shm_flusher", 2, - 1, tizen_surface_shm_flusher_requests, - 2, tizen_surface_shm_flusher_events, -}; - diff --git a/src/protocol/tizen-surface.xml b/src/protocol/tizen-surface.xml deleted file mode 100644 index ad516c0..0000000 --- a/src/protocol/tizen-surface.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index ef08f8b..503475c 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -19,7 +19,7 @@ #include #include #include -#include "protocol/tizen-surface-client.h" +#include /* In wayland, application and compositor create its own drawing buffers. Recommend size is more than 2. */ #define CLIENT_QUEUE_SIZE 3 diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index d48e619..8d0d640 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -8,12 +8,12 @@ #include #include #include +#include #include "tpl_utils.h" #include "tpl_internal.h" #include "wayland-egl/wayland-egl-priv.h" #include "tpl_wayland_egl_thread.h" -#include "protocol/tizen-surface-client.h" #include "wayland-vulkan/wayland-vulkan-client-protocol.h" #include "tpl_utils.h" diff --git a/worker_test/Makefile b/worker_test/Makefile index 6ce36ec..b6989e7 100644 --- a/worker_test/Makefile +++ b/worker_test/Makefile @@ -21,12 +21,10 @@ SRCS += ../src/tpl_utils_map.c SRCS += ../src/tpl_object.c SRCS += ../src/wayland-egl/wayland-egl.c SRCS += ../src/tpl_wayland_egl_thread.c -SRCS += ../src/protocol/tizen-surface-protocol.c HEADERS += ../src/tpl_wayland_egl_thread.h HEADERS += ../src/tpl_utils.h HEADERS += ../src/tpl_internal.h HEADERS += ../src/tpl.h -HEADERS += ../src/protocol/tizen-surface-client.h OBJS = $(SRCS:%.c=%.o) -- 2.7.4 From a816206cfc6e25f982ac0182e5d57cfb79d8f0ca Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 24 Jan 2018 15:11:56 +0900 Subject: [PATCH 07/16] Package version up to 1.5.3 Change-Id: Ie298e8f70a242eec37e645213bfa4e0a01d95b09 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 9f1051a..4b1e945 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 5 -%define TPL_VERSION_PATCH 2 +%define TPL_VERSION_PATCH 3 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From 2d8149fe316acabe82015d5310a721c4bacb046e Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 31 Jan 2018 13:36:28 +0900 Subject: [PATCH 08/16] tpl_wayland_egl: Added tdm_mutex to wayland_egl_display to guarantee thread safety. - RELATED COMMIT: Guaranteed thread safety for wl_event processing. - 750b2fe32de4438d3eb8e2ce1ee9a968a511c4f7 - Above commit can cover the wl_event processing only. - And in multi-surfaces or multi-threads situation, wayland_egl_display can be accessed at the same time in the processing of different surfaces. - The tdm_client in wayland_egl_display also dispatches wl_display internally, so thread_safety for tdm_client should be guaranteed. Change-Id: I30dbac42f90a003070c27a750d3a34354c4719ed Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 503475c..4565402 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -36,6 +36,7 @@ struct _tpl_wayland_egl_display { struct wl_event_queue *wl_tbm_event_queue; struct tizen_surface_shm *tizen_surface_shm; /* used for surface buffer_flush */ pthread_mutex_t wl_event_mutex; + pthread_mutex_t tdm_mutex; }; struct _tpl_wayland_egl_surface { @@ -199,6 +200,11 @@ __tpl_wayland_egl_display_init(tpl_display_t *display) goto free_wl_display; } + if (pthread_mutex_init(&wayland_egl_display->tdm_mutex, NULL)) { + TPL_ERR("Failed to initialize tdm_mutex."); + goto free_wl_display; + } + wayland_egl_display->wl_dpy = wl_dpy; __tpl_wayland_egl_display_buffer_flusher_init(wayland_egl_display); @@ -222,6 +228,9 @@ free_wl_display: if (wayland_egl_display->wl_tbm_client) wayland_tbm_client_deinit(wayland_egl_display->wl_tbm_client); + pthread_mutex_destroy(&wayland_egl_display->wl_event_mutex); + pthread_mutex_destroy(&wayland_egl_display->tdm_mutex); + wayland_egl_display->wl_tbm_event_queue = NULL; wayland_egl_display->wl_tbm_client = NULL; wayland_egl_display->tdm_client = NULL; @@ -242,6 +251,7 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) wayland_egl_display = (tpl_wayland_egl_display_t *)display->backend.data; if (wayland_egl_display) { int lock_res = 0; + int tdm_lock_res = 0; TPL_LOG_B("WL_EGL", "[FINI] tpl_wayland_egl_display_t(%p) wl_tbm_client(%p)", wayland_egl_display, wayland_egl_display->wl_tbm_client); @@ -249,8 +259,10 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) __tpl_wayland_egl_display_buffer_flusher_fini(wayland_egl_display); + tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); if (wayland_egl_display->tdm_client) tdm_client_destroy(wayland_egl_display->tdm_client); + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); if (wayland_egl_display->wl_tbm_client) wayland_tbm_client_set_event_queue(wayland_egl_display->wl_tbm_client, NULL); @@ -266,6 +278,10 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) TPL_ERR("Failed to destroy wl_event_mutex(%p)", &wayland_egl_display->wl_event_mutex); + if (pthread_mutex_destroy(&wayland_egl_display->tdm_mutex)) + TPL_ERR("Failed to destroy tdm_mutex(%p)", + &wayland_egl_display->tdm_mutex); + wayland_egl_display->wl_tbm_event_queue = NULL; wayland_egl_display->wl_tbm_client = NULL; wayland_egl_display->tdm_client = NULL; @@ -581,12 +597,15 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) /* tdm_vblank object decide to be maintained every tpl_wayland_egl_surface for the case where the several surfaces is created in one display connection. */ if (wayland_egl_display->tdm_client) { + int tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); if (TPL_ERROR_NONE != __tpl_wayland_egl_surface_create_vblank( wayland_egl_surface, wayland_egl_display->tdm_client)) { TPL_ERR("TBM surface create vblank failed!"); + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); goto create_vblank_fail; } + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); } __tpl_wayland_egl_surface_buffer_flusher_init(surface); @@ -648,10 +667,12 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) __tpl_wayland_egl_surface_buffer_flusher_fini(surface); if (wayland_egl_surface->tdm_vblank) { + int tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); TPL_LOG_B("WL_EGL", "[TDM_VBLANK_FINI] tpl_wayland_egl_surface_t(%p) tdm_vblank(%p)", wayland_egl_surface, wayland_egl_surface->tdm_vblank); tdm_client_vblank_destroy(wayland_egl_surface->tdm_vblank); + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); } wl_display_flush(wayland_egl_display->wl_dpy); @@ -705,17 +726,19 @@ __tpl_wayland_egl_surface_wait_vblank(tpl_surface_t *surface) (tpl_wayland_egl_display_t *)surface->display->backend.data; tpl_wayland_egl_surface_t *wayland_egl_surface = (tpl_wayland_egl_surface_t *)surface->backend.data; + int tdm_lock_res = 0; TPL_OBJECT_UNLOCK(surface); - do { + tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); + while (wayland_egl_surface->vblank_done == TPL_FALSE) { tdm_err = tdm_client_handle_events(wayland_egl_display->tdm_client); if (tdm_err != TDM_ERROR_NONE) { TPL_ERR("Failed to tdm_client_handle_events."); break; } - - } while (wayland_egl_surface->vblank_done == TPL_FALSE); + } + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); TPL_OBJECT_LOCK(surface); } @@ -834,6 +857,7 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, /* TPL_WAIT_VBLANK = 1 */ if (wayland_egl_display->tdm_client) { + int tdm_lock_res = pthread_mutex_lock(&wayland_egl_display->tdm_mutex); tdm_err = tdm_client_vblank_wait(wayland_egl_surface->tdm_vblank, 1, /* interval */ __cb_tdm_client_wait_vblank, /* handler */ @@ -843,6 +867,7 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, wayland_egl_surface->vblank_done = TPL_FALSE; else TPL_ERR("Failed to tdm_client_wait_vblank. error:%d", tdm_err); + if (tdm_lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->tdm_mutex); } TRACE_ASYNC_BEGIN((int)tbm_surface, "[COMMIT ~ RELEASE_CB] BO_NAME:%d", -- 2.7.4 From a5f11f5d46f72b4bd246aa53397edc46fdecd7c9 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 5 Jan 2018 14:57:05 +0900 Subject: [PATCH 09/16] tpl_wayland_egl_thread: Added useful trace logs for vulkan. Change-Id: Ie37f9075a72856747c6259a73e3af381aec10ba8 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 8d0d640..7704956 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1400,6 +1400,9 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, TPL_OBJECT_UNLOCK(&surf_source->obj); } + TRACE_MARK("[SET_BUFFER_INFO] BO(%d)", + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); + TPL_LOG_T(BACKEND, "[REUSE_BUF] buf_info(%p) tbm_surface(%p) bo(%d) (%dx%d) transform(%d)", buf_info, tbm_surface, @@ -1493,6 +1496,8 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, TPL_OBJECT_UNLOCK(&surf_source->obj); } + TRACE_MARK("[SET_BUFFER_INFO] BO(%d)", + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); TPL_LOG_T(BACKEND, "[NEW_BUF] buf_info(%p) tbm_surface(%p) bo(%d) (%dx%d) transform(%d)", buf_info, tbm_surface, @@ -1610,6 +1615,8 @@ __cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, return; } + TRACE_ASYNC_END((int)surf_source, "WAIT_VBLANK"); + disp_source = surf_source->disp_source; surf_source->vblank_done = TPL_TRUE; @@ -1690,9 +1697,10 @@ _twe_surface_wait_vblank(twe_wl_surf_source *surf_source) __cb_tdm_client_wait_vblank, (void *)surf_source); - if (tdm_err == TDM_ERROR_NONE) + if (tdm_err == TDM_ERROR_NONE) { surf_source->vblank_done = TPL_FALSE; - else { + TRACE_ASYNC_BEGIN((int)surf_source, "WAIT_VBLANK"); + } else { TPL_ERR("Failed to tdm_client_vblank_wait. tdm_err(%d)", tdm_err); return TPL_ERROR_INVALID_OPERATION; } -- 2.7.4 From f0d6739dfa773f29af64ef9f76ee8b1734cc38af Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 5 Jan 2018 17:31:40 +0900 Subject: [PATCH 10/16] tpl_wl_vk_thread: Implemented reference count for swapchain. - The order of creation and destruction of swapchain is not clear when reset is needed by HWC or resize. - When regeneration is needed, the vulkan application can either destroy the old swapchain first, or create a new swapchain before that. - In Tizen, however, the tbm_surface_queue of swapchain does not actually need to be regenerated. - Therefore, the 'reference count' of swapchain is needed to prevent unintended regeneration of tbm_surface_queue. Change-Id: Ibe05f922ef149fa668a23c678065a89131ff547d Signed-off-by: joonbum.ko --- src/tpl_wl_vk_thread.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index b175f39..141a3f6 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -26,6 +26,7 @@ struct _tpl_wayland_vk_wsi_surface { int buffer_count; tpl_bool_t is_activated; tpl_bool_t reset; + tpl_util_atomic_uint swapchain_reference; }; static tpl_result_t __tpl_wl_vk_wsi_surface_destroy_swapchain( @@ -458,8 +459,8 @@ __tpl_wl_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, tsq_err = tbm_surface_queue_dequeue(wayland_vk_wsi_surface->tbm_queue, &tbm_surface); if (!tbm_surface) { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d", - tsq_err); + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue(%p) | tsq_err = %d", + wayland_vk_wsi_surface->tbm_queue, tsq_err); if (lock_ret == TPL_ERROR_NONE) twe_display_unlock(wayland_vk_wsi_display->twe_display); return NULL; @@ -510,8 +511,8 @@ __tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, for (i = 0 ; i < wayland_vk_wsi_surface->buffer_count ; i++) { tsq_err = tbm_surface_queue_dequeue(wayland_vk_wsi_surface->tbm_queue, &buffer); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue | tsq_err = %d", - tsq_err); + TPL_ERR("Failed to get tbm_surface from tbm_surface_queue(%p) | tsq_err = %d", + wayland_vk_wsi_surface->tbm_queue, tsq_err); dequeue_count = i; ret = TPL_ERROR_OUT_OF_MEMORY; goto get_buffer_fail; @@ -623,6 +624,9 @@ __tpl_wl_vk_wsi_surface_create_swapchain(tpl_surface_t *surface, wayland_vk_wsi_surface->buffer_count = tbm_surface_queue_get_size(wayland_vk_wsi_surface->tbm_queue); wayland_vk_wsi_surface->reset = TPL_FALSE; + + __tpl_util_atomic_inc(&wayland_vk_wsi_surface->swapchain_reference); + TPL_LOG_T("WL_VK", "[REUSE] wayland_vk_wsi_surface(%p) tbm_queue(%p) size(%d)", wayland_vk_wsi_surface, wayland_vk_wsi_surface->tbm_queue, wayland_vk_wsi_surface->buffer_count); @@ -654,6 +658,8 @@ __tpl_wl_vk_wsi_surface_create_swapchain(tpl_surface_t *surface, wayland_vk_wsi_surface->buffer_count = buffer_count; wayland_vk_wsi_surface->reset = TPL_FALSE; + __tpl_util_atomic_set(&wayland_vk_wsi_surface->swapchain_reference, 1); + return TPL_ERROR_NONE; } @@ -662,6 +668,7 @@ __tpl_wl_vk_wsi_surface_destroy_swapchain(tpl_surface_t *surface) { tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; tpl_result_t res = TPL_ERROR_NONE; + unsigned int ref; TPL_ASSERT(surface); TPL_ASSERT(surface->backend.data); @@ -670,6 +677,15 @@ __tpl_wl_vk_wsi_surface_destroy_swapchain(tpl_surface_t *surface) wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *) surface->backend.data; TPL_ASSERT(wayland_vk_wsi_surface); + ref = __tpl_util_atomic_dec(&wayland_vk_wsi_surface->swapchain_reference); + if (ref > 0) { + TPL_LOG_T("WL_VK", + "This swapchain is still valid. | twe_surface(%p)", + wayland_vk_wsi_surface->twe_surface); + return TPL_ERROR_NONE; + } + + if (wayland_vk_wsi_surface->reset) { TPL_LOG_T("WL_VK", "Since reset is in the TRUE state, it will not be destroyed."); -- 2.7.4 From b97db75972ce555526a391ba324b4c2d2ebf3f3d Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 9 Jan 2018 17:59:46 +0900 Subject: [PATCH 11/16] tpl_wayland_egl_thread: Added a new internal API to get swapchain buffers from wl_tbm_client. - Added internal API is twe_surface_get_swapchain_buffers. - This function uses the wayland-tbm API 'wayland_tbm_client_queue_get_surfaces()' to get the handle of tbm_surfaces to be used from the tbm_surface_queue of swapchain. Change-Id: If2d5d2f2d6bbb85ba586d56a9ffac6cb54cb689e Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 33 +++++++++++++++++++++++++++++++++ src/tpl_wayland_egl_thread.h | 5 +++++ 2 files changed, 38 insertions(+) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 7704956..d800c4c 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -2658,6 +2658,39 @@ twe_surface_destroy_swapchain(twe_surface_h twe_surface) return TPL_ERROR_NONE; } +tpl_result_t +twe_surface_get_swapchain_buffers(twe_surface_h twe_surface, + tbm_surface_h *surfaces, + int *buffer_count) +{ + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)twe_surface; + twe_wl_disp_source *disp_source = NULL; + int ret = 1; + + if (!surf_source || g_source_is_destroyed(&surf_source->gsource)) { + TPL_ERR("twe_surface(%p) is invalid.", twe_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (!surfaces) { + *buffer_count = tbm_surface_queue_get_size(surf_source->tbm_queue); + return TPL_ERROR_NONE; + } + + disp_source = surf_source->disp_source; + + ret = wayland_tbm_client_queue_get_surfaces( + disp_source->wl_tbm_client, + surf_source->tbm_queue, + surfaces, buffer_count); + if (!ret) { + TPL_ERR("Failed to get buffers from wl_tbm_client(%p) tbm_queue(%p)", + disp_source->wl_tbm_client, surf_source->tbm_queue); + return TPL_ERROR_INVALID_OPERATION; + } + + return TPL_ERROR_NONE; +} tpl_result_t twe_surface_set_rotate_callback(twe_surface_h twe_surface, diff --git a/src/tpl_wayland_egl_thread.h b/src/tpl_wayland_egl_thread.h index e89d527..bd32f1d 100644 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -55,6 +55,11 @@ twe_surface_create_swapchain(twe_surface_h twe_surface, tpl_result_t twe_surface_destroy_swapchain(twe_surface_h twe_surface); +tpl_result_t +twe_surface_get_swapchain_buffers(twe_surface_h twe_surface, + tbm_surface_h *surfaces, + int *buffer_count); + tbm_surface_queue_h twe_surface_get_tbm_queue(twe_surface_h twe_surface); -- 2.7.4 From 96fcf4d7efba17a80c67562716f602d5817cd7df Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 9 Jan 2018 19:09:45 +0900 Subject: [PATCH 12/16] tpl_wl_vk_thread: Modified get_swapchain_buffers to use internal function. - Before this commit, had to call tbm_surface_queue_dequeue() as much as wayland_vk_wsi_surface->buffer_count to get the handle of the buffers. - And dequeued buffers must be return to tbm_surface_queue with tbm_surface_queue_release(). - This method is complicated and not suitable for HWC situations, so I modified it to get handles of the buffers from wl_tbm_client via twe_surface_get_swapchain_buffers(). Change-Id: I535a531219cd2284a230cc4583b818aa16593c21 Signed-off-by: joonbum.ko --- src/tpl_wl_vk_thread.c | 51 ++++++++++++++------------------------------------ 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 141a3f6..f670382 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -487,11 +487,9 @@ __tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, tbm_surface_h **buffers, int *buffer_count) { - tbm_surface_h buffer = NULL; tbm_surface_h *swapchain_buffers = NULL; tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; - tbm_surface_queue_error_e tsq_err; - int i, dequeue_count; + int i; tpl_result_t ret = TPL_ERROR_NONE; TPL_ASSERT(surface); @@ -508,46 +506,25 @@ __tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, return TPL_ERROR_OUT_OF_MEMORY; } - for (i = 0 ; i < wayland_vk_wsi_surface->buffer_count ; i++) { - tsq_err = tbm_surface_queue_dequeue(wayland_vk_wsi_surface->tbm_queue, &buffer); - if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { - TPL_ERR("Failed to get tbm_surface from tbm_surface_queue(%p) | tsq_err = %d", - wayland_vk_wsi_surface->tbm_queue, tsq_err); - dequeue_count = i; - ret = TPL_ERROR_OUT_OF_MEMORY; - goto get_buffer_fail; - } - swapchain_buffers[i] = buffer; - TPL_DEBUG("swapchain_buffers[%d] = tbm_surface(%p)", i, buffer); + ret = twe_surface_get_swapchain_buffers(wayland_vk_wsi_surface->twe_surface, + swapchain_buffers, buffer_count); + if (ret != TPL_ERROR_NONE) { + TPL_ERR("Failed to get swapchain_buffers. wayland_vk_wsi_surface(%p) twe_surface(%p)", + wayland_vk_wsi_surface, wayland_vk_wsi_surface->twe_surface); + free(swapchain_buffers); + swapchain_buffers = NULL; + return ret; } - for (i = 0 ; i < wayland_vk_wsi_surface->buffer_count ; i++) { - tsq_err = tbm_surface_queue_release(wayland_vk_wsi_surface->tbm_queue, - swapchain_buffers[i]); - if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { - TPL_ERR("Failed to release tbm_surface. | tsq_err = %d", tsq_err); - ret = TPL_ERROR_INVALID_OPERATION; - goto release_buffer_fail; - } + for (i = 0; i < *buffer_count; i++) { + TPL_DEBUG("swapchain_buffers[%d] = tbm_surface(%p) bo(%d)", + i, swapchain_buffers[i], + tbm_bo_export(tbm_surface_internal_get_bo(swapchain_buffers[i], 0))); } *buffers = swapchain_buffers; - *buffer_count = wayland_vk_wsi_surface->buffer_count; - return TPL_ERROR_NONE; -get_buffer_fail: - for (i = 0 ; i < dequeue_count ; i++) { - tsq_err = tbm_surface_queue_release(wayland_vk_wsi_surface->tbm_queue, - swapchain_buffers[i]); - if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { - TPL_ERR("Failed to release tbm_surface. | tsq_err = %d", tsq_err); - goto release_buffer_fail; - } - } - -release_buffer_fail: - free(swapchain_buffers); - return ret; + return TPL_ERROR_NONE; } static void -- 2.7.4 From c34883b51af32f6756daf09e8daea5412ec0a24e Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 9 Jan 2018 20:10:09 +0900 Subject: [PATCH 13/16] Fixed some build warnings. Change-Id: Ia3b45e382cafe02e25f9aaf777338dbd4f9e191e Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 5 +++-- src/tpl_wl_egl_thread.c | 2 +- src/tpl_wl_vk_thread.c | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index d800c4c..4ae5313 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -2608,7 +2608,7 @@ twe_surface_destroy_swapchain(twe_surface_h twe_surface) } if (surf_source->vk_sub_thread) { - TPL_DEBUG("vk_sub_thread(%d) exit.", 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); @@ -2837,7 +2837,8 @@ twe_surface_commit_without_enqueue(twe_surface_h twe_surface, if (!surf_source->is_destroying) _twe_thread_wl_surface_commit(surf_source, tbm_surface); else - TPL_WARN("surf_source(%p) native window is already destroyed."); + TPL_WARN("surf_source(%p) native window is already destroyed.", + surf_source); TPL_OBJECT_UNLOCK(&surf_source->obj); } diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index b7e2128..e4fa659 100644 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -698,7 +698,7 @@ __tpl_wl_egl_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, surface->frontbuffer, tbm_bo_export(tbm_surface_internal_get_bo( surface->frontbuffer, 0))); - TRACE_ASYNC_BEGIN(surface->frontbuffer, + TRACE_ASYNC_BEGIN((int)surface->frontbuffer, "[DEQ]~[ENQ] BO_NAME:%d", tbm_bo_export(tbm_surface_internal_get_bo( surface->frontbuffer, 0))); diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index f670382..6f96b2f 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -433,12 +433,13 @@ __tpl_wl_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, lock_ret = twe_display_lock(wayland_vk_wsi_display->twe_display); if (res == TPL_ERROR_TIME_OUT) { - TPL_ERR("Failed to get buffer during timeout_ns(%u)", timeout_ns); + TPL_ERR("Failed to get buffer during timeout_ns(%" PRIu64 ")", + timeout_ns); if (lock_ret == TPL_ERROR_NONE) twe_display_unlock(wayland_vk_wsi_display->twe_display); return NULL; } else if (res != TPL_ERROR_NONE) { - TPL_ERR("Invalid parameter. twe_surface(%p) timeout_ns(%u)", + TPL_ERR("Invalid parameter. twe_surface(%p) timeout_ns(%" PRIu64 ")", wayland_vk_wsi_surface->twe_surface, timeout_ns); if (lock_ret == TPL_ERROR_NONE) twe_display_unlock(wayland_vk_wsi_display->twe_display); -- 2.7.4 From 0459ee298e0e1941b08c7d6e7563f228c5e57e7b Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 16 Jan 2018 13:58:03 +0900 Subject: [PATCH 14/16] tpl_wayland_egl_thread: Registered dequeueable callback to tbm_queue. - Signal to free_queue_cond when dequeuable callback is called. - wl_buffer release callback does not signal to free_queue_cond, and if dequeuable callback is called when tbm_surface_queue_release() is called, signal to free_queue_cond. Change-Id: I52d898f37ef6dc5074e98690399a04116869d177 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 58 +++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 4ae5313..6c4f1ef 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -1273,8 +1273,6 @@ __cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer) twe_wl_surf_source *surf_source = buf_info->surf_source; tbm_surface_queue_error_e tsq_err; - g_mutex_lock(&surf_source->free_queue_mutex); - tsq_err = tbm_surface_queue_release(surf_source->tbm_queue, tbm_surface); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) @@ -1301,9 +1299,6 @@ __cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer) tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); tbm_surface_internal_unref(tbm_surface); - g_cond_signal(&surf_source->free_queue_cond); - g_mutex_unlock(&surf_source->free_queue_mutex); - return; } @@ -1543,16 +1538,23 @@ __cb_tbm_queue_reset_callback(tbm_surface_queue_h tbm_queue, { twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data; - if (surf_source && !g_source_is_destroyed(&surf_source->gsource)) { - surf_source->swapchain_properties.width = - tbm_surface_queue_get_width(tbm_queue); - surf_source->swapchain_properties.height = - tbm_surface_queue_get_height(tbm_queue); - surf_source->swapchain_properties.buffer_count = - tbm_surface_queue_get_size(tbm_queue); - surf_source->format = tbm_surface_queue_get_format(tbm_queue); + if (!surf_source || g_source_is_destroyed(&surf_source->gsource)) { + TPL_ERR("Invalid parameter. surf_source(%p)", surf_source); + return; } + surf_source->swapchain_properties.width = + tbm_surface_queue_get_width(tbm_queue); + surf_source->swapchain_properties.height = + tbm_surface_queue_get_height(tbm_queue); + surf_source->swapchain_properties.buffer_count = + tbm_surface_queue_get_size(tbm_queue); + surf_source->format = tbm_surface_queue_get_format(tbm_queue); + + g_mutex_lock(&surf_source->free_queue_mutex); + g_cond_signal(&surf_source->free_queue_cond); + g_mutex_unlock(&surf_source->free_queue_mutex); + TPL_LOG_T(BACKEND, "tbm_queue(%p) has been reset!", tbm_queue); } @@ -1594,6 +1596,25 @@ static void __cb_tbm_queue_trace_callback(tbm_surface_queue_h tbm_queue, } } +static void __cb_tbm_queue_dequeueable_callback(tbm_surface_queue_h tbm_queue, + void *data) +{ + twe_wl_surf_source *surf_source = (twe_wl_surf_source *)data; + + if (!surf_source || g_source_is_destroyed(&surf_source->gsource)) { + TPL_ERR("Invalid parameter. surf_source(%p)", surf_source); + return; + } + + g_mutex_lock(&surf_source->free_queue_mutex); + + TPL_LOG_T(BACKEND, "[DEQUEUEABLE_CB] surf_source(%p) tbm_queue(%p)", + surf_source, surf_source->tbm_queue); + + g_cond_signal(&surf_source->free_queue_cond); + g_mutex_unlock(&surf_source->free_queue_mutex); +} + static void _twe_thread_wl_vk_surface_commit(twe_wl_surf_source *surf_source, tbm_surface_h tbm_surface); @@ -2141,7 +2162,7 @@ _twe_surface_create_tbm_queue(twe_wl_surf_source *source, if (tbm_surface_queue_add_reset_cb(tbm_queue, __cb_tbm_queue_reset_callback, - NULL) != TBM_SURFACE_QUEUE_ERROR_NONE) { + (void *)source) != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("Failed to register reset callback to tbm_surface_queue(%p)", tbm_queue); tbm_surface_queue_destroy(tbm_queue); @@ -2553,6 +2574,15 @@ twe_surface_create_swapchain(twe_surface_h twe_surface, return TPL_ERROR_INVALID_OPERATION; } + if (tbm_surface_queue_add_dequeuable_cb(surf_source->tbm_queue, + __cb_tbm_queue_dequeueable_callback, + (void *)surf_source) != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to register dequeueable callback to tbm_surface_queue(%p)", + surf_source->tbm_queue); + tbm_surface_queue_destroy(surf_source->tbm_queue); + return TPL_ERROR_INVALID_OPERATION; + } + if (present_mode == TPL_DISPLAY_PRESENT_MODE_FIFO || present_mode == TPL_DISPLAY_PRESENT_MODE_FIFO_RELAXED) { surf_source->vblank_waiting_buffers = __tpl_list_alloc(); -- 2.7.4 From b7c050ba63dc9f6940a65798211e4d6742b27b31 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 16 Jan 2018 15:36:58 +0900 Subject: [PATCH 15/16] tpl_wayland_egl_thread: Changed to use GMutex instead of tpl_object of the disp_source. Change-Id: Ieec00366d2084cfb9b77ed518bac7c3fb8c7d1b2 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 6c4f1ef..1a69167 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -75,7 +75,7 @@ struct _twe_wl_disp_source { tpl_bool_t prepared; twe_del_source *disp_del_source; twe_thread *thread; - tpl_object_t obj; + GMutex wl_event_mutex; /* TODO : surface list */ }; @@ -634,7 +634,7 @@ _twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer data) return G_SOURCE_REMOVE; } - TPL_OBJECT_LOCK(&disp_source->obj); + g_mutex_lock(&disp_source->wl_event_mutex); if (disp_source->gfd.revents & G_IO_IN) { if (wl_display_dispatch_queue_pending(disp_source->disp, disp_source->ev_queue) == -1) { @@ -643,7 +643,7 @@ _twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer data) } wl_display_flush(disp_source->disp); - TPL_OBJECT_UNLOCK(&disp_source->obj); + g_mutex_unlock(&disp_source->wl_event_mutex); return G_SOURCE_CONTINUE; } @@ -651,11 +651,7 @@ _twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer data) static void _twe_thread_wl_disp_finalize(GSource *source) { - twe_wl_disp_source *disp_source = (twe_wl_disp_source *)source; - - TPL_LOG_T(BACKEND, "finalize| disp_source(%p)", disp_source); - - __tpl_object_fini(&disp_source->obj); + TPL_LOG_T(BACKEND, "finalize| disp_source(%p)", source); return; } @@ -917,7 +913,7 @@ _twe_thread_wl_disp_source_destroy(void *source) } g_mutex_lock(&_twe_ctx->thread_mutex); - TPL_OBJECT_LOCK(&disp_source->obj); + g_mutex_lock(&disp_source->wl_event_mutex); /* If disp_source is in prepared state, cancel it */ if (disp_source->prepared) { @@ -931,11 +927,13 @@ _twe_thread_wl_disp_source_destroy(void *source) } wl_event_queue_destroy(disp_source->ev_queue); - TPL_OBJECT_UNLOCK(&disp_source->obj); + g_mutex_unlock(&disp_source->wl_event_mutex); TPL_LOG_T(BACKEND, "[DEL] twe_display(%p) wl_display(%p)", disp_source, disp_source->disp); + g_mutex_clear(&disp_source->wl_event_mutex); + g_source_remove_poll(&disp_source->gsource, &disp_source->gfd); g_source_destroy(&disp_source->gsource); g_source_unref(&disp_source->gsource); @@ -981,7 +979,7 @@ twe_display_add(twe_thread* thread, source->gfd.fd = wl_display_get_fd(display); source->gfd.events = G_IO_IN | G_IO_ERR; source->gfd.revents = 0; - __tpl_object_init(&source->obj, TPL_OBJECT_DISPLAY, NULL); + g_mutex_init(&source->wl_event_mutex); if (backend == TPL_BACKEND_WAYLAND_VULKAN_WSI || backend == TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD) { @@ -1062,7 +1060,9 @@ twe_display_lock(twe_display_h display) return TPL_ERROR_INVALID_PARAMETER; } - return TPL_OBJECT_LOCK(&disp_source->obj); + g_mutex_lock(&disp_source->wl_event_mutex); + + return TPL_ERROR_NONE; } void @@ -1074,7 +1074,7 @@ twe_display_unlock(twe_display_h display) return; } - TPL_OBJECT_UNLOCK(&disp_source->obj); + g_mutex_unlock(&disp_source->wl_event_mutex); } tpl_result_t @@ -2240,7 +2240,7 @@ _twe_thread_wl_surf_source_destroy(void *source) g_mutex_lock(&_twe_ctx->thread_mutex); - TPL_OBJECT_LOCK(&disp_source->obj); + g_mutex_lock(&disp_source->wl_event_mutex); if (surf_source->in_use_buffers) { __tpl_list_free(surf_source->in_use_buffers, @@ -2298,7 +2298,7 @@ _twe_thread_wl_surf_source_destroy(void *source) surf_source->surf = NULL; } - TPL_OBJECT_UNLOCK(&disp_source->obj); + g_mutex_unlock(&disp_source->wl_event_mutex); g_cond_clear(&surf_source->free_queue_cond); g_mutex_clear(&surf_source->free_queue_mutex); -- 2.7.4 From 169c9152399e169cc74005c8c14ed9a52e126467 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 17 Jan 2018 11:40:16 +0900 Subject: [PATCH 16/16] tpl_wayland_egl_thread: Changed to use GMutex instead of tpl_object of the surf_source. Change-Id: I05bdca4011f142fd39db939de49a9d83db55259c Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 54 ++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 1a69167..cc3e2e8 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -104,7 +104,6 @@ struct _twe_wl_surf_source { } swapchain_properties; tpl_surface_cb_func_t rotate_cb; tpl_bool_t rotation_capability; - tpl_object_t obj; /* for mutex lock */ tpl_list_t *committed_buffers; tpl_list_t *in_use_buffers; tpl_list_t *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */ @@ -117,6 +116,8 @@ struct _twe_wl_surf_source { twe_wl_disp_source *disp_source; twe_del_source *surf_del_source; + GMutex surf_mutex; + GMutex free_queue_mutex; GCond free_queue_cond; @@ -1123,12 +1124,12 @@ __cb_destroy_callback(void *private) if (surf_source) { TPL_LOG_T(BACKEND, "[DESTROY_CB] wl_egl_window(%p) surf_source(%p)", surf_source->wl_egl_window, surf_source); - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); surf_source->wl_egl_window->private = NULL; surf_source->wl_egl_window = NULL; surf_source->surf = NULL; surf_source->is_destroying = TPL_TRUE; - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } } @@ -1279,11 +1280,11 @@ __cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer) TPL_ERR("tbm_surface(%p) tsq_err(%d)", tbm_surface, tsq_err); if (surf_source->committed_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); __tpl_list_remove_data(surf_source->committed_buffers, (void *)tbm_surface, TPL_FIRST, NULL); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } buf_info->need_to_release = TPL_FALSE; @@ -1308,11 +1309,11 @@ __cb_buffer_release_callback(void *data, struct wl_proxy *wl_buffer) g_mutex_lock(&surf_source->free_queue_mutex); if (surf_source->committed_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); __tpl_list_remove_data(surf_source->committed_buffers, (void *)tbm_surface, TPL_FIRST, NULL); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } TRACE_MARK("[RELEASE] BO(%d)", @@ -1389,10 +1390,10 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info->sync_fd = -1; if (surf_source->in_use_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); __tpl_list_push_back(surf_source->in_use_buffers, (void *)tbm_surface); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } TRACE_MARK("[SET_BUFFER_INFO] BO(%d)", @@ -1485,10 +1486,10 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info); if (surf_source->in_use_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); __tpl_list_push_back(surf_source->in_use_buffers, (void *)tbm_surface); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } TRACE_MARK("[SET_BUFFER_INFO] BO(%d)", @@ -1524,11 +1525,11 @@ _twe_surface_cancel_dequeued_buffer(twe_wl_surf_source *surf_source, tbm_surface); if (surf_source->in_use_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); /* Stop tracking of this canceled tbm_surface */ __tpl_list_remove_data(surf_source->in_use_buffers, (void *)tbm_surface, TPL_FIRST, NULL); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } } @@ -1645,7 +1646,7 @@ __cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, if (!disp_source->is_vulkan_dpy) _twe_thread_wl_surface_acquire_and_commit(surf_source); else { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); switch (surf_source->swapchain_properties.present_mode) { case TPL_DISPLAY_PRESENT_MODE_MAILBOX: if (surf_source->draw_done_buffer) { @@ -1686,7 +1687,7 @@ __cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error, break; } - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } } @@ -1928,7 +1929,7 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO, (void **)&buf_info); - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); if (!disp_source->is_vulkan_dpy) { /* wayland_egl */ TPL_LOG_T(BACKEND, "[ACQ] tbm_surface(%p) bo(%d)", tbm_surface, @@ -1996,7 +1997,7 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source) break; } } - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } } @@ -2048,8 +2049,6 @@ _twe_thread_wl_surface_finalize(GSource *source) close(surf_source->event_fd); surf_source->event_fd = -1; - __tpl_object_fini(&surf_source->obj); - return; } @@ -2242,6 +2241,8 @@ _twe_thread_wl_surf_source_destroy(void *source) g_mutex_lock(&disp_source->wl_event_mutex); + g_mutex_lock(&surf_source->surf_mutex); + if (surf_source->in_use_buffers) { __tpl_list_free(surf_source->in_use_buffers, (tpl_free_func_t)__cb_buffer_remove_from_list); @@ -2298,6 +2299,9 @@ _twe_thread_wl_surf_source_destroy(void *source) surf_source->surf = NULL; } + g_mutex_unlock(&surf_source->surf_mutex); + g_mutex_clear(&surf_source->surf_mutex); + g_mutex_unlock(&disp_source->wl_event_mutex); g_cond_clear(&surf_source->free_queue_cond); @@ -2397,8 +2401,6 @@ twe_surface_add(twe_thread* thread, source->vk_sub_thread = NULL; source->draw_done_count = 0; - __tpl_object_init(&source->obj, TPL_OBJECT_SURFACE, NULL); - if (!disp_source->is_vulkan_dpy) { struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)native_handle; @@ -2430,6 +2432,8 @@ twe_surface_add(twe_thread* thread, g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop)); + g_mutex_init(&source->surf_mutex); + g_mutex_init(&source->free_queue_mutex); g_cond_init(&source->free_queue_cond); @@ -2662,7 +2666,7 @@ twe_surface_destroy_swapchain(twe_surface_h twe_surface) } if (surf_source->committed_buffers) { - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); while (!__tpl_list_is_empty(surf_source->committed_buffers)) { tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; tbm_surface_h tbm_surface = @@ -2677,7 +2681,7 @@ twe_surface_destroy_swapchain(twe_surface_h twe_surface) TPL_ERR("Failed to release. tbm_surface(%p) tsq_err(%d)", tbm_surface, tsq_err); } - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } if (surf_source->tbm_queue) { @@ -2863,13 +2867,13 @@ twe_surface_commit_without_enqueue(twe_surface_h twe_surface, return; } - TPL_OBJECT_LOCK(&surf_source->obj); + g_mutex_lock(&surf_source->surf_mutex); if (!surf_source->is_destroying) _twe_thread_wl_surface_commit(surf_source, tbm_surface); else TPL_WARN("surf_source(%p) native window is already destroyed.", surf_source); - TPL_OBJECT_UNLOCK(&surf_source->obj); + g_mutex_unlock(&surf_source->surf_mutex); } static gboolean -- 2.7.4