From a105ba6612f0e8d9f5bb09c79b27c1effc595188 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 9 May 2018 14:16:40 +0900 Subject: [PATCH 01/16] Package version up to 1.5.7 Change-Id: Ifc38b36e2fb6b133014420d8f9b530be4d03136f 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 6808790..46b186e 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 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 b3062df98d3b45cce65b5d4d30f43ee0f2defefa Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 15 Jun 2018 17:07:10 +0900 Subject: [PATCH 02/16] tpl_wl_vk_thread: Implemented cancel_dequeued_buffer() for vk_wsi_thread backend. Change-Id: I3b7484222b073b7b280335f0d7cc13b524398697 Signed-off-by: joonbum.ko --- src/tpl_wl_vk_thread.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 9c7a8c1..8e68f8d 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -393,6 +393,40 @@ __tpl_wl_vk_wsi_surface_validate(tpl_surface_t *surface) return !(wayland_vk_wsi_surface->reset); } +static tpl_result_t +__tpl_wl_vk_wsi_surface_cancel_dequeued_buffer(tpl_surface_t *surface, + tbm_surface_h tbm_surface) +{ + tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; + tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; + + wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *)surface->backend.data; + if (!wayland_vk_wsi_surface) { + TPL_ERR("Invalid backend surface. surface(%p) wayland_vk_wsi_surface(%p)", + surface, wayland_vk_wsi_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (!tbm_surface_internal_is_valid(tbm_surface)) { + TPL_ERR("Invalid buffer. tbm_surface(%p)", tbm_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + tbm_surface_internal_unref(tbm_surface); + + tsq_err = tbm_surface_queue_cancel_dequeue(wayland_vk_wsi_surface->tbm_queue, + tbm_surface); + if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to release tbm_surface(%p)", tbm_surface); + return TPL_ERROR_INVALID_OPERATION; + } + + TPL_LOG_T("WL_VK", "[CANCEL BUFFER] tpl_surface(%p) tbm_surface(%p)", + surface, tbm_surface); + + return TPL_ERROR_NONE; +} + static tbm_surface_h __tpl_wl_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, uint64_t timeout_ns, @@ -710,6 +744,8 @@ __tpl_surface_init_backend_wl_vk_wsi_thread(tpl_surface_backend_t *backend) backend->init = __tpl_wl_vk_wsi_surface_init; backend->fini = __tpl_wl_vk_wsi_surface_fini; backend->validate = __tpl_wl_vk_wsi_surface_validate; + backend->cancel_dequeued_buffer = + __tpl_wl_vk_wsi_surface_cancel_dequeued_buffer; backend->dequeue_buffer = __tpl_wl_vk_wsi_surface_dequeue_buffer; backend->enqueue_buffer = __tpl_wl_vk_wsi_surface_enqueue_buffer; backend->get_swapchain_buffers = -- 2.7.4 From 2915ded4ce2101259ac1b4bad128f5f8b37c4263 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Fri, 15 Jun 2018 17:09:42 +0900 Subject: [PATCH 03/16] tpl_surface: Fixed tpl_surface_create() to support oldSwapchain. - In vulkan, new swapchain use same native_surface with old swapchain's one. - So when new swapchain created with using oldswapchain, if there is already existed tpl_surface in runtime hlist, skip the adding procedure to create new swapchain's tpl_surface. Change-Id: I26d8048da596bfbb2bc3e825c41e7295000a18cd Signed-off-by: joonbum.ko --- src/tpl_surface.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/tpl_surface.c b/src/tpl_surface.c index 2252f15..437ec02 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -69,12 +69,18 @@ tpl_surface_create(tpl_display_t *display, tpl_handle_t handle, return NULL; } - /* Add it to the runtime. */ - ret = __tpl_runtime_add_surface(surface); - if (ret != TPL_ERROR_NONE) { - TPL_ERR("Failed to add surface to runtime list!"); - tpl_object_unreference((tpl_object_t *) surface); - return NULL; + /* vulkan feature */ + /* vulkan can create more than one tpl_surface with one native surface + * for supporting oldSwapchain. + */ + if (tpl_surface_get(display, handle) == NULL) { + /* Add it to the runtime. */ + ret = __tpl_runtime_add_surface(surface); + if (ret != TPL_ERROR_NONE) { + TPL_ERR("Failed to add surface to runtime list!"); + tpl_object_unreference((tpl_object_t *) surface); + return NULL; + } } TPL_LOG_F("tpl_display_t(%p) tpl_surface_t(%p) native_handle(%p) format(%d)", -- 2.7.4 From 4e9762c3b92e706c2dfd41128df5973f495e117e Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 19 Jun 2018 15:36:00 +0900 Subject: [PATCH 04/16] tpl_wayland_egl: Deleted dispatch codes at the flush callback. - dispatch_pending in a flush callback can cause unexpected problems in multi-surfaces scenarios. Change-Id: I0327b907c9756bd3fa9a08af0c73bc89299395f5 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index f7b77b0..8b6e104 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -663,7 +663,7 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) wl_display_dispatch_queue_pending(wayland_egl_display->wl_dpy, wayland_egl_display->wl_tbm_event_queue); /* When surface is destroyed, unreference tbm_surface which tracked by - * the list of attached_buffers in order to free the created resources. + * the list of attached_buffers in order to free the created resources. * (tpl_wayland_egl_buffer_t or wl_buffer) */ if (wayland_egl_surface->attached_buffers) { TPL_OBJECT_LOCK(&wayland_egl_surface->base); @@ -672,7 +672,7 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) tbm_surface_h tbm_surface = __tpl_list_pop_front(wayland_egl_surface->attached_buffers, NULL); TRACE_ASYNC_END((int)tbm_surface, "[COMMIT ~ RELEASE_CB] BO_NAME:%d", - tbm_bo_export(tbm_surface_internal_get_bo( + tbm_bo_export(tbm_surface_internal_get_bo( tbm_surface, 0))); tbm_surface_internal_unref(tbm_surface); tsq_err = tbm_surface_queue_release(wayland_egl_surface->tbm_queue, tbm_surface); @@ -1644,7 +1644,6 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, tpl_surface_t *surface = 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); @@ -1663,19 +1662,6 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, TPL_LOG_B("WL_EGL", "[FLUSH_CB] tpl_wayland_egl_surface_t(%p)", wayland_egl_surface); - /*Fist distach panding queue for TPL - - dispatch buffer-release - - dispatch queue flush - */ - ret = wl_display_dispatch_queue_pending(wayland_egl_display->wl_dpy, - wayland_egl_display->wl_tbm_event_queue); - 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_flush(wayland_egl_surface->tbm_queue); /* Only when client call tpl_surface_dequeue_buffer(), client can do @@ -1692,7 +1678,7 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, tbm_surface_h tbm_surface = __tpl_list_pop_front(wayland_egl_surface->attached_buffers, NULL); TRACE_ASYNC_END((int)tbm_surface, "[COMMIT ~ RELEASE_CB] BO_NAME:%d", - tbm_bo_export(tbm_surface_internal_get_bo( + tbm_bo_export(tbm_surface_internal_get_bo( tbm_surface, 0))); tbm_surface_internal_unref(tbm_surface); tsq_err = tbm_surface_queue_release(wayland_egl_surface->tbm_queue, tbm_surface); @@ -1712,7 +1698,6 @@ static void __cb_tizen_surface_shm_flusher_free_flush_callback(void *data, tpl_surface_t *surface = 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); @@ -1731,19 +1716,6 @@ static void __cb_tizen_surface_shm_flusher_free_flush_callback(void *data, TPL_LOG_B("WL_EGL", "[FLUSH_CB] tpl_wayland_egl_surface_t(%p)", wayland_egl_surface); - /*Fist distach panding queue for TPL - - dispatch buffer-release - - dispatch queue flush - */ - ret = wl_display_dispatch_queue_pending(wayland_egl_display->wl_dpy, - wayland_egl_display->wl_tbm_event_queue); - 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); -- 2.7.4 From c6736a86ad0f5087f058c3930dc048086282b1c5 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 19 Jun 2018 15:42:16 +0900 Subject: [PATCH 05/16] tpl_wayland_egl(_thread): Changed to destroy wl_event_queue after wl_registry is destroyed. Change-Id: I531719abc4079961b52c9b2467f1f2ea73be5705 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 14 +++++++------- src/tpl_wayland_egl_thread.c | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index 8b6e104..d4d1ecd 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -222,10 +222,10 @@ free_wl_display: tdm_client_destroy(wayland_egl_display->tdm_client); if (wayland_egl_display->wl_tbm_client) wayland_tbm_client_set_event_queue(wayland_egl_display->wl_tbm_client, NULL); - if (wayland_egl_display->wl_tbm_event_queue) - wl_event_queue_destroy(wayland_egl_display->wl_tbm_event_queue); if (wayland_egl_display->wl_tbm_client) wayland_tbm_client_deinit(wayland_egl_display->wl_tbm_client); + if (wayland_egl_display->wl_tbm_event_queue) + wl_event_queue_destroy(wayland_egl_display->wl_tbm_event_queue); pthread_mutex_destroy(&wayland_egl_display->wl_event_mutex); pthread_mutex_destroy(&wayland_egl_display->tdm_mutex); @@ -266,12 +266,12 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) if (wayland_egl_display->wl_tbm_client) wayland_tbm_client_set_event_queue(wayland_egl_display->wl_tbm_client, NULL); - if (wayland_egl_display->wl_tbm_event_queue) - wl_event_queue_destroy(wayland_egl_display->wl_tbm_event_queue); - if (wayland_egl_display->wl_tbm_client) wayland_tbm_client_deinit(wayland_egl_display->wl_tbm_client); + if (wayland_egl_display->wl_tbm_event_queue) + wl_event_queue_destroy(wayland_egl_display->wl_tbm_event_queue); + 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)", @@ -1620,12 +1620,12 @@ __tpl_wayland_egl_display_buffer_flusher_init( NULL); fini: - if (queue) - wl_event_queue_destroy(queue); if (display_wrapper) wl_proxy_wrapper_destroy(display_wrapper); if (registry) wl_registry_destroy(registry); + if (queue) + wl_event_queue_destroy(queue); } static void diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 106f41d..14814bf 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -844,12 +844,12 @@ _twe_display_wayland_init(twe_wl_disp_source *disp_source) } fini: - if (queue) - wl_event_queue_destroy(queue); if (display_wrapper) wl_proxy_wrapper_destroy(display_wrapper); if (registry) wl_registry_destroy(registry); + if (queue) + wl_event_queue_destroy(queue); } static void -- 2.7.4 From 4c12c224a0b21311332219f1af2d826422c3e304 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 28 May 2018 11:37:44 +0900 Subject: [PATCH 06/16] tpl_gbm, tpl_tbm: Set the union rect of given damage rects to tbm_surface. - When egl client call the EGL API(eglSwapBuffersWithDamageEXT or eglSwapBuffersWithDamageKHR), driver will call the tpl API tpl_surface_enqueue_buffer_with_damage(). - The wayland-egl backend for wl_client, when the damage rects were delivered to tpl, that informations can be set to wl_surface with damage_set protocol. But, the compositor could not set damage rects to display manager(tdm). - To make it possible in Tizen, libtbm added the following tbm_surface_internal APIs. commit message : surface: added tbm_surface_internal_set/get_damage func commit ID : 96527bf85d87df8c5767c51c0ec3a53320dbc35d int tbm_surface_internal_set_damage(tbm_surface_h surface, int x, int y, int width, int height); int tbm_surface_internal_get_damage(tbm_surface_h surface, int *x, int *y, int *width, int *height); - In TPL_TBM and TPL_GBM, create a union rectangle of the given damage rects using set_damage() API above to save the damage information to tbm_surface. Change-Id: I1e10087100d0ece919c589868abdb0d6beda9c11 Signed-off-by: joonbum.ko --- src/tpl_gbm.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/tpl_tbm.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/src/tpl_gbm.c b/src/tpl_gbm.c index 15f144b..83c9c81 100644 --- a/src/tpl_gbm.c +++ b/src/tpl_gbm.c @@ -369,13 +369,14 @@ __tpl_gbm_surface_enqueue_buffer(tpl_surface_t *surface, { tpl_gbm_buffer_t *gbm_buffer = NULL; tpl_gbm_surface_t *gbm_surface = NULL; + int ret = 0; + int union_x, union_y; + int union_w, union_h; TPL_ASSERT(surface); TPL_ASSERT(surface->display); TPL_ASSERT(surface->display->native_handle); TPL_ASSERT(tbm_surface); - TPL_IGNORE(num_rects); - TPL_IGNORE(rects); gbm_surface = (tpl_gbm_surface_t *)surface->backend.data; if (!gbm_surface) { @@ -413,6 +414,51 @@ __tpl_gbm_surface_enqueue_buffer(tpl_surface_t *surface, close(sync_fence); } + /* If there are given damage rects for given tbm_surface, */ + if (num_rects != 0 && rects != NULL) { + int i; + int left = surface->width; + int bottom = surface->height; + int right = 0, top = 0; + + /* Carculate the union region of given damage rectangles */ + for (i = 0; i < num_rects; i++) { + int rect_i = i * 4; + int x = rects[rect_i]; + int y = rects[rect_i + 1]; + int w = rects[rect_i + 2]; + int h = rects[rect_i + 3]; + + left = (x < left) ? x : left; + bottom = (y < bottom) ? y : bottom; + right = ((x + w) > right) ? (x + w) : right; + top = ((y + h) > top) ? (y + h) : top; + } + + /* Calibrate so as not to exceed the range. */ + left = (left < 0) ? 0 : left; + bottom = (bottom < 0) ? 0 : bottom; + right = (right > surface->width) ? surface->width : right; + top = (top > surface->height) ? surface->height : top; + + /* And set its union rect to tbm_surface as its damage region. */ + union_w = right - left; + union_h = top - bottom; + union_x = left; + union_y = top; + } else { + /* If there are no any damage rects, + * set its full size of surface as its damage region. */ + union_w = surface->width; + union_h = surface->height; + union_x = 0; + union_y = 0; + } + + if (!(ret = tbm_surface_internal_set_damage(tbm_surface, union_x, union_y, + union_w, union_h))) + TPL_WARN("Failed to set damage rect to tbm_surface(%p)", tbm_surface); + if (tbm_surface_queue_enqueue(gbm_surface->tbm_queue, tbm_surface) != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("tbm_surface_queue_enqueue failed. tbm_surface_queue(%p) tbm_surface(%p)", diff --git a/src/tpl_tbm.c b/src/tpl_tbm.c index 0c64ee2..9b258f0 100644 --- a/src/tpl_tbm.c +++ b/src/tpl_tbm.c @@ -521,13 +521,14 @@ __tpl_tbm_surface_enqueue_buffer(tpl_surface_t *surface, tpl_tbm_surface_t *tpl_tbm_surface = NULL; tpl_tbm_buffer_t *tpl_tbm_buffer = NULL; tbm_surface_queue_h tbm_queue = NULL; + int ret = 0; + int union_x, union_y; + int union_w, union_h; TPL_ASSERT(surface); TPL_ASSERT(surface->display); TPL_ASSERT(surface->display->native_handle); TPL_ASSERT(tbm_surface); - TPL_IGNORE(num_rects); - TPL_IGNORE(rects); if (!tbm_surface_internal_is_valid(tbm_surface)) { TPL_ERR("Failed to enqueue tbm_surface(%p) Invalid value.", tbm_surface); @@ -566,6 +567,51 @@ __tpl_tbm_surface_enqueue_buffer(tpl_surface_t *surface, close(sync_fence); } + /* If there are given damage rects for given tbm_surface, */ + if (num_rects != 0 && rects != NULL) { + int i; + int left = surface->width; + int bottom = surface->height; + int right = 0, top = 0; + + /* Carculate the union region of given damage rectangles */ + for (i = 0; i < num_rects; i++) { + int rect_i = i * 4; + int x = rects[rect_i]; + int y = rects[rect_i + 1]; + int w = rects[rect_i + 2]; + int h = rects[rect_i + 3]; + + left = (x < left) ? x : left; + bottom = (y < bottom) ? y : bottom; + right = ((x + w) > right) ? (x + w) : right; + top = ((y + h) > top) ? (y + h) : top; + } + + /* Calibrate so as not to exceed the range. */ + left = (left < 0) ? 0 : left; + bottom = (bottom < 0) ? 0 : bottom; + right = (right > surface->width) ? surface->width : right; + top = (top > surface->height) ? surface->height : top; + + /* And set its union rect to tbm_surface as its damage region. */ + union_w = right - left; + union_h = top - bottom; + union_x = left; + union_y = top; + } else { + /* If there are no any damage rects, + * set its full size of surface as its damage region. */ + union_w = surface->width; + union_h = surface->height; + union_x = 0; + union_y = 0; + } + + if (!(ret = tbm_surface_internal_set_damage(tbm_surface, union_x, union_y, + union_w, union_h))) + TPL_WARN("Failed to set damage rect to tbm_surface(%p)", tbm_surface); + if (tbm_surface_queue_enqueue(tbm_queue, tbm_surface) != TBM_SURFACE_QUEUE_ERROR_NONE) { TPL_ERR("tbm_surface_queue_enqueue failed. tbm_queue(%p) tbm_surface(%p)", -- 2.7.4 From 42495fb65daba3448613e56c428e8b912a3e4732 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 20 Jun 2018 14:15:54 +0900 Subject: [PATCH 07/16] Package version up to 1.5.8 Change-Id: I5645a89b3636c3e4a2a586356aa82e5e101f070f 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 46b186e..3e732eb 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 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 04192aa4eb0ee6405fbc7f84e20b1fd4794fa163 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Mon, 18 Jun 2018 11:48:31 +0900 Subject: [PATCH 08/16] tpl_tbm: Added checking codes to choice tbm backend with dummy_dpy. Change-Id: If9a894414e042c904b3704c76354bffd3ac305f6 Signed-off-by: joonbum.ko --- src/tpl_tbm.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tpl_tbm.c b/src/tpl_tbm.c index 9b258f0..aeb8f14 100644 --- a/src/tpl_tbm.c +++ b/src/tpl_tbm.c @@ -8,6 +8,7 @@ #include #include #include +#include #include "tpl_worker_thread.h" #include @@ -761,6 +762,9 @@ __tpl_display_choose_backend_tbm(tpl_handle_t native_dpy) if (!native_dpy) return TPL_FALSE; + if (tbm_dummy_display_is_valid((tbm_dummy_display *)native_dpy)) + return TPL_TRUE; + bufmgr = tbm_bufmgr_init(-1); if (bufmgr == (tbm_bufmgr)native_dpy) ret = TPL_TRUE; -- 2.7.4 From 2c1438ffc8e6d7c6fa66283c54a54e9c5bf84089 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 21 Jun 2018 17:11:41 +0900 Subject: [PATCH 09/16] Package version up to 1.5.9 Change-Id: Idba23788b1d947942da3124d3f5e44a9525697c4 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 3e732eb..72c2647 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 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 c2cfe702bada6df62c1681b4df36632d271fd2e1 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Tue, 26 Jun 2018 13:47:10 +0900 Subject: [PATCH 10/16] tpl_wayland_egl: Set need_to_release flag to FALSE to skip release procedure. - When flush_callback is called, the buffers in the attached_buffers list will be invalid, so they do not need to be handled by release_callback. Change-Id: I7418cf4db8e3906c3088b859bfe806fca11101b6 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index d4d1ecd..cf5ddf9 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -1677,9 +1677,14 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, tbm_surface_queue_error_e tsq_err; tbm_surface_h tbm_surface = __tpl_list_pop_front(wayland_egl_surface->attached_buffers, NULL); - TRACE_ASYNC_END((int)tbm_surface, "[COMMIT ~ RELEASE_CB] BO_NAME:%d", - tbm_bo_export(tbm_surface_internal_get_bo( - tbm_surface, 0))); + tpl_wayland_egl_buffer_t *wayland_egl_buffer = + __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface); + if (wayland_egl_buffer) { + /* This buffer does not need to processed at release_callback. + * It will be invalid buffer */ + wayland_egl_buffer->need_to_release = TPL_FALSE; + } + tbm_surface_internal_unref(tbm_surface); tsq_err = tbm_surface_queue_release(wayland_egl_surface->tbm_queue, tbm_surface); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) -- 2.7.4 From 2586535c5a576943dd8a35eec4c4f8bed865a9f2 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Wed, 4 Jul 2018 09:16:56 +0900 Subject: [PATCH 11/16] tpl_surface: Added a new frontend API to set the number of desired buffers. - New API below. tpl_surface_t * tpl_surface_create_with_num_buffers(tpl_display_t *display, tpl_handle_t handle, tpl_surface_type_t type, tbm_format format, int num_buffers); Create a TPL surface for the given native surface(handle) with the number of desired buffers. This API is the same as tpl_surface_create() except that it can specify the number of buffers. Change-Id: I1b0808da436906cd0a14568cd796f184b4343746 Signed-off-by: joonbum.ko --- src/tpl.h | 21 ++++++++++++++++++ src/tpl_internal.h | 4 ++++ src/tpl_surface.c | 52 +++++++++++++++++++++++++++++++++++++++----- src/tpl_wayland_egl.c | 18 +++++---------- src/tpl_wayland_egl_thread.c | 8 +++---- src/tpl_wayland_egl_thread.h | 2 +- src/tpl_wl_egl_thread.c | 2 +- src/tpl_wl_vk_thread.c | 2 +- 8 files changed, 83 insertions(+), 26 deletions(-) diff --git a/src/tpl.h b/src/tpl.h index 27a3ba9..3c6b70b 100644 --- a/src/tpl.h +++ b/src/tpl.h @@ -391,10 +391,31 @@ tpl_display_get_backend_type(tpl_handle_t native_dpy); * @param format Pixel format of the surface. * @return Created surface on success, NULL otherwise. */ + tpl_surface_t * tpl_surface_create(tpl_display_t *display, tpl_handle_t handle, tpl_surface_type_t type, tbm_format format); + +/** + * Create a TPL surface for the given native surface(handle) + * with the number of desired buffers. + * This API is the same as tpl_surface_create() except that + * it can specify the number of buffers. + * + * @param display display used for surface creation. + * @param handle Handle to the native surface. + * @param type Type of the surface (Window or Pixmap). + * @param format Pixel format of the surface. + * @param num_buffers The numbuer of desired buffers. + * @return Created surface on success, NULL otherwise. + * */ +tpl_surface_t * +tpl_surface_create_with_num_buffers(tpl_display_t *display, tpl_handle_t handle, + tpl_surface_type_t type, tbm_format format, + int num_buffers); + + /** * Get TPL surface object for the given native surface. * diff --git a/src/tpl_internal.h b/src/tpl_internal.h index d8f037d..4d1d45d 100644 --- a/src/tpl_internal.h +++ b/src/tpl_internal.h @@ -48,6 +48,9 @@ #define TPL_OBJECT_TYPE_CHECK(x, tp) do {if ((TPL_OBJECT(x)->type) != (tpl_object_type_t)(tp)) { TPL_ERR("Object type check failed"); return;} } while (0) #define TPL_OBJECT_TYPE_CHECK_RETURN(x, tp, ret) do {if ((TPL_OBJECT(x)->type) != (tpl_object_type_t)(tp)) { TPL_ERR("Object type check failed"); return ret;} } while (0) +#define TPL_SURFACE_MIN_BUFFER_COUNT 2 +#define TPL_SURFACE_DEFAULT_BUFFER_COUNT 3 + typedef struct _tpl_runtime tpl_runtime_t; typedef struct _tpl_display_backend tpl_display_backend_t; typedef struct _tpl_surface_backend tpl_surface_backend_t; @@ -139,6 +142,7 @@ struct _tpl_surface { int rotation; int post_interval; int dump_count; + int num_buffers; tpl_bool_t rotation_capability; tpl_surface_backend_t backend; diff --git a/src/tpl_surface.c b/src/tpl_surface.c index 437ec02..9c281ac 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -19,12 +19,12 @@ __tpl_surface_free(void *data) free(data); } -tpl_surface_t * -tpl_surface_create(tpl_display_t *display, tpl_handle_t handle, - tpl_surface_type_t type, tbm_format format) +static tpl_surface_t * +__tpl_surface_internal_create(tpl_display_t *display, tpl_handle_t handle, + tpl_surface_type_t type, tbm_format format, + int num_buffers) { tpl_surface_t *surface = NULL; - tpl_result_t ret = TPL_ERROR_NONE; if (!display) { TPL_ERR("Display is NULL!"); @@ -36,6 +36,11 @@ tpl_surface_create(tpl_display_t *display, tpl_handle_t handle, return NULL; } + if (num_buffers < TPL_SURFACE_MIN_BUFFER_COUNT) { + TPL_ERR("num_buffers(%d) must be >= 2", num_buffers); + return NULL; + } + surface = (tpl_surface_t *) calloc(1, sizeof(tpl_surface_t)); if (!surface) { TPL_ERR("Failed to allocate memory for surface!"); @@ -57,6 +62,7 @@ tpl_surface_create(tpl_display_t *display, tpl_handle_t handle, surface->post_interval = 1; surface->dump_count = 0; + surface->num_buffers = num_buffers; /* Intialize backend. */ __tpl_surface_init_backend(surface, display->backend.type); @@ -74,6 +80,7 @@ tpl_surface_create(tpl_display_t *display, tpl_handle_t handle, * for supporting oldSwapchain. */ if (tpl_surface_get(display, handle) == NULL) { + tpl_result_t ret = TPL_ERROR_NONE; /* Add it to the runtime. */ ret = __tpl_runtime_add_surface(surface); if (ret != TPL_ERROR_NONE) { @@ -83,8 +90,41 @@ tpl_surface_create(tpl_display_t *display, tpl_handle_t handle, } } - TPL_LOG_F("tpl_display_t(%p) tpl_surface_t(%p) native_handle(%p) format(%d)", - display, surface, handle, format); + return surface; +} + +tpl_surface_t * +tpl_surface_create(tpl_display_t *display, tpl_handle_t handle, + tpl_surface_type_t type, tbm_format format) +{ + tpl_surface_t *surface = NULL; + + surface = __tpl_surface_internal_create(display, handle, + type, format, + TPL_SURFACE_DEFAULT_BUFFER_COUNT); + if (surface) { + TPL_LOG_F("tpl_display_t(%p) tpl_surface_t(%p) native_handle(%p) format(%d) num_buffers(%d)", + display, surface, handle, format, TPL_SURFACE_DEFAULT_BUFFER_COUNT); + } else + TPL_ERR("Failed to create tpl_surface with native window(%p)", handle); + return surface; +} + +tpl_surface_t * +tpl_surface_create_with_num_buffers(tpl_display_t *display, tpl_handle_t handle, + tpl_surface_type_t type, tbm_format format, + int num_buffers) +{ + tpl_surface_t *surface = NULL; + + surface = __tpl_surface_internal_create(display, handle, + type, format, + num_buffers); + if (surface) { + TPL_LOG_F("tpl_display_t(%p) tpl_surface_t(%p) native_handle(%p) format(%d)", + display, surface, handle, format, num_buffers); + } else + TPL_ERR("Failed to create tpl_surface with native window(%p)", handle); return surface; } diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index cf5ddf9..b2e5fbb 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -21,9 +21,6 @@ #include #include -/* In wayland, application and compositor create its own drawing buffers. Recommend size is more than 2. */ -#define CLIENT_QUEUE_SIZE 3 - typedef struct _tpl_wayland_egl_display tpl_wayland_egl_display_t; typedef struct _tpl_wayland_egl_surface tpl_wayland_egl_surface_t; typedef struct _tpl_wayland_egl_buffer tpl_wayland_egl_buffer_t; @@ -527,14 +524,14 @@ __tpl_wayland_egl_surface_init(tpl_surface_t *surface) wayland_egl_surface->tbm_queue = wayland_tbm_client_create_surface_queue( wayland_egl_display->wl_tbm_client, wl_egl_window->surface, - CLIENT_QUEUE_SIZE, + surface->num_buffers, wl_egl_window->width, wl_egl_window->height, surface->format); } else /*Why wl_surface is NULL ?*/ wayland_egl_surface->tbm_queue = tbm_surface_queue_sequence_create( - CLIENT_QUEUE_SIZE, + surface->num_buffers, wl_egl_window->width, wl_egl_window->height, surface->format, @@ -1677,14 +1674,9 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, tbm_surface_queue_error_e tsq_err; tbm_surface_h tbm_surface = __tpl_list_pop_front(wayland_egl_surface->attached_buffers, NULL); - tpl_wayland_egl_buffer_t *wayland_egl_buffer = - __tpl_wayland_egl_get_wayland_buffer_from_tbm_surface(tbm_surface); - if (wayland_egl_buffer) { - /* This buffer does not need to processed at release_callback. - * It will be invalid buffer */ - wayland_egl_buffer->need_to_release = TPL_FALSE; - } - + TRACE_ASYNC_END((int)tbm_surface, "[COMMIT ~ RELEASE_CB] BO_NAME:%d", + tbm_bo_export(tbm_surface_internal_get_bo( + tbm_surface, 0))); tbm_surface_internal_unref(tbm_surface); tsq_err = tbm_surface_queue_release(wayland_egl_surface->tbm_queue, tbm_surface); if (tsq_err != TBM_SURFACE_QUEUE_ERROR_NONE) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 14814bf..7a091aa 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -2081,7 +2081,7 @@ static tbm_surface_queue_h _twe_surface_create_tbm_queue(twe_wl_surf_source *source, struct wayland_tbm_client *wl_tbm_client, tpl_handle_t native_handle, - int format) + int format, int num_buffers) { tbm_surface_queue_h tbm_queue = NULL; struct wl_egl_window *wl_egl_window = (struct wl_egl_window *)native_handle; @@ -2095,7 +2095,7 @@ _twe_surface_create_tbm_queue(twe_wl_surf_source *source, tbm_queue = wayland_tbm_client_create_surface_queue( wl_tbm_client, wl_egl_window->surface, - CLIENT_QUEUE_SIZE, + num_buffers, wl_egl_window->width, wl_egl_window->height, format); @@ -2303,7 +2303,7 @@ twe_surface_h twe_surface_add(twe_thread* thread, twe_display_h twe_display, tpl_handle_t native_handle, - int format) + int format, int num_buffers) { twe_thread_context *ctx = thread->ctx; twe_wl_surf_source *source = NULL; @@ -2336,7 +2336,7 @@ twe_surface_add(twe_thread* thread, !(tbm_queue = _twe_surface_create_tbm_queue(source, disp_source->wl_tbm_client, native_handle, - format))) { + format, num_buffers))) { TPL_ERR("Failed to create tbm_surface_queue."); g_source_unref(&source->gsource); return NULL; diff --git a/src/tpl_wayland_egl_thread.h b/src/tpl_wayland_egl_thread.h index bd32f1d..4f7ba97 100644 --- a/src/tpl_wayland_egl_thread.h +++ b/src/tpl_wayland_egl_thread.h @@ -43,7 +43,7 @@ twe_surface_h twe_surface_add(twe_thread* thread, twe_display_h twe_display, tpl_handle_t native_handle, - int format); + int format, int num_buffers); tpl_result_t twe_surface_del(twe_surface_h twe_surface); diff --git a/src/tpl_wl_egl_thread.c b/src/tpl_wl_egl_thread.c index e4fa659..e9e463b 100644 --- a/src/tpl_wl_egl_thread.c +++ b/src/tpl_wl_egl_thread.c @@ -349,7 +349,7 @@ __tpl_wl_egl_surface_init(tpl_surface_t *surface) twe_surface = twe_surface_add(wayland_egl_display->wl_egl_thread, wayland_egl_display->twe_display, surface->native_handle, - surface->format); + surface->format, surface->num_buffers); if (!twe_surface) { TPL_ERR("Failed to add native_window(%p) to thread(%p)", surface->native_handle, wayland_egl_display->wl_egl_thread); diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 8e68f8d..09716c6 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -276,7 +276,7 @@ __tpl_wl_vk_wsi_surface_init(tpl_surface_t *surface) twe_surface = twe_surface_add(wayland_vk_wsi_display->wl_thread, wayland_vk_wsi_display->twe_display, surface->native_handle, - surface->format); + surface->format, surface->num_buffers); if (!twe_surface) { TPL_ERR("Failed to add native_surface(%p) to thread(%p)", surface->native_handle, wayland_vk_wsi_display->wl_thread); -- 2.7.4 From 75341e8f7c66be49c594b340ef7cd3a16a9f8b27 Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 5 Jul 2018 11:45:37 +0900 Subject: [PATCH 12/16] Package version up to 1.5.10 Change-Id: I0fc7edecc19d56079b0014417a4c2daf3c17c709 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 72c2647..442120d 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 9 +%define TPL_VERSION_PATCH 10 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From d6288bf9bd19a6ffef66171a7d6b04cc62674dfd Mon Sep 17 00:00:00 2001 From: yhji Date: Thu, 19 Jul 2018 18:10:17 +0900 Subject: [PATCH 13/16] Fix Wformat build error Change-Id: I52a171c0dc82fc5f6b5ed28b2bff01102b95bcd7 Signed-off-by: yhji --- src/tpl_surface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tpl_surface.c b/src/tpl_surface.c index 9c281ac..8c14e82 100644 --- a/src/tpl_surface.c +++ b/src/tpl_surface.c @@ -121,7 +121,7 @@ tpl_surface_create_with_num_buffers(tpl_display_t *display, tpl_handle_t handle, type, format, num_buffers); if (surface) { - TPL_LOG_F("tpl_display_t(%p) tpl_surface_t(%p) native_handle(%p) format(%d)", + TPL_LOG_F("tpl_display_t(%p) tpl_surface_t(%p) native_handle(%p) format(%d) num_buffers(%d)", display, surface, handle, format, num_buffers); } else TPL_ERR("Failed to create tpl_surface with native window(%p)", handle); -- 2.7.4 From 1b22c4216b6b745a01bb220a061632205afb1017 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Mon, 23 Jul 2018 14:43:33 +0900 Subject: [PATCH 14/16] Package version up to 1.5.11 Change-Id: I247df5594ceadb92f7a53d0bd6eefeb56b27cf15 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 442120d..cd74845 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 10 +%define TPL_VERSION_PATCH 11 %define TPL_VERSION %{TPL_VERSION_MAJOR}.%{TPL_VERSION_MINOR}.%{TPL_VERSION_PATCH} #TPL WINDOW SYSTEM DEFINITION -- 2.7.4 From a39d57611f9f64dcda6efe72fa6ed4ba54107f2e Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 25 Jul 2018 15:35:03 +0900 Subject: [PATCH 15/16] tpl_utils: Added internal util function to find node from given list with data. Change-Id: I5754db81f7edc27728d7b839985a124923671e6f Signed-off-by: Joonbum Ko --- src/tpl_utils.h | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/tpl_utils.h b/src/tpl_utils.h index 11aad8c..4237247 100644 --- a/src/tpl_utils.h +++ b/src/tpl_utils.h @@ -569,6 +569,52 @@ __tpl_list_insert(tpl_list_node_t *pos, void *data) return TPL_ERROR_NONE; } +static TPL_INLINE tpl_list_node_t * +__tpl_list_find_node(tpl_list_t *list, void *data, int occurrence, + tpl_free_func_t func) +{ + tpl_list_node_t *node = NULL; + tpl_list_node_t *res_node = NULL; + + TPL_ASSERT(list); + + if (occurrence == TPL_FIRST) { + node = list->head.next; + + while (node != &list->tail) { + tpl_list_node_t *curr; + + curr = node; + node = node->next; + + TPL_ASSERT(curr); + TPL_ASSERT(node); + + if (curr->data == data) { + res_node = curr; + } + } + } else if (occurrence == TPL_LAST) { + node = list->tail.prev; + + while (node != &list->head) { + tpl_list_node_t *curr; + + curr = node; + node = node->prev; + + TPL_ASSERT(curr); + TPL_ASSERT(node); + + if (curr->data == data) { + res_node = curr; + } + } + } + + return res_node; +} + static TPL_INLINE void __tpl_list_remove_data(tpl_list_t *list, void *data, int occurrence, tpl_free_func_t func) -- 2.7.4 From 5bedc776b5d4187eca392ee48b6c6badec849d9a Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Wed, 25 Jul 2018 15:40:09 +0900 Subject: [PATCH 16/16] tpl_wayland_egl: Modified to track committed wl_buffer using global list. - If more than one release event is processed for only once committed wl_buffer, the tbm_surface that should not be destroyed can be destroyed. - Save wl_buffer during from wl_surface_commit to wl_buffer_release to a global list called committed_wl_buffers to filter out unwanted release events. [The cases of the problem] 1. Multi-surfaces client. 2. client want to render in iconified status. Change-Id: I09ea2f0ba26b7066695971238d9bed003443e9e4 Signed-off-by: Joonbum Ko --- src/tpl_wayland_egl.c | 87 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 76 insertions(+), 11 deletions(-) diff --git a/src/tpl_wayland_egl.c b/src/tpl_wayland_egl.c index b2e5fbb..3dc6f43 100644 --- a/src/tpl_wayland_egl.c +++ b/src/tpl_wayland_egl.c @@ -66,6 +66,9 @@ struct _tpl_wayland_egl_buffer { struct wl_proxy *wl_proxy; /* wl_buffer proxy */ }; +static tpl_list_t *committed_wl_buffers = NULL; +static pthread_mutex_t g_list_mutex; + static const struct wl_buffer_listener buffer_release_listener; static int tpl_wayland_egl_buffer_key; @@ -201,6 +204,14 @@ __tpl_wayland_egl_display_init(tpl_display_t *display) goto free_wl_display; } + if (!committed_wl_buffers) { + committed_wl_buffers = __tpl_list_alloc(); + if (!committed_wl_buffers) + TPL_ERR("Failed to allocate committed_wl_buffers list."); + if (pthread_mutex_init(&g_list_mutex, NULL) != 0) + TPL_ERR("g_list_mutex init failed."); + } + wayland_egl_display->wl_dpy = wl_dpy; __tpl_wayland_egl_display_buffer_flusher_init(wayland_egl_display); @@ -285,6 +296,16 @@ __tpl_wayland_egl_display_fini(tpl_display_t *display) free(wayland_egl_display); } + if (pthread_mutex_lock(&g_list_mutex) == 0) { + if (committed_wl_buffers) + __tpl_list_free(committed_wl_buffers, NULL); + committed_wl_buffers = NULL; + pthread_mutex_unlock(&g_list_mutex); + } + + if (pthread_mutex_destroy(&g_list_mutex) != 0) + TPL_ERR("Failed to destroy g_list_mutex"); + display->backend.data = NULL; } @@ -606,9 +627,9 @@ add_reset_cb_fail: tbm_surface_queue_destroy(wayland_egl_surface->tbm_queue); wayland_egl_surface->tbm_queue = NULL; queue_create_fail: - __tpl_list_free(wayland_egl_surface->attached_buffers, NULL); -alloc_dequeue_buffers_fail: __tpl_list_free(wayland_egl_surface->dequeued_buffers, NULL); +alloc_dequeue_buffers_fail: + __tpl_list_free(wayland_egl_surface->attached_buffers, NULL); alloc_attached_buffers_fail: __tpl_object_fini(&wayland_egl_surface->base); tpl_object_init_fail: @@ -662,8 +683,8 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) /* When surface is destroyed, unreference tbm_surface which tracked by * the list of attached_buffers in order to free the created resources. * (tpl_wayland_egl_buffer_t or wl_buffer) */ + TPL_OBJECT_LOCK(&wayland_egl_surface->base); if (wayland_egl_surface->attached_buffers) { - TPL_OBJECT_LOCK(&wayland_egl_surface->base); while (!__tpl_list_is_empty(wayland_egl_surface->attached_buffers)) { tbm_surface_queue_error_e tsq_err; tbm_surface_h tbm_surface = @@ -680,8 +701,8 @@ __tpl_wayland_egl_surface_fini(tpl_surface_t *surface) __tpl_list_free(wayland_egl_surface->attached_buffers, NULL); wayland_egl_surface->attached_buffers = NULL; - TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); } + TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); @@ -842,12 +863,21 @@ __tpl_wayland_egl_surface_commit(tpl_surface_t *surface, wayland_egl_buffer->wl_proxy, wayland_egl_buffer->width, wayland_egl_buffer->height); + TPL_OBJECT_LOCK(&wayland_egl_surface->base); if (wayland_egl_surface->attached_buffers) { - TPL_OBJECT_LOCK(&wayland_egl_surface->base); /* Start tracking of this tbm_surface until release_cb called. */ __tpl_list_push_back(wayland_egl_surface->attached_buffers, (void *)tbm_surface); - TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); + } + TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); + + if (pthread_mutex_lock(&g_list_mutex) == 0) { + if (committed_wl_buffers) { + /* Start tracking of wl_buffer which is committed by this wayland_egl_surface */ + __tpl_list_push_back(committed_wl_buffers, + (void *)wayland_egl_buffer->wl_proxy); + } + pthread_mutex_unlock(&g_list_mutex); } /* TPL_WAIT_VBLANK = 1 */ @@ -1411,7 +1441,26 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) tbm_surface_h tbm_surface = NULL; tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; - TPL_ASSERT(data); + if (proxy && (pthread_mutex_lock(&g_list_mutex) == 0)) { + if (committed_wl_buffers) { + /* Look for the given wl_proxy in the global list(committed_wl_buffers), + * whether its release event has not been processed since wl_surface_commit + * with this wl_proxy */ + tpl_list_node_t *node = + __tpl_list_find_node(committed_wl_buffers, (void *)proxy, + TPL_FIRST, NULL); + + /* If the proxy can not be found in the committed_wl_buffers list, + * it has not been committed or has already been released. + * In this case, it is not an error, but the log will be printed. */ + if (!node) { + TPL_ERR("wl_buffer(%p) already has been released.", proxy); + pthread_mutex_unlock(&g_list_mutex); + return; + } + } + pthread_mutex_unlock(&g_list_mutex); + } tbm_surface = (tbm_surface_h) data; @@ -1432,13 +1481,13 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) if (wayland_egl_buffer->need_to_release) { wayland_egl_surface = wayland_egl_buffer->wayland_egl_surface; + TPL_OBJECT_LOCK(&wayland_egl_surface->base); if (wayland_egl_surface->attached_buffers) { - TPL_OBJECT_LOCK(&wayland_egl_surface->base); /* Stop tracking of this released tbm_surface. */ __tpl_list_remove_data(wayland_egl_surface->attached_buffers, (void *)tbm_surface, TPL_FIRST, NULL); - TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); } + TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); tsq_err = tbm_surface_queue_release(wayland_egl_surface->tbm_queue, tbm_surface); @@ -1449,12 +1498,22 @@ __cb_client_buffer_release_callback(void *data, struct wl_proxy *proxy) wayland_egl_buffer->need_to_release = TPL_FALSE; tbm_surface_internal_unref(tbm_surface); + + if (pthread_mutex_lock(&g_list_mutex) == 0) { + /* This wl_buffer should be removed from committed_wl_buffers list. */ + __tpl_list_remove_data(committed_wl_buffers, (void *)proxy, + TPL_FIRST, NULL); + pthread_mutex_unlock(&g_list_mutex); + } + } else { TPL_WARN("No need to release buffer | wl_buffer(%p) tbm_surface(%p) bo(%d)", proxy, tbm_surface, tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); } } + } else { + TPL_ERR("Failed to process release_event. Invalid tbm_surface(%p)", tbm_surface); } } @@ -1668,8 +1727,9 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, * Then, client does not need to wait for release_callback to unreference * attached buffer. */ + + TPL_OBJECT_LOCK(&wayland_egl_surface->base); if (wayland_egl_surface->attached_buffers) { - TPL_OBJECT_LOCK(&wayland_egl_surface->base); while (!__tpl_list_is_empty(wayland_egl_surface->attached_buffers)) { tbm_surface_queue_error_e tsq_err; tbm_surface_h tbm_surface = @@ -1683,7 +1743,12 @@ static void __cb_tizen_surface_shm_flusher_flush_callback(void *data, TPL_ERR("Failed to release. tbm_surface(%p) tsq_err(%d)", tbm_surface, tsq_err); } - TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); + } + TPL_OBJECT_UNLOCK(&wayland_egl_surface->base); + + if (pthread_mutex_lock(&g_list_mutex) == 0) { + __tpl_list_fini(committed_wl_buffers, NULL); + pthread_mutex_unlock(&g_list_mutex); } if (lock_res == 0) pthread_mutex_unlock(&wayland_egl_display->wl_event_mutex); -- 2.7.4