From e142edc633335129f6d00b452a7cd3730c331d44 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Thu, 13 Sep 2018 18:47:35 +0900 Subject: [PATCH] tpl_vk_wsi_thread: Increased the ref_cnt of swapchain_buffers. - vulkan-wsi-tizen creates vkImage(s) from the swapchain_buffers obtained from the tpl_surface_get_swapchain_buffers() API. - If the queue_reset occurs in the event thread, then swapchain_buffers that have already been acquired by wsi will be destroyed, which can cause problems. - Therefore, even if queue_reset occurs in event_thread, TPL must increase ref_cnt of swapchain_buffers so that it is valid until swapchain is destroyed. Change-Id: Ibe41f212a64da89dbc30ea3f137f44dab187eb50 Signed-off-by: Joonbum Ko --- src/tpl_wl_vk_thread.c | 57 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index 5db9ec7..96ac5da 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -23,6 +23,7 @@ struct _tpl_wayland_vk_wsi_display { struct _tpl_wayland_vk_wsi_surface { twe_surface_h twe_surface; tbm_surface_queue_h tbm_queue; + tbm_surface_h *swapchain_buffers; int buffer_count; tpl_bool_t is_activated; tpl_bool_t reset; @@ -287,6 +288,7 @@ __tpl_wl_vk_wsi_surface_init(tpl_surface_t *surface) wayland_vk_wsi_surface->twe_surface = twe_surface; wayland_vk_wsi_surface->is_activated = TPL_FALSE; + wayland_vk_wsi_surface->swapchain_buffers = NULL; TPL_LOG_T("WL_VK", "[INIT]tpl_surface(%p) tpl_wayland_vk_wsi_surface(%p) twe_surface(%p)", @@ -314,6 +316,11 @@ __tpl_wl_vk_wsi_surface_fini(tpl_surface_t *surface) if (wayland_vk_wsi_surface->tbm_queue) __tpl_wl_vk_wsi_surface_destroy_swapchain(surface); + if (wayland_vk_wsi_surface->swapchain_buffers) { + free(wayland_vk_wsi_surface->swapchain_buffers); + wayland_vk_wsi_surface->swapchain_buffers = NULL; + } + TPL_LOG_T("WL_VK", "[FINI] wayland_vk_wsi_surface(%p) native_surface(%p) twe_surface(%p)", wayland_vk_wsi_surface, surface->native_handle, @@ -520,7 +527,6 @@ __tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, tbm_surface_h **buffers, int *buffer_count) { - tbm_surface_h *swapchain_buffers = NULL; tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display = NULL; int i; @@ -534,9 +540,10 @@ __tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, TPL_ASSERT(buffer_count); wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *)surface->backend.data; - swapchain_buffers = (tbm_surface_h *)calloc( - wayland_vk_wsi_surface->buffer_count, sizeof(tbm_surface_h)); - if (!swapchain_buffers) { + wayland_vk_wsi_surface->swapchain_buffers = (tbm_surface_h *)calloc( + wayland_vk_wsi_surface->buffer_count, + sizeof(tbm_surface_h)); + if (!wayland_vk_wsi_surface->swapchain_buffers) { TPL_ERR("Failed to allocate memory for buffers."); return TPL_ERROR_OUT_OF_MEMORY; } @@ -545,22 +552,27 @@ __tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, if (twe_display_lock(wayland_vk_wsi_display->twe_display) == TPL_ERROR_NONE) { ret = twe_surface_get_swapchain_buffers(wayland_vk_wsi_surface->twe_surface, - swapchain_buffers, buffer_count); + wayland_vk_wsi_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; + free(wayland_vk_wsi_surface->swapchain_buffers); + wayland_vk_wsi_surface->swapchain_buffers = NULL; + twe_display_unlock(wayland_vk_wsi_display->twe_display); return ret; } 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))); + i, wayland_vk_wsi_surface->swapchain_buffers[i], + tbm_bo_export(tbm_surface_internal_get_bo( + wayland_vk_wsi_surface->swapchain_buffers[i], 0))); + tbm_surface_internal_ref(wayland_vk_wsi_surface->swapchain_buffers[i]); } - *buffers = swapchain_buffers; + + *buffers = wayland_vk_wsi_surface->swapchain_buffers; twe_display_unlock(wayland_vk_wsi_display->twe_display); } @@ -645,6 +657,18 @@ __tpl_wl_vk_wsi_surface_create_swapchain(tpl_surface_t *surface, __tpl_util_atomic_inc(&wayland_vk_wsi_surface->swapchain_reference); + if (wayland_vk_wsi_surface->swapchain_buffers) { + int i; + for (i = 0; i < wayland_vk_wsi_surface->buffer_count; i++) { + TPL_DEBUG("unref tbm_surface(%p)", wayland_vk_wsi_surface->swapchain_buffers[i]); + tbm_surface_internal_unref(wayland_vk_wsi_surface->swapchain_buffers[i]); + wayland_vk_wsi_surface->swapchain_buffers[i] = NULL; + } + + free(wayland_vk_wsi_surface->swapchain_buffers); + wayland_vk_wsi_surface->swapchain_buffers = NULL; + } + 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); @@ -715,6 +739,19 @@ __tpl_wl_vk_wsi_surface_destroy_swapchain(tpl_surface_t *surface) return TPL_ERROR_NONE; } + if (wayland_vk_wsi_surface->swapchain_buffers) { + int i; + for (i = 0; i < wayland_vk_wsi_surface->buffer_count; i++) { + TPL_DEBUG("Stop tracking tbm_surface(%p)", + wayland_vk_wsi_surface->swapchain_buffers[i]); + tbm_surface_internal_unref(wayland_vk_wsi_surface->swapchain_buffers[i]); + wayland_vk_wsi_surface->swapchain_buffers[i] = NULL; + } + + free(wayland_vk_wsi_surface->swapchain_buffers); + wayland_vk_wsi_surface->swapchain_buffers = NULL; + } + res = twe_surface_destroy_swapchain(wayland_vk_wsi_surface->twe_surface); if (res != TPL_ERROR_NONE) { TPL_ERR("Failed to destroy swapchain. twe_surface(%p)", -- 2.7.4