From 9630493a85d584705785cf71505fffb9bcd02938 Mon Sep 17 00:00:00 2001 From: Joonbum Ko Date: Fri, 30 Apr 2021 15:27:54 +0900 Subject: [PATCH] Back up the legacy codes of wl_vk_thread to unused. Change-Id: Ie9276cd997b89be2f558306daaee3e3eb3738be9 Signed-off-by: Joonbum Ko --- src/unused/tpl_wl_vk_thread_legacy.c | 832 +++++++++++++++++++++++++++ 1 file changed, 832 insertions(+) create mode 100644 src/unused/tpl_wl_vk_thread_legacy.c diff --git a/src/unused/tpl_wl_vk_thread_legacy.c b/src/unused/tpl_wl_vk_thread_legacy.c new file mode 100644 index 0000000..cb4f549 --- /dev/null +++ b/src/unused/tpl_wl_vk_thread_legacy.c @@ -0,0 +1,832 @@ +#define inline __inline__ +#undef inline + +#include "tpl_internal.h" + +#include +#include +#include + +#include + +#include "tpl_wayland_egl_thread.h" + +typedef struct _tpl_wayland_vk_wsi_display tpl_wayland_vk_wsi_display_t; +typedef struct _tpl_wayland_vk_wsi_surface tpl_wayland_vk_wsi_surface_t; +typedef struct _tpl_wayland_vk_wsi_buffer tpl_wayland_vk_wsi_buffer_t; + +struct _tpl_wayland_vk_wsi_display { + twe_thread *wl_thread; + twe_display_h twe_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; + tpl_util_atomic_uint swapchain_reference; +}; + +static tpl_result_t __tpl_wl_vk_wsi_surface_destroy_swapchain( + tpl_surface_t *surface); + +static TPL_INLINE tpl_bool_t +__tpl_wl_vk_wsi_display_is_wl_display(tpl_handle_t native_dpy) +{ + if (!native_dpy) return TPL_FALSE; + + if (twe_check_native_handle_is_wl_display(native_dpy)) + return TPL_TRUE; + + return TPL_FALSE; +} + +static tpl_result_t +__tpl_wl_vk_wsi_display_init(tpl_display_t *display) +{ + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display = NULL; + + TPL_ASSERT(display); + + /* Do not allow default display in wayland */ + if (!display->native_handle) { + TPL_ERR("Invalid native handle for display."); + return TPL_ERROR_INVALID_PARAMETER; + } + + wayland_vk_wsi_display = (tpl_wayland_vk_wsi_display_t *) calloc(1, + sizeof(tpl_wayland_vk_wsi_display_t)); + if (!wayland_vk_wsi_display) { + TPL_ERR("Failed to allocate memory for new tpl_wayland_vk_wsi_display_t."); + return TPL_ERROR_OUT_OF_MEMORY; + } + + display->backend.data = wayland_vk_wsi_display; + + if (twe_check_native_handle_is_wl_display(display->native_handle)) { + wayland_vk_wsi_display->wl_thread = twe_thread_create(); + if (!wayland_vk_wsi_display->wl_thread) { + TPL_ERR("Failed to create twe_thread."); + goto free_display; + } + + wayland_vk_wsi_display->twe_display = + twe_display_add(wayland_vk_wsi_display->wl_thread, + display->native_handle, + display->backend.type); + if (!wayland_vk_wsi_display->twe_display) { + TPL_ERR("Failed to add native_display(%p) to thread(%p)", + display->native_handle, + wayland_vk_wsi_display->wl_thread); + goto free_display; + } + + } else { + TPL_ERR("Invalid native handle for display."); + goto free_display; + } + + TPL_LOG_T("WL_VK", + "[INIT DISPLAY] wayland_vk_wsi_display(%p) twe_thread(%p) twe_display(%p)", + wayland_vk_wsi_display, + wayland_vk_wsi_display->wl_thread, + wayland_vk_wsi_display->twe_display); + + return TPL_ERROR_NONE; + +free_display: + if (wayland_vk_wsi_display) { + if (wayland_vk_wsi_display->twe_display) + twe_display_del(wayland_vk_wsi_display->twe_display); + if (wayland_vk_wsi_display->wl_thread) + twe_thread_destroy(wayland_vk_wsi_display->wl_thread); + + wayland_vk_wsi_display->wl_thread = NULL; + wayland_vk_wsi_display->twe_display = NULL; + + free(wayland_vk_wsi_display); + display->backend.data = NULL; + } + + return TPL_ERROR_INVALID_OPERATION; +} + +static void +__tpl_wl_vk_wsi_display_fini(tpl_display_t *display) +{ + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display; + + TPL_ASSERT(display); + + wayland_vk_wsi_display = (tpl_wayland_vk_wsi_display_t *)display->backend.data; + if (wayland_vk_wsi_display) { + + TPL_LOG_T("WL_VK", + "[FINI] wayland_vk_wsi_display(%p) twe_thread(%p) twe_display(%p)", + wayland_vk_wsi_display, + wayland_vk_wsi_display->wl_thread, + wayland_vk_wsi_display->twe_display); + + if (wayland_vk_wsi_display->twe_display) { + tpl_result_t ret = TPL_ERROR_NONE; + ret = twe_display_del(wayland_vk_wsi_display->twe_display); + if (ret != TPL_ERROR_NONE) + TPL_ERR("Failed to delete twe_display(%p) from twe_thread(%p)", + wayland_vk_wsi_display->twe_display, + wayland_vk_wsi_display->wl_thread); + wayland_vk_wsi_display->twe_display = NULL; + } + + if (wayland_vk_wsi_display->wl_thread) { + twe_thread_destroy(wayland_vk_wsi_display->wl_thread); + wayland_vk_wsi_display->wl_thread = NULL; + } + + free(wayland_vk_wsi_display); + } + display->backend.data = NULL; +} + +static tpl_result_t +__tpl_wl_vk_wsi_display_query_config(tpl_display_t *display, + tpl_surface_type_t surface_type, + int red_size, int green_size, + int blue_size, int alpha_size, + int color_depth, int *native_visual_id, + tpl_bool_t *is_slow) +{ + TPL_ASSERT(display); + + if (surface_type == TPL_SURFACE_TYPE_WINDOW && red_size == 8 && + green_size == 8 && blue_size == 8 && + (color_depth == 32 || color_depth == 24)) { + + if (alpha_size == 8) { + if (native_visual_id) *native_visual_id = TBM_FORMAT_ARGB8888; + if (is_slow) *is_slow = TPL_FALSE; + return TPL_ERROR_NONE; + } + if (alpha_size == 0) { + if (native_visual_id) *native_visual_id = TBM_FORMAT_XRGB8888; + if (is_slow) *is_slow = TPL_FALSE; + return TPL_ERROR_NONE; + } + } + + return TPL_ERROR_INVALID_PARAMETER; +} + +static tpl_result_t +__tpl_wl_vk_wsi_display_filter_config(tpl_display_t *display, + int *visual_id, + int alpha_size) +{ + TPL_IGNORE(display); + TPL_IGNORE(visual_id); + TPL_IGNORE(alpha_size); + return TPL_ERROR_NONE; +} + +static tpl_result_t +__tpl_wl_vk_wsi_display_query_window_supported_buffer_count( + tpl_display_t *display, + tpl_handle_t window, int *min, int *max) +{ + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display = NULL; + tpl_result_t res = TPL_ERROR_NONE; + + TPL_ASSERT(display); + TPL_ASSERT(window); + + wayland_vk_wsi_display = (tpl_wayland_vk_wsi_display_t *)display->backend.data; + + if (!wayland_vk_wsi_display) return TPL_ERROR_INVALID_OPERATION; + + res = twe_display_get_buffer_count(wayland_vk_wsi_display->twe_display, + min, max); + if (res != TPL_ERROR_NONE) { + TPL_ERR("Failed to query buffer count. twe_display(%p)", + wayland_vk_wsi_display->twe_display); + return res; + } + + return TPL_ERROR_NONE; +} + +static tpl_result_t +__tpl_wl_vk_wsi_display_query_window_supported_present_modes( + tpl_display_t *display, + tpl_handle_t window, int *modes) +{ + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display = NULL; + tpl_result_t res = TPL_ERROR_NONE; + + TPL_ASSERT(display); + TPL_ASSERT(window); + + wayland_vk_wsi_display = (tpl_wayland_vk_wsi_display_t *)display->backend.data; + + if (!wayland_vk_wsi_display) return TPL_ERROR_INVALID_OPERATION; + + if (modes) { + res = twe_display_get_present_mode(wayland_vk_wsi_display->twe_display, + modes); + if (res != TPL_ERROR_NONE) { + TPL_ERR("Failed to query present modes. twe_display(%p)", + wayland_vk_wsi_display->twe_display); + return res; + } + } + + return TPL_ERROR_NONE; +} + +static tpl_result_t +__tpl_wl_vk_wsi_surface_init(tpl_surface_t *surface) +{ + tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display = NULL; + twe_surface_h twe_surface = NULL; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->type == TPL_SURFACE_TYPE_WINDOW); + TPL_ASSERT(surface->native_handle); + + wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *) calloc(1, + sizeof(tpl_wayland_vk_wsi_surface_t)); + if (!wayland_vk_wsi_surface) { + TPL_ERR("Failed to allocate memory for new tpl_wayland_vk_wsi_surface_t."); + return TPL_ERROR_OUT_OF_MEMORY; + } + + wayland_vk_wsi_display = + (tpl_wayland_vk_wsi_display_t *)surface->display->backend.data; + if (!wayland_vk_wsi_display) { + TPL_ERR("Invalid parameter. wayland_vk_wsi_display(%p)", + wayland_vk_wsi_display); + free(wayland_vk_wsi_surface); + return TPL_ERROR_INVALID_PARAMETER; + } + + surface->backend.data = (void *)wayland_vk_wsi_surface; + wayland_vk_wsi_surface->tbm_queue = NULL; + + twe_surface = twe_surface_add(wayland_vk_wsi_display->wl_thread, + wayland_vk_wsi_display->twe_display, + surface->native_handle, + 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); + free(wayland_vk_wsi_surface); + surface->backend.data = NULL; + return TPL_ERROR_OUT_OF_MEMORY; + } + + 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)", + surface, wayland_vk_wsi_surface, twe_surface); + + return TPL_ERROR_NONE; +} + +static void +__tpl_wl_vk_wsi_surface_fini(tpl_surface_t *surface) +{ + tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display = NULL; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->display); + + wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *) surface->backend.data; + if (wayland_vk_wsi_surface == NULL) return; + + wayland_vk_wsi_display = (tpl_wayland_vk_wsi_display_t *) + surface->display->backend.data; + if (wayland_vk_wsi_display == NULL) return; + + 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, + wayland_vk_wsi_surface->twe_surface); + + if (twe_surface_del(wayland_vk_wsi_surface->twe_surface) + != TPL_ERROR_NONE) { + TPL_ERR("Failed to delete twe_surface(%p) from thread(%p)", + wayland_vk_wsi_surface->twe_surface, + wayland_vk_wsi_display->wl_thread); + } + + wayland_vk_wsi_surface->twe_surface = NULL; + + free(wayland_vk_wsi_surface); + surface->backend.data = NULL; +} + +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->display); + TPL_ASSERT(surface->display->native_handle); + TPL_ASSERT(tbm_surface); + + tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = + (tpl_wayland_vk_wsi_surface_t *) surface->backend.data; + tbm_surface_queue_error_e tsq_err; + + 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; + } + + /* If there are received region information, + * save it to buf_info in tbm_surface user_data using below API. */ + if (num_rects && rects) { + tpl_result_t ret = TPL_ERROR_NONE; + ret = twe_surface_set_damage_region(tbm_surface, num_rects, rects); + if (ret != TPL_ERROR_NONE) { + TPL_WARN("Failed to set damage region. num_rects(%d) rects(%p)", + num_rects, rects); + } + } + tsq_err = tbm_surface_queue_enqueue(wayland_vk_wsi_surface->tbm_queue, + tbm_surface); + if (tsq_err == TBM_SURFACE_QUEUE_ERROR_NONE) { + tbm_surface_internal_unref(tbm_surface); + } else { + TPL_ERR("Failed to enqeueue tbm_surface. | tsq_err = %d", tsq_err); + return TPL_ERROR_INVALID_OPERATION; + } + + if (sync_fence != -1) { + tpl_result_t res = TPL_ERROR_NONE; + res = twe_surface_set_sync_fd(wayland_vk_wsi_surface->twe_surface, + tbm_surface, sync_fence); + if (res != TPL_ERROR_NONE) { + TPL_WARN("Failed to set sync_fd(%d). Fallback to async mode.", + sync_fence); + } + } + + TPL_LOG_T("WL_VK", "[ENQ] tbm_surface(%p) bo(%d) sync_fence(%d)", + tbm_surface, + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)), + sync_fence); + + return TPL_ERROR_NONE; +} + +static tpl_bool_t +__tpl_wl_vk_wsi_surface_validate(tpl_surface_t *surface) +{ + TPL_ASSERT(surface); + TPL_ASSERT(surface->backend.data); + + tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = + (tpl_wayland_vk_wsi_surface_t *)surface->backend.data; + + 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, + tbm_fd *sync_fence) +{ + TPL_ASSERT(surface); + TPL_ASSERT(surface->backend.data); + TPL_ASSERT(surface->display); + + tbm_surface_h tbm_surface = NULL; + tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = + (tpl_wayland_vk_wsi_surface_t *)surface->backend.data; + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display = + (tpl_wayland_vk_wsi_display_t *)surface->display->backend.data; + tbm_surface_queue_error_e tsq_err = 0; + tpl_result_t lock_res = TPL_ERROR_NONE; + tpl_result_t res = TPL_ERROR_NONE; + + if (sync_fence) + *sync_fence = -1; + + TPL_OBJECT_UNLOCK(surface); + TRACE_BEGIN("WAIT_DEQUEUEABLE"); + lock_res = twe_display_lock(wayland_vk_wsi_display->twe_display); + res = twe_surface_wait_dequeueable(wayland_vk_wsi_surface->twe_surface, + timeout_ns); + TRACE_END(); + TPL_OBJECT_LOCK(surface); + + if (res == TPL_ERROR_TIME_OUT) { + TPL_ERR("Failed to get buffer during timeout_ns(%" PRIu64 ")", + timeout_ns); + if (lock_res == TPL_ERROR_NONE) + twe_display_unlock(wayland_vk_wsi_display->twe_display); + return NULL; + } else if (res != TPL_ERROR_NONE) { + TPL_ERR("Invalid operation. twe_surface(%p) timeout_ns(%" PRIu64 ")", + wayland_vk_wsi_surface->twe_surface, timeout_ns); + if (lock_res == TPL_ERROR_NONE) + twe_display_unlock(wayland_vk_wsi_display->twe_display); + return NULL; + } + + if (wayland_vk_wsi_surface->reset) { + TPL_LOG_T("WL_VK", "tbm_queue(%p) has been reset. Do not process dequeue.", + wayland_vk_wsi_surface->tbm_queue); + if (lock_res == TPL_ERROR_NONE) + twe_display_unlock(wayland_vk_wsi_display->twe_display); + return NULL; + } + + + 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(%p) | tsq_err = %d", + wayland_vk_wsi_surface->tbm_queue, tsq_err); + if (lock_res == TPL_ERROR_NONE) + twe_display_unlock(wayland_vk_wsi_display->twe_display); + return NULL; + } + + tbm_surface_internal_ref(tbm_surface); + + if (sync_fence) { + *sync_fence = twe_surface_create_sync_fd(tbm_surface); + } + + TPL_LOG_T("WL_VK", "[DEQ] tbm_queue(%p) tbm_surface(%p) bo(%d)", + wayland_vk_wsi_surface->tbm_queue, tbm_surface, + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); + + if (lock_res == TPL_ERROR_NONE) + twe_display_unlock(wayland_vk_wsi_display->twe_display); + + 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_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_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); + + wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *)surface->backend.data; + wayland_vk_wsi_display = (tpl_wayland_vk_wsi_display_t *)surface->display->backend.data; + + 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, + NULL, buffer_count); + if (ret != TPL_ERROR_NONE) { + TPL_ERR("Failed to get buffer_count. twe_surface(%p)", + wayland_vk_wsi_surface->twe_surface); + twe_display_unlock(wayland_vk_wsi_display->twe_display); + return ret; + } + + wayland_vk_wsi_surface->swapchain_buffers = (tbm_surface_h *)calloc( + *buffer_count, + sizeof(tbm_surface_h)); + if (!wayland_vk_wsi_surface->swapchain_buffers) { + TPL_ERR("Failed to allocate memory for buffers."); + twe_display_unlock(wayland_vk_wsi_display->twe_display); + return TPL_ERROR_OUT_OF_MEMORY; + } + + ret = twe_surface_get_swapchain_buffers(wayland_vk_wsi_surface->twe_surface, + 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(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++) { + if (wayland_vk_wsi_surface->swapchain_buffers[i]) { + TPL_DEBUG("swapchain_buffers[%d] = tbm_surface(%p) bo(%d)", + 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 = wayland_vk_wsi_surface->swapchain_buffers; + + twe_display_unlock(wayland_vk_wsi_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_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; + tpl_bool_t is_activated = TPL_FALSE; + + surface = (tpl_surface_t *)data; + TPL_CHECK_ON_NULL_RETURN(surface); + + wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *)surface->backend.data; + TPL_CHECK_ON_NULL_RETURN(wayland_vk_wsi_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(wayland_vk_wsi_surface->twe_surface); + + if (wayland_vk_wsi_surface->is_activated != is_activated) { + if (is_activated) { + TPL_LOG_T("WL_VK", + "[ACTIVATED_CB] wayland_vk_wsi_surface(%p) tbm_queue(%p)", + wayland_vk_wsi_surface, surface_queue); + } else { + TPL_LOG_T("WL_VK", + "[DEACTIVATED_CB] wayland_vk_wsi_surface(%p) tbm_queue(%p)", + wayland_vk_wsi_surface, surface_queue); + } + wayland_vk_wsi_surface->is_activated = is_activated; + } + + wayland_vk_wsi_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_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_display = NULL; + tpl_result_t res = TPL_ERROR_NONE; + + TPL_ASSERT(surface); + TPL_ASSERT(surface->backend.data); + TPL_ASSERT(surface->display); + + wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *) surface->backend.data; + TPL_ASSERT(wayland_vk_wsi_surface); + + wayland_vk_wsi_display = (tpl_wayland_vk_wsi_display_t *) + surface->display->backend.data; + TPL_ASSERT(wayland_vk_wsi_display); + + if (wayland_vk_wsi_surface->tbm_queue) { + int old_width = tbm_surface_queue_get_width(wayland_vk_wsi_surface->tbm_queue); + int old_height = tbm_surface_queue_get_height(wayland_vk_wsi_surface->tbm_queue); + + if (old_width != width || old_height != height) { + tbm_surface_queue_reset(wayland_vk_wsi_surface->tbm_queue, + width, height, format); + TPL_LOG_T("WL_VK", + "[RESIZE] wayland_vk_wsi_surface(%p) tbm_queue(%p), (%d x %d) -> (%d x %d)", + wayland_vk_wsi_surface, wayland_vk_wsi_surface->tbm_queue, + old_width, old_height, width, height); + } + + if (wayland_vk_wsi_surface->swapchain_buffers) { + int i; + for (i = 0; i < wayland_vk_wsi_surface->buffer_count; i++) { + if (wayland_vk_wsi_surface->swapchain_buffers[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; + } + + 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); + return TPL_ERROR_NONE; + } + + res = twe_surface_create_swapchain(wayland_vk_wsi_surface->twe_surface, + width, height, format, + buffer_count, present_mode); + if (res != TPL_ERROR_NONE) { + TPL_ERR("Failed to create swapchain. twe_surface(%p)", + wayland_vk_wsi_surface->twe_surface); + return res; + } + + wayland_vk_wsi_surface->tbm_queue = twe_surface_get_tbm_queue( + wayland_vk_wsi_surface->twe_surface); + + /* Set reset_callback to tbm_queue */ + if (tbm_surface_queue_add_reset_cb(wayland_vk_wsi_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(wayland_vk_wsi_surface->twe_surface); + wayland_vk_wsi_surface->tbm_queue = NULL; + return TPL_ERROR_INVALID_OPERATION; + } + + 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; +} + +static tpl_result_t +__tpl_wl_vk_wsi_surface_destroy_swapchain(tpl_surface_t *surface) +{ + tpl_wayland_vk_wsi_surface_t *wayland_vk_wsi_surface = NULL; + tpl_wayland_vk_wsi_display_t *wayland_vk_wsi_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); + + wayland_vk_wsi_surface = (tpl_wayland_vk_wsi_surface_t *) surface->backend.data; + wayland_vk_wsi_display = (tpl_wayland_vk_wsi_display_t *) surface->display->backend.data; + + if (twe_display_lock(wayland_vk_wsi_display->twe_display) == TPL_ERROR_NONE) { + 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); + twe_display_unlock(wayland_vk_wsi_display->twe_display); + 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."); + twe_display_unlock(wayland_vk_wsi_display->twe_display); + 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)", + wayland_vk_wsi_surface->twe_surface); + twe_display_unlock(wayland_vk_wsi_display->twe_display); + return res; + } + + wayland_vk_wsi_surface->tbm_queue = NULL; + + twe_display_unlock(wayland_vk_wsi_display->twe_display); + } + + return TPL_ERROR_NONE; +} + +tpl_bool_t +__tpl_display_choose_backend_wayland_vk_wsi_thread(tpl_handle_t native_dpy) +{ + if (!native_dpy) return TPL_FALSE; + + if (twe_check_native_handle_is_wl_display(native_dpy)) + return TPL_TRUE; + + return TPL_FALSE; +} + +void +__tpl_display_init_backend_wl_vk_wsi_thread(tpl_display_backend_t *backend) +{ + TPL_ASSERT(backend); + + backend->type = TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD; + backend->data = NULL; + + backend->init = __tpl_wl_vk_wsi_display_init; + backend->fini = __tpl_wl_vk_wsi_display_fini; + backend->query_config = __tpl_wl_vk_wsi_display_query_config; + backend->filter_config = __tpl_wl_vk_wsi_display_filter_config; + backend->query_window_supported_buffer_count = + __tpl_wl_vk_wsi_display_query_window_supported_buffer_count; + backend->query_window_supported_present_modes = + __tpl_wl_vk_wsi_display_query_window_supported_present_modes; +} + +void +__tpl_surface_init_backend_wl_vk_wsi_thread(tpl_surface_backend_t *backend) +{ + TPL_ASSERT(backend); + + backend->type = TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD; + backend->data = NULL; + + 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 = + __tpl_wl_vk_wsi_surface_get_swapchain_buffers; + backend->create_swapchain = __tpl_wl_vk_wsi_surface_create_swapchain; + backend->destroy_swapchain = __tpl_wl_vk_wsi_surface_destroy_swapchain; +} -- 2.34.1