From: Joonbum Ko Date: Fri, 9 Apr 2021 05:24:31 +0000 (+0900) Subject: Implement swapchain create/destroy/get_swapchain_buffers. X-Git-Tag: submit/tizen/20210504.031804~13 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2b3e45de48873051c66365b2df997411b4019a21;p=platform%2Fcore%2Fuifw%2Flibtpl-egl.git Implement swapchain create/destroy/get_swapchain_buffers. Change-Id: Ic6b07b8247230409808db35ec308dbee2df5861c Signed-off-by: Joonbum Ko --- diff --git a/src/tpl_wl_vk_thread.c b/src/tpl_wl_vk_thread.c index fceee7e..caa2ce2 100644 --- a/src/tpl_wl_vk_thread.c +++ b/src/tpl_wl_vk_thread.c @@ -169,8 +169,16 @@ struct _tpl_wl_vk_buffer { tpl_wl_vk_surface_t *wl_vk_surface; }; -static tpl_result_t __tpl_wl_vk_wsi_surface_destroy_swapchain( - tpl_surface_t *surface); +static void +_print_buffer_lists(tpl_wl_vk_surface_t *wl_vk_surface); +static int +_get_tbm_surface_bo_name(tbm_surface_h tbm_surface); +static void +__cb_wl_vk_buffer_free(tpl_wl_vk_buffer_t *wl_vk_buffer); +static tpl_result_t +_thread_swapchain_create_tbm_queue(tpl_wl_vk_surface_t *wl_vk_surface); +static void +_thread_swapchain_destroy_tbm_queue(tpl_wl_vk_surface_t *wl_vk_surface); static tpl_bool_t _check_native_handle_is_wl_display(tpl_handle_t native_dpy) @@ -214,7 +222,7 @@ __thread_func_tdm_dispatch(tpl_gsource *gsource, uint64_t message) /* If an error occurs in tdm_client_handle_events, it cannot be recovered. * When tdm_source is no longer available due to an unexpected situation, - * wl_egl_thread must remove it from the thread and destroy it. + * wl_vk_thread must remove it from the thread and destroy it. * In that case, tdm_vblank can no longer be used for surfaces and displays * that used this tdm_source. */ if (tdm_err != TDM_ERROR_NONE) { @@ -434,7 +442,7 @@ _thread_wl_display_init(tpl_wl_vk_display_t *wl_vk_display) if (wl_vk_display->explicit_sync) { wl_proxy_set_queue((struct wl_proxy *)wl_vk_display->explicit_sync, wl_vk_display->ev_queue); - TPL_LOG_T("WL_EGL", "zwp_linux_explicit_synchronization_v1(%p) init.", + TPL_LOG_T("WL_VK", "zwp_linux_explicit_synchronization_v1(%p) init.", wl_vk_display->explicit_sync); } @@ -626,7 +634,7 @@ __thread_func_disp_finalize(tpl_gsource *gsource) if (wl_vk_display->wl_initialized) _thread_wl_display_fini(wl_vk_display); - TPL_LOG_T("WL_EGL", "finalize| wl_vk_display(%p) tpl_gsource(%p)", + TPL_LOG_T("WL_VK", "finalize| wl_vk_display(%p) tpl_gsource(%p)", wl_vk_display, gsource); return; @@ -697,11 +705,11 @@ __tpl_wl_vk_wsi_display_init(tpl_display_t *display) tpl_gmutex_init(&wl_vk_display->wl_event_mutex); /* Create gthread */ - wl_vk_display->thread = tpl_gthread_create("wl_egl_thread", + wl_vk_display->thread = tpl_gthread_create("wl_vk_thread", (tpl_gthread_func)_thread_init, (void *)wl_vk_display); if (!wl_vk_display->thread) { - TPL_ERR("Failed to create wl_egl_thread"); + TPL_ERR("Failed to create wl_vk_thread"); goto free_display; } @@ -1092,7 +1100,11 @@ __thread_func_surf_dispatch(tpl_gsource *gsource, uint64_t message) tpl_gmutex_lock(&wl_vk_surface->surf_mutex); TPL_DEBUG("wl_vk_surface(%p) queue creation message received!", wl_vk_surface); - + if (_thread_swapchain_create_tbm_queue(wl_vk_surface) + != TPL_ERROR_NONE) { + TPL_ERR("Failed to create tbm_queue. wl_vk_surface(%p)", + wl_vk_surface); + } tpl_gcond_signal(&wl_vk_surface->surf_cond); tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); } else if (message == 3) { /* Acquirable message */ @@ -1105,7 +1117,7 @@ __thread_func_surf_dispatch(tpl_gsource *gsource, uint64_t message) tpl_gmutex_lock(&wl_vk_surface->surf_mutex); TPL_DEBUG("wl_vk_surface(%p) swapchain destroy message received!", wl_vk_surface); - + _thread_swapchain_destroy_tbm_queue(wl_vk_surface); tpl_gcond_signal(&wl_vk_surface->surf_cond); tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); } @@ -1259,28 +1271,453 @@ __tpl_wl_vk_wsi_surface_fini(tpl_surface_t *surface) surface->backend.data = NULL; } +static void +__cb_tbm_queue_reset_callback(tbm_surface_queue_h tbm_queue, + void *data) +{ + tpl_wl_vk_surface_t *wl_vk_surface = NULL; + tpl_wl_vk_display_t *wl_vk_display = NULL; + tpl_wl_vk_swapchain_t *swapchain = NULL; + tpl_surface_t *surface = NULL; + tpl_bool_t is_activated = TPL_FALSE; + int width, height; + + wl_vk_surface = (tpl_wl_vk_surface_t *)data; + TPL_CHECK_ON_NULL_RETURN(wl_vk_surface); + + wl_vk_display = wl_vk_surface->wl_vk_display; + TPL_CHECK_ON_NULL_RETURN(wl_vk_display); + + surface = wl_vk_surface->tpl_surface; + TPL_CHECK_ON_NULL_RETURN(surface); + + swapchain = wl_vk_surface->swapchain; + TPL_CHECK_ON_NULL_RETURN(swapchain); + + /* When the queue is resized, change the reset flag to TPL_TRUE to reflect + * the changed window size at the next frame. */ + width = tbm_surface_queue_get_width(tbm_queue); + height = tbm_surface_queue_get_height(tbm_queue); + if (surface->width != width || surface->height != height) { + TPL_INFO("[QUEUE_RESIZE]", + "wl_vk_surface(%p) tbm_queue(%p) (%dx%d) -> (%dx%d)", + wl_vk_surface, tbm_queue, + surface->width, surface->height, width, height); + } + + /* When queue_reset_callback is called, if is_activated is different from + * its previous state change the reset flag to TPL_TRUE to get a new buffer + * with the changed state(ACTIVATED/DEACTIVATED) at the next frame. */ + is_activated = wayland_tbm_client_queue_check_activate(wl_vk_display->wl_tbm_client, + swapchain->tbm_queue); + if (wl_vk_surface->is_activated != is_activated) { + if (is_activated) { + TPL_INFO("[ACTIVATED]", + "wl_vk_surface(%p) wl_surface(%p) tbm_queue(%p)", + wl_vk_surface, wl_vk_surface->wl_surface, tbm_queue); + } else { + TPL_LOG_T("[DEACTIVATED]", + " wl_vk_surface(%p) wl_surface(%p) tbm_queue(%p)", + wl_vk_surface, wl_vk_surface->wl_surface, tbm_queue); + } + } + + wl_vk_surface->reset = TPL_TRUE; + + if (surface->reset_cb) + surface->reset_cb(surface->reset_data); +} + +static void +__cb_tbm_queue_acquirable_callback(tbm_surface_queue_h tbm_queue, + void *data) +{ + TPL_IGNORE(tbm_queue); + + tpl_wl_vk_surface_t *wl_vk_surface = (tpl_wl_vk_surface_t *)data; + TPL_CHECK_ON_NULL_RETURN(wl_vk_surface); + + tpl_gmutex_lock(&wl_vk_surface->surf_mutex); + + tpl_gsource_send_message(wl_vk_surface->surf_source, 3); + + tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); +} + static tpl_result_t -__tpl_wl_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, - tbm_surface_h tbm_surface, - int num_rects, const int *rects, - tbm_fd sync_fence) +_thread_swapchain_create_tbm_queue(tpl_wl_vk_surface_t *wl_vk_surface) +{ + TPL_ASSERT (wl_vk_surface); + + tpl_wl_vk_display_t *wl_vk_display = wl_vk_surface->wl_vk_display; + tpl_wl_vk_swapchain_t *swapchain = wl_vk_surface->swapchain; + tbm_surface_queue_h tbm_queue = NULL; + tbm_bufmgr bufmgr = NULL; + unsigned int capability; + + TPL_CHECK_ON_NULL_RETURN_VAL(wl_vk_display, TPL_ERROR_INVALID_PARAMETER); + TPL_CHECK_ON_NULL_RETURN_VAL(swapchain, TPL_ERROR_INVALID_PARAMETER); + + if (swapchain->properties.buffer_count < wl_vk_display->min_buffer) { + TPL_ERR("buffer count(%d) must be higher than (%d)", + swapchain->properties.buffer_count, + wl_vk_display->min_buffer); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (swapchain->properties.buffer_count > wl_vk_display->max_buffer) { + TPL_ERR("buffer count(%d) must be lower than (%d)", + swapchain->properties.buffer_count, + wl_vk_display->max_buffer); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (!(swapchain->properties.present_mode & wl_vk_display->present_modes)) { + TPL_ERR("Unsupported present_mode(%d)", + swapchain->properties.present_mode); + return TPL_ERROR_INVALID_PARAMETER; + } + + if (swapchain->tbm_queue) { + int old_width = tbm_surface_queue_get_width(swapchain->tbm_queue); + int old_height = tbm_surface_queue_get_height(swapchain->tbm_queue); + + if (swapchain->swapchain_buffers) { + int i; + for (i = 0; i < swapchain->properties.buffer_count; i++) { + if (swapchain->swapchain_buffers[i]) { + TPL_DEBUG("unref tbm_surface(%p)", swapchain->swapchain_buffers[i]); + tbm_surface_internal_unref(swapchain->swapchain_buffers[i]); + swapchain->swapchain_buffers[i] = NULL; + } + } + + free(swapchain->swapchain_buffers); + swapchain->swapchain_buffers = NULL; + } + + if (old_width != swapchain->properties.width || + old_height != swapchain->properties.height) { + tbm_surface_queue_reset(swapchain->tbm_queue, + swapchain->properties.width, + swapchain->properties.height, + swapchain->properties.format); + TPL_INFO("[RESIZE]", + "wl_vk_surface(%p) swapchain(%p) tbm_queue(%p) (%dx%d)->(%dx%d)", + wl_vk_surface, swapchain, swapchain->tbm_queue, + old_width, old_height, + swapchain->properties.width, + swapchain->properties.height); + } + + swapchain->properties.buffer_count = + tbm_surface_queue_get_size(swapchain->tbm_queue); + + wl_vk_surface->reset = TPL_FALSE; + + __tpl_util_atomic_inc(&swapchain->ref_cnt); + + TPL_INFO("[SWAPCHAIN_REUSE]", + "wl_vk_surface(%p) swapchain(%p) tbm_queue(%p) buffer_count(%d)", + wl_vk_surface, swapchain, swapchain->tbm_queue, + swapchain->properties.buffer_count); + + return TPL_ERROR_NONE; + } + + bufmgr = tbm_bufmgr_init(-1); + capability = tbm_bufmgr_get_capability(bufmgr); + tbm_bufmgr_deinit(bufmgr); + + if (capability & TBM_BUFMGR_CAPABILITY_TILED_MEMORY) { + tbm_queue = wayland_tbm_client_create_surface_queue_tiled( + wl_vk_display->wl_tbm_client, + wl_vk_surface->wl_surface, + swapchain->properties.buffer_count, + swapchain->properties.width, + swapchain->properties.height, + TBM_FORMAT_ARGB8888); + } else { + tbm_queue = wayland_tbm_client_create_surface_queue( + wl_vk_display->wl_tbm_client, + wl_vk_surface->wl_surface, + swapchain->properties.buffer_count, + swapchain->properties.width, + swapchain->properties.height, + TBM_FORMAT_ARGB8888); + } + + if (!tbm_queue) { + TPL_ERR("Failed to create tbm_queue. wl_vk_surface(%p)", + wl_vk_surface); + return TPL_ERROR_OUT_OF_MEMORY; + } + + if (tbm_surface_queue_set_modes( + tbm_queue, TBM_SURFACE_QUEUE_MODE_GUARANTEE_CYCLE) != + TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to set queue mode to tbm_surface_queue(%p)", + tbm_queue); + tbm_surface_queue_destroy(tbm_queue); + return TPL_ERROR_INVALID_OPERATION; + } + + if (tbm_surface_queue_add_reset_cb( + tbm_queue, + __cb_tbm_queue_reset_callback, + (void *)wl_vk_surface) != 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); + return TPL_ERROR_INVALID_OPERATION; + } + + if (tbm_surface_queue_add_acquirable_cb( + tbm_queue, + __cb_tbm_queue_acquirable_callback, + (void *)wl_vk_surface) != TBM_SURFACE_QUEUE_ERROR_NONE) { + TPL_ERR("Failed to register acquirable callback to tbm_surface_queue(%p)", + tbm_queue); + tbm_surface_queue_destroy(tbm_queue); + return TPL_ERROR_INVALID_OPERATION; + } + + swapchain->tbm_queue = tbm_queue; + + TPL_INFO("[TBM_QUEUE_CREATED]", + "wl_vk_surface(%p) wl_vk_swapchain(%p) tbm_queue(%p)", + wl_vk_surface, swapchain, tbm_queue); + + return TPL_ERROR_NONE; +} + +static tpl_result_t +__tpl_wl_vk_wsi_surface_create_swapchain(tpl_surface_t *surface, + tbm_format format, int width, + int height, int buffer_count, int present_mode) +{ + tpl_wl_vk_surface_t *wl_vk_surface = NULL; + tpl_wl_vk_display_t *wl_vk_display = NULL; + tpl_wl_vk_swapchain_t *swapchain = NULL; + tpl_result_t res = TPL_ERROR_NONE; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->display); + + wl_vk_surface = (tpl_wl_vk_surface_t *)surface->backend.data; + TPL_CHECK_ON_NULL_RETURN_VAL(wl_vk_surface, TPL_ERROR_INVALID_PARAMETER); + + wl_vk_display = (tpl_wl_vk_display_t *) + surface->display->backend.data; + TPL_CHECK_ON_NULL_RETURN_VAL(wl_vk_display, TPL_ERROR_INVALID_PARAMETER); + + swapchain = wl_vk_surface->swapchain; + + if (swapchain == NULL) { + swapchain = + (tpl_wl_vk_swapchain_t *)calloc(1, sizeof(tpl_wl_vk_swapchain_t)); + TPL_CHECK_ON_NULL_RETURN_VAL(swapchain, TPL_ERROR_OUT_OF_MEMORY); + swapchain->tbm_queue = NULL; + } + + swapchain->properties.buffer_count = buffer_count; + swapchain->properties.width = width; + swapchain->properties.height = height; + swapchain->properties.present_mode = present_mode; + swapchain->wl_vk_surface = wl_vk_surface; + + wl_vk_surface->swapchain = swapchain; + + tpl_gmutex_lock(&wl_vk_surface->surf_mutex); + /* send swapchain create tbm_queue message */ + tpl_gsource_send_message(wl_vk_surface->surf_source, 2); + tpl_gcond_wait(&wl_vk_surface->surf_cond, &wl_vk_surface->surf_mutex); + tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); + + TPL_CHECK_ON_FALSE_ASSERT_FAIL( + swapchain->tbm_queue != NULL, + "[CRITICAL FAIL] Failed to create tbm_surface_queue"); + + wl_vk_surface->reset = TPL_FALSE; + + __tpl_util_atomic_set(&swapchain->ref_cnt, 1); + + return TPL_ERROR_NONE; +} + +static void +_thread_swapchain_destroy_tbm_queue(tpl_wl_vk_surface_t *wl_vk_surface) +{ + TPL_ASSERT(wl_vk_surface); + + tpl_wl_vk_swapchain_t *swapchain = wl_vk_surface->swapchain; + + TPL_CHECK_ON_NULL_RETURN(swapchain); + + if (swapchain->tbm_queue) { + TPL_INFO("[TBM_QUEUE_DESTROY]", + "wl_vk_surface(%p) swapchain(%p) tbm_queue(%p)", + wl_vk_surface, swapchain, swapchain->tbm_queue); + tbm_surface_queue_destroy(swapchain->tbm_queue); + swapchain->tbm_queue = NULL; + } +} + +static tpl_result_t +__tpl_wl_vk_wsi_surface_destroy_swapchain(tpl_surface_t *surface) { + tpl_wl_vk_swapchain_t *swapchain = NULL; + tpl_wl_vk_surface_t *wl_vk_surface = NULL; + tpl_wl_vk_display_t *wl_vk_display = NULL; + tpl_result_t res = TPL_ERROR_NONE; + unsigned int ref; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->display); + + wl_vk_surface = (tpl_wl_vk_surface_t *) surface->backend.data; + TPL_CHECK_ON_NULL_RETURN_VAL(wl_vk_surface, TPL_ERROR_INVALID_PARAMETER); + + wl_vk_display = (tpl_wl_vk_display_t *) surface->display->backend.data; + TPL_CHECK_ON_NULL_RETURN_VAL(wl_vk_display, TPL_ERROR_INVALID_PARAMETER); + + swapchain = wl_vk_surface->swapchain; + if (!swapchain) { + TPL_ERR("wl_vk_surface(%p)->swapchain is NULL. already destroyed.", + wl_vk_surface); + return TPL_ERROR_INVALID_OPERATION; + } + + if (__tpl_util_atomic_dec(&swapchain->ref_cnt) > 0) { + TPL_INFO("[DESTROY_SWAPCHAIN]", + "wl_vk_surface(%p) swapchain(%p) still valid.", + wl_vk_surface, swapchain); + return TPL_ERROR_NONE; + } + + TPL_INFO("[DESTROY_SWAPCHAIN][BEGIN]", + "wl_vk_surface(%p) swapchain(%p)", + wl_vk_surface, wl_vk_surface->swapchain); + + if (swapchain->swapchain_buffers) { + for (int i = 0; i < swapchain->properties.buffer_count; i++) { + if (swapchain->swapchain_buffers[i]) { + TPL_DEBUG("Stop tracking tbm_surface(%p)", + swapchain->swapchain_buffers[i]); + tbm_surface_internal_unref(swapchain->swapchain_buffers[i]); + swapchain->swapchain_buffers[i] = NULL; + } + } + + free(swapchain->swapchain_buffers); + swapchain->swapchain_buffers = NULL; + } + + _tpl_wl_vk_surface_buffer_clear(wl_vk_surface); + + tpl_gmutex_lock(&wl_vk_surface->surf_mutex); + tpl_gsource_send_message(wl_vk_surface->surf_source, 4); + tpl_gcond_wait(&wl_vk_surface->surf_cond, &wl_vk_surface->surf_mutex); + tpl_gmutex_unlock(&wl_vk_surface->surf_mutex); + + _print_buffer_lists(wl_vk_surface); + + free(swapchain); + wl_vk_surface->swapchain = NULL; + return TPL_ERROR_NONE; +} + +static tpl_result_t +__tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, + tbm_surface_h **buffers, + int *buffer_count) +{ TPL_ASSERT(surface); + TPL_ASSERT(surface->backend.data); TPL_ASSERT(surface->display); - TPL_ASSERT(surface->display->native_handle); - TPL_ASSERT(tbm_surface); + TPL_ASSERT(surface->display->backend.data); tpl_wl_vk_surface_t *wl_vk_surface = - (tpl_wl_vk_surface_t *) surface->backend.data; - tbm_surface_queue_error_e tsq_err; + (tpl_wl_vk_surface_t *)surface->backend.data; + tpl_wl_vk_display_t *wl_vk_display = + (tpl_wl_vk_display_t *)surface->display->backend.data; + tpl_wl_vk_swapchain_t *swapchain = wl_vk_surface->swapchain; + tpl_result_t ret = TPL_ERROR_NONE; + int i; - if (!tbm_surface_internal_is_valid(tbm_surface)) { - TPL_ERR("Failed to enqueue tbm_surface(%p) Invalid value.", - tbm_surface); - return TPL_ERROR_INVALID_PARAMETER; + TPL_CHECK_ON_NULL_RETURN_VAL(swapchain, TPL_ERROR_INVALID_PARAMETER); + TPL_CHECK_ON_NULL_RETURN_VAL(buffer_count, TPL_ERROR_INVALID_PARAMETER); + + tpl_gmutex_lock(&wl_vk_display->wl_event_mutex); + + if (!buffers) { + *buffer_count = tbm_surface_queue_get_size(swapchain->tbm_queue); + tpl_gmutex_unlock(&wl_vk_display->wl_event_mutex); + return TPL_ERROR_NONE; + } + + swapchain->swapchain_buffers = (tbm_surface_h *)calloc( + *buffer_count, + sizeof(tbm_surface_h)); + if (!swapchain->swapchain_buffers) { + TPL_ERR("Failed to allocate swapchain_buffers. buffer_count(%d)", + *buffer_count); + tpl_gmutex_unlock(&wl_vk_display->wl_event_mutex); + return TPL_ERROR_OUT_OF_MEMORY; + } + + ret = wayland_tbm_client_queue_get_surfaces(wl_vk_display->wl_tbm_client, + swapchain->tbm_queue, + swapchain->swapchain_buffers, + buffer_count); + if (!ret) { + TPL_ERR("Failed to get buffers from wl_tbm_client(%p) tbm_queue(%p)", + wl_vk_display->wl_tbm_client, swapchain->tbm_queue); + free(swapchain->swapchain_buffers); + swapchain->swapchain_buffers = NULL; + tpl_gmutex_unlock(&wl_vk_display->wl_event_mutex); + return TPL_ERROR_INVALID_OPERATION; + } + + for (i = 0; i < *buffer_count; i++) { + if (swapchain->swapchain_buffers[i]) { + TPL_DEBUG("swapchain_buffers[%d] = tbm_surface(%p) bo(%d)", + i, swapchain->swapchain_buffers[i], + _get_tbm_surface_bo_name(swapchain->swapchain_buffers[i])); + tbm_surface_internal_ref(swapchain->swapchain_buffers[i]); + } } + *buffers = swapchain->swapchain_buffers; + + tpl_gmutex_unlock(&wl_vk_display->wl_event_mutex); + + return TPL_ERROR_NONE; +} + +static tpl_result_t +__tpl_wl_vk_wsi_surface_enqueue_buffer(tpl_surface_t *surface, + tbm_surface_h tbm_surface, + int num_rects, const int *rects, + tbm_fd sync_fence) +{ + TPL_ASSERT(surface); + TPL_ASSERT(surface->backend.data); + + tpl_wl_vk_surface_t *wl_vk_surface = + (tpl_wl_vk_surface_t *) surface->backend.data; + tpl_wl_vk_swapchain_t *swapchain = wl_vk_surface->swapchain; + tbm_surface_queue_error_e tsq_err = TBM_SURFACE_QUEUE_ERROR_NONE; + int bo_name = -1; + + TPL_CHECK_ON_NULL_RETURN_VAL(swapchain, TPL_ERROR_INVALID_PARAMETER); + TPL_CHECK_ON_NULL_RETURN_VAL(tbm_surface, TPL_ERROR_INVALID_PARAMETER); + TPL_CHECK_ON_FALSE_RETURN_VAL(tbm_surface_internal_is_valid(tbm_surface), + TPL_ERROR_INVALID_PARAMETER); + + bo_name = _get_tbm_surface_bo_name(tbm_surface); + /* If there are received region information, * save it to buf_info in tbm_surface user_data using below API. */ if (num_rects && rects) { @@ -1442,265 +1879,6 @@ __tpl_wl_vk_wsi_surface_dequeue_buffer(tpl_surface_t *surface, return tbm_surface; } -static tpl_result_t -__tpl_wl_vk_wsi_surface_get_swapchain_buffers(tpl_surface_t *surface, - tbm_surface_h **buffers, - int *buffer_count) -{ - tpl_wl_vk_surface_t *wl_vk_surface = NULL; - tpl_wl_vk_display_t *wl_vk_display = NULL; - int i; - tpl_result_t ret = TPL_ERROR_NONE; - - TPL_ASSERT(surface); - TPL_ASSERT(surface->backend.data); - TPL_ASSERT(surface->display); - TPL_ASSERT(surface->display->backend.data); - TPL_ASSERT(buffers); - TPL_ASSERT(buffer_count); - - wl_vk_surface = (tpl_wl_vk_surface_t *)surface->backend.data; - wl_vk_display = (tpl_wl_vk_display_t *)surface->display->backend.data; - - if (twe_display_lock(wl_vk_display->twe_display) == TPL_ERROR_NONE) { - ret = twe_surface_get_swapchain_buffers(wl_vk_surface->twe_surface, - NULL, buffer_count); - if (ret != TPL_ERROR_NONE) { - TPL_ERR("Failed to get buffer_count. twe_surface(%p)", - wl_vk_surface->twe_surface); - twe_display_unlock(wl_vk_display->twe_display); - return ret; - } - - wl_vk_surface->swapchain_buffers = (tbm_surface_h *)calloc( - *buffer_count, - sizeof(tbm_surface_h)); - if (!wl_vk_surface->swapchain_buffers) { - TPL_ERR("Failed to allocate memory for buffers."); - twe_display_unlock(wl_vk_display->twe_display); - return TPL_ERROR_OUT_OF_MEMORY; - } - - ret = twe_surface_get_swapchain_buffers(wl_vk_surface->twe_surface, - wl_vk_surface->swapchain_buffers, - buffer_count); - if (ret != TPL_ERROR_NONE) { - TPL_ERR("Failed to get swapchain_buffers. wl_vk_surface(%p) twe_surface(%p)", - wl_vk_surface, wl_vk_surface->twe_surface); - free(wl_vk_surface->swapchain_buffers); - wl_vk_surface->swapchain_buffers = NULL; - twe_display_unlock(wl_vk_display->twe_display); - return ret; - } - - for (i = 0; i < *buffer_count; i++) { - if (wl_vk_surface->swapchain_buffers[i]) { - TPL_DEBUG("swapchain_buffers[%d] = tbm_surface(%p) bo(%d)", - i, wl_vk_surface->swapchain_buffers[i], - tbm_bo_export(tbm_surface_internal_get_bo( - wl_vk_surface->swapchain_buffers[i], 0))); - tbm_surface_internal_ref(wl_vk_surface->swapchain_buffers[i]); - } - } - - *buffers = wl_vk_surface->swapchain_buffers; - - twe_display_unlock(wl_vk_display->twe_display); - } - - return TPL_ERROR_NONE; -} - -static void -__cb_tbm_queue_reset_callback(tbm_surface_queue_h surface_queue, - void *data) -{ - tpl_surface_t *surface = NULL; - tpl_wl_vk_surface_t *wl_vk_surface = NULL; - tpl_bool_t is_activated = TPL_FALSE; - - surface = (tpl_surface_t *)data; - TPL_CHECK_ON_NULL_RETURN(surface); - - wl_vk_surface = (tpl_wl_vk_surface_t *)surface->backend.data; - TPL_CHECK_ON_NULL_RETURN(wl_vk_surface); - - /* When queue_reset_callback is called, if is_activated is different from - * its previous state change the reset flag to TPL_TRUE to get a new buffer - * with the changed state(ACTIVATED/DEACTIVATED) at the next frame. */ - is_activated = twe_surface_check_activated(wl_vk_surface->twe_surface); - - if (wl_vk_surface->is_activated != is_activated) { - if (is_activated) { - TPL_LOG_T("WL_VK", - "[ACTIVATED_CB] wl_vk_surface(%p) tbm_queue(%p)", - wl_vk_surface, surface_queue); - } else { - TPL_LOG_T("WL_VK", - "[DEACTIVATED_CB] wl_vk_surface(%p) tbm_queue(%p)", - wl_vk_surface, surface_queue); - } - wl_vk_surface->is_activated = is_activated; - } - - wl_vk_surface->reset = TPL_TRUE; - - if (surface->reset_cb) - surface->reset_cb(surface->reset_data); -} - -static tpl_result_t -__tpl_wl_vk_wsi_surface_create_swapchain(tpl_surface_t *surface, - tbm_format format, int width, - int height, int buffer_count, int present_mode) -{ - tpl_wl_vk_surface_t *wl_vk_surface = NULL; - tpl_wl_vk_display_t *wl_vk_display = NULL; - tpl_result_t res = TPL_ERROR_NONE; - - TPL_ASSERT(surface); - TPL_ASSERT(surface->backend.data); - TPL_ASSERT(surface->display); - - wl_vk_surface = (tpl_wl_vk_surface_t *) surface->backend.data; - TPL_ASSERT(wl_vk_surface); - - wl_vk_display = (tpl_wl_vk_display_t *) - surface->display->backend.data; - TPL_ASSERT(wl_vk_display); - - if (wl_vk_surface->tbm_queue) { - int old_width = tbm_surface_queue_get_width(wl_vk_surface->tbm_queue); - int old_height = tbm_surface_queue_get_height(wl_vk_surface->tbm_queue); - - if (old_width != width || old_height != height) { - tbm_surface_queue_reset(wl_vk_surface->tbm_queue, - width, height, format); - TPL_LOG_T("WL_VK", - "[RESIZE] wl_vk_surface(%p) tbm_queue(%p), (%d x %d) -> (%d x %d)", - wl_vk_surface, wl_vk_surface->tbm_queue, - old_width, old_height, width, height); - } - - if (wl_vk_surface->swapchain_buffers) { - int i; - for (i = 0; i < wl_vk_surface->buffer_count; i++) { - if (wl_vk_surface->swapchain_buffers[i]) { - TPL_DEBUG("unref tbm_surface(%p)", wl_vk_surface->swapchain_buffers[i]); - tbm_surface_internal_unref(wl_vk_surface->swapchain_buffers[i]); - wl_vk_surface->swapchain_buffers[i] = NULL; - } - } - - free(wl_vk_surface->swapchain_buffers); - wl_vk_surface->swapchain_buffers = NULL; - } - - wl_vk_surface->buffer_count = - tbm_surface_queue_get_size(wl_vk_surface->tbm_queue); - wl_vk_surface->reset = TPL_FALSE; - - __tpl_util_atomic_inc(&wl_vk_surface->swapchain_reference); - - TPL_LOG_T("WL_VK", "[REUSE] wl_vk_surface(%p) tbm_queue(%p) size(%d)", - wl_vk_surface, wl_vk_surface->tbm_queue, - wl_vk_surface->buffer_count); - return TPL_ERROR_NONE; - } - - res = twe_surface_create_swapchain(wl_vk_surface->twe_surface, - width, height, format, - buffer_count, present_mode); - if (res != TPL_ERROR_NONE) { - TPL_ERR("Failed to create swapchain. twe_surface(%p)", - wl_vk_surface->twe_surface); - return res; - } - - wl_vk_surface->tbm_queue = twe_surface_get_tbm_queue( - wl_vk_surface->twe_surface); - - /* Set reset_callback to tbm_queue */ - if (tbm_surface_queue_add_reset_cb(wl_vk_surface->tbm_queue, - __cb_tbm_queue_reset_callback, - (void *)surface) != TBM_SURFACE_QUEUE_ERROR_NONE) { - TPL_ERR("TBM surface queue add reset cb failed!"); - twe_surface_destroy_swapchain(wl_vk_surface->twe_surface); - wl_vk_surface->tbm_queue = NULL; - return TPL_ERROR_INVALID_OPERATION; - } - - wl_vk_surface->buffer_count = buffer_count; - wl_vk_surface->reset = TPL_FALSE; - - __tpl_util_atomic_set(&wl_vk_surface->swapchain_reference, 1); - - return TPL_ERROR_NONE; -} - -static tpl_result_t -__tpl_wl_vk_wsi_surface_destroy_swapchain(tpl_surface_t *surface) -{ - tpl_wl_vk_surface_t *wl_vk_surface = NULL; - tpl_wl_vk_display_t *wl_vk_display = NULL; - tpl_result_t res = TPL_ERROR_NONE; - unsigned int ref; - - TPL_ASSERT(surface); - TPL_ASSERT(surface->backend.data); - TPL_ASSERT(surface->display); - TPL_ASSERT(surface->display->backend.data); - - wl_vk_surface = (tpl_wl_vk_surface_t *) surface->backend.data; - wl_vk_display = (tpl_wl_vk_display_t *) surface->display->backend.data; - - if (twe_display_lock(wl_vk_display->twe_display) == TPL_ERROR_NONE) { - ref = __tpl_util_atomic_dec(&wl_vk_surface->swapchain_reference); - if (ref > 0) { - TPL_LOG_T("WL_VK", - "This swapchain is still valid. | twe_surface(%p)", - wl_vk_surface->twe_surface); - twe_display_unlock(wl_vk_display->twe_display); - return TPL_ERROR_NONE; - } - - - if (wl_vk_surface->reset) { - TPL_LOG_T("WL_VK", - "Since reset is in the TRUE state, it will not be destroyed."); - twe_display_unlock(wl_vk_display->twe_display); - return TPL_ERROR_NONE; - } - - if (wl_vk_surface->swapchain_buffers) { - int i; - for (i = 0; i < wl_vk_surface->buffer_count; i++) { - TPL_DEBUG("Stop tracking tbm_surface(%p)", - wl_vk_surface->swapchain_buffers[i]); - tbm_surface_internal_unref(wl_vk_surface->swapchain_buffers[i]); - wl_vk_surface->swapchain_buffers[i] = NULL; - } - - free(wl_vk_surface->swapchain_buffers); - wl_vk_surface->swapchain_buffers = NULL; - } - - res = twe_surface_destroy_swapchain(wl_vk_surface->twe_surface); - if (res != TPL_ERROR_NONE) { - TPL_ERR("Failed to destroy swapchain. twe_surface(%p)", - wl_vk_surface->twe_surface); - twe_display_unlock(wl_vk_display->twe_display); - return res; - } - - wl_vk_surface->tbm_queue = NULL; - - twe_display_unlock(wl_vk_display->twe_display); - } - - return TPL_ERROR_NONE; -} - tpl_bool_t __tpl_display_choose_backend_wayland_vk_wsi_thread(tpl_handle_t native_dpy) { @@ -1752,74 +1930,74 @@ __tpl_surface_init_backend_wl_vk_wsi_thread(tpl_surface_backend_t *backend) } static void -__cb_wl_egl_buffer_free(tpl_wl_egl_buffer_t *wl_egl_buffer) +__cb_wl_vk_buffer_free(tpl_wl_vk_buffer_t *wl_vk_buffer) { - tpl_wl_egl_surface_t *wl_egl_surface = wl_egl_buffer->wl_egl_surface; - tpl_wl_egl_display_t *wl_egl_display = wl_egl_surface->wl_egl_display; + tpl_wl_vk_surface_t *wl_vk_surface = wl_vk_buffer->wl_vk_surface; + tpl_wl_vk_display_t *wl_vk_display = wl_vk_surface->wl_vk_display; - TPL_INFO("[BUFFER_FREE]", "wl_egl_buffer(%p) wl_buffer(%p) tbm_surface(%p)", - wl_egl_buffer, wl_egl_buffer->wl_buffer, wl_egl_buffer->tbm_surface); + TPL_INFO("[BUFFER_FREE]", "wl_vk_buffer(%p) wl_buffer(%p) tbm_surface(%p)", + wl_vk_buffer, wl_vk_buffer->wl_buffer, wl_vk_buffer->tbm_surface); - tpl_gmutex_lock(&wl_egl_surface->buffers_mutex); - if (wl_egl_buffer->idx >= 0 && wl_egl_surface->buffers[wl_egl_buffer->idx]) { - wl_egl_surface->buffers[wl_egl_buffer->idx] = NULL; - wl_egl_surface->buffer_cnt--; + tpl_gmutex_lock(&wl_vk_surface->buffers_mutex); + if (wl_vk_buffer->idx >= 0 && wl_vk_surface->buffers[wl_vk_buffer->idx]) { + wl_vk_surface->buffers[wl_vk_buffer->idx] = NULL; + wl_vk_surface->buffer_cnt--; - wl_egl_buffer->idx = -1; + wl_vk_buffer->idx = -1; } - tpl_gmutex_unlock(&wl_egl_surface->buffers_mutex); + tpl_gmutex_unlock(&wl_vk_surface->buffers_mutex); - wl_display_flush(wl_egl_display->wl_display); + wl_display_flush(wl_vk_display->wl_display); - if (wl_egl_buffer->wl_buffer) { - wayland_tbm_client_destroy_buffer(wl_egl_display->wl_tbm_client, - (void *)wl_egl_buffer->wl_buffer); - wl_egl_buffer->wl_buffer = NULL; + if (wl_vk_buffer->wl_buffer) { + wayland_tbm_client_destroy_buffer(wl_vk_display->wl_tbm_client, + (void *)wl_vk_buffer->wl_buffer); + wl_vk_buffer->wl_buffer = NULL; } - if (wl_egl_buffer->buffer_release) { - zwp_linux_buffer_release_v1_destroy(wl_egl_buffer->buffer_release); - wl_egl_buffer->buffer_release = NULL; + if (wl_vk_buffer->buffer_release) { + zwp_linux_buffer_release_v1_destroy(wl_vk_buffer->buffer_release); + wl_vk_buffer->buffer_release = NULL; } - if (wl_egl_buffer->release_fence_fd != -1) { - close(wl_egl_buffer->release_fence_fd); - wl_egl_buffer->release_fence_fd = -1; + if (wl_vk_buffer->release_fence_fd != -1) { + close(wl_vk_buffer->release_fence_fd); + wl_vk_buffer->release_fence_fd = -1; } - if (wl_egl_buffer->waiting_source) { - tpl_gsource_destroy(wl_egl_buffer->waiting_source, TPL_FALSE); - wl_egl_buffer->waiting_source = NULL; + if (wl_vk_buffer->waiting_source) { + tpl_gsource_destroy(wl_vk_buffer->waiting_source, TPL_FALSE); + wl_vk_buffer->waiting_source = NULL; } - if (wl_egl_buffer->commit_sync_fd != -1) { - int ret = _write_to_eventfd(wl_egl_buffer->commit_sync_fd); + if (wl_vk_buffer->commit_sync_fd != -1) { + int ret = _write_to_eventfd(wl_vk_buffer->commit_sync_fd); if (ret == -1) TPL_ERR("Failed to send commit_sync signal to fd(%d)", - wl_egl_buffer->commit_sync_fd); - close(wl_egl_buffer->commit_sync_fd); - wl_egl_buffer->commit_sync_fd = -1; + wl_vk_buffer->commit_sync_fd); + close(wl_vk_buffer->commit_sync_fd); + wl_vk_buffer->commit_sync_fd = -1; } - if (wl_egl_buffer->presentation_sync_fd != -1) { - int ret = _write_to_eventfd(wl_egl_buffer->presentation_sync_fd); + if (wl_vk_buffer->presentation_sync_fd != -1) { + int ret = _write_to_eventfd(wl_vk_buffer->presentation_sync_fd); if (ret == -1) TPL_ERR("Failed to send presentation_sync signal to fd(%d)", - wl_egl_buffer->presentation_sync_fd); - close(wl_egl_buffer->presentation_sync_fd); - wl_egl_buffer->presentation_sync_fd = -1; + wl_vk_buffer->presentation_sync_fd); + close(wl_vk_buffer->presentation_sync_fd); + wl_vk_buffer->presentation_sync_fd = -1; } - if (wl_egl_buffer->rects) { - free(wl_egl_buffer->rects); - wl_egl_buffer->rects = NULL; - wl_egl_buffer->num_rects = 0; + if (wl_vk_buffer->rects) { + free(wl_vk_buffer->rects); + wl_vk_buffer->rects = NULL; + wl_vk_buffer->num_rects = 0; } - wl_egl_buffer->tbm_surface = NULL; - wl_egl_buffer->bo_name = -1; + wl_vk_buffer->tbm_surface = NULL; + wl_vk_buffer->bo_name = -1; - free(wl_egl_buffer); + free(wl_vk_buffer); } static int @@ -1829,22 +2007,22 @@ _get_tbm_surface_bo_name(tbm_surface_h tbm_surface) } static void -_print_buffer_lists(tpl_wl_egl_surface_t *wl_egl_surface) +_print_buffer_lists(tpl_wl_vk_surface_t *wl_vk_surface) { int idx = 0; - tpl_gmutex_lock(&wl_egl_surface->buffers_mutex); - TPL_INFO("[BUFFERS_INFO]", "wl_egl_surface(%p) buffer_cnt(%d)", - wl_egl_surface, wl_egl_surface->buffer_cnt); + tpl_gmutex_lock(&wl_vk_surface->buffers_mutex); + TPL_INFO("[BUFFERS_INFO]", "wl_vk_surface(%p) buffer_cnt(%d)", + wl_vk_surface, wl_vk_surface->buffer_cnt); for (idx = 0; idx < BUFFER_ARRAY_SIZE; idx++) { - tpl_wl_egl_buffer_t *wl_egl_buffer = wl_egl_surface->buffers[idx]; - if (wl_egl_buffer) { + tpl_wl_vk_buffer_t *wl_vk_buffer = wl_vk_surface->buffers[idx]; + if (wl_vk_buffer) { TPL_INFO("[INFO]", - "INDEX[%d] | wl_egl_buffer(%p) tbm_surface(%p) bo(%d) | status(%s)", - idx, wl_egl_buffer, wl_egl_buffer->tbm_surface, - wl_egl_buffer->bo_name, - status_to_string[wl_egl_buffer->status]); + "INDEX[%d] | wl_vk_buffer(%p) tbm_surface(%p) bo(%d) | status(%s)", + idx, wl_vk_buffer, wl_vk_buffer->tbm_surface, + wl_vk_buffer->bo_name, + status_to_string[wl_vk_buffer->status]); } } - tpl_gmutex_unlock(&wl_egl_surface->buffers_mutex); + tpl_gmutex_unlock(&wl_vk_surface->buffers_mutex); }