From: Joonbum Ko Date: Tue, 15 Dec 2020 10:53:09 +0000 (+0900) Subject: re-implement presentation sync without using sync_timeline. X-Git-Tag: submit/tizen/20201223.060207~6 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=84e482f0b22a39418f2571e56923c3f514ff3cd5;p=platform%2Fcore%2Fuifw%2Flibtpl-egl.git re-implement presentation sync without using sync_timeline. Change-Id: I999a56996081ac7b1706ca6ba9226b36e9b6f3d5 Signed-off-by: Joonbum Ko --- diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index fa92a87..4c7f2f9 100755 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -76,7 +76,6 @@ struct _twe_wl_disp_source { struct wayland_tbm_client *wl_tbm_client; struct tizen_surface_shm *tss; /* used for surface buffer_flush */ struct wp_presentation *presentation; - tpl_list_t *presentation_feedbacks; struct zwp_linux_explicit_synchronization_v1 *explicit_sync; tpl_bool_t use_explicit_sync; struct { @@ -131,6 +130,7 @@ struct _twe_wl_surf_source { tpl_list_t *fence_waiting_sources; /* Trace fence_wait_source from ENQUEUE to fence signaled */ tpl_list_t *vblank_waiting_buffers; /* for FIFO/FIFO_RELAXED modes */ tpl_list_t *render_done_fences; /* for attaching to twe_thread with fences passed by enqueue */ + tpl_list_t *presentation_feedbacks; /* for tracing presentation feedbacks */ tbm_surface_h draw_done_buffer; /* for MAILBOX mode */ int render_done_cnt; @@ -149,11 +149,10 @@ struct _twe_wl_surf_source { int fd; } commit_sync; - tbm_fd presentation_sync_timeline; - int presentation_sync_timestamp; - int presentation_sync_ts_backup; - int presentation_sync_req_cnt; - GMutex pst_mutex; + struct { + GMutex mutex; + int fd; + } presentation_sync; GMutex surf_mutex; @@ -217,6 +216,10 @@ struct _twe_wl_buffer_info { int acquire_fence_fd; int commit_sync_fd; + + struct wp_presentation_feedback *presentation_feedback; + int presentation_sync_fd; + }; struct _twe_fence_wait_source { @@ -1120,9 +1123,6 @@ _twe_thread_wl_disp_source_destroy(void *source) _twe_display_print_err(disp_source, "dispatch_queue_pending"); } - if (disp_source->presentation && disp_source->presentation_feedbacks) - __tpl_list_free(disp_source->presentation_feedbacks, (tpl_free_func_t)free); - wl_event_queue_destroy(disp_source->ev_queue); g_mutex_unlock(&disp_source->wl_event_mutex); @@ -1195,11 +1195,6 @@ twe_display_add(twe_thread* thread, TPL_DISPLAY_PRESENT_MODE_FIFO; _twe_display_wayland_init(source); - source->presentation_feedbacks = NULL; - - if (source->presentation) - source->presentation_feedbacks = __tpl_list_alloc(); - source->disp_del_source = _twe_del_source_init(ctx, source); source->disp_del_source->destroy_target_source_func = _twe_thread_wl_disp_source_destroy; @@ -1520,7 +1515,7 @@ __cb_create_presentation_sync_fd(struct wl_egl_window *wl_egl_window, void *priv struct tizen_private *tizen_private = (struct tizen_private *)private; twe_wl_surf_source *surf_source = NULL; - tbm_fd presentation_sync_fd = -1; + int presentation_sync_fd = -1; surf_source = (twe_wl_surf_source *)tizen_private->data; if (!surf_source) { @@ -1528,31 +1523,33 @@ __cb_create_presentation_sync_fd(struct wl_egl_window *wl_egl_window, void *priv return -1; } - if (surf_source->presentation_sync_timeline != -1) { - char name[32]; - snprintf(name, 32, "p_sync_timeline:%d", - surf_source->presentation_sync_timeline); - - g_mutex_lock(&surf_source->pst_mutex); - - surf_source->presentation_sync_timestamp++; - - presentation_sync_fd = tbm_sync_fence_create(surf_source->presentation_sync_timeline, - name, - surf_source->presentation_sync_timestamp); - TPL_DEBUG("[PRESENTATION_SYNC] surf_source(%p) timeline(%d) timestamp(%d) sync_fence(%d)", - surf_source, surf_source->presentation_sync_timeline, surf_source->presentation_sync_timestamp, - presentation_sync_fd); + g_mutex_lock(&surf_source->presentation_sync.mutex); + if (surf_source->presentation_sync.fd != -1) { + presentation_sync_fd = dup(surf_source->presentation_sync.fd); + TRACE_MARK("[ONLY_DUP] presentation_sync_fd(%d) dup(%d)", + surf_source->presentation_sync.fd, presentation_sync_fd); + TPL_DEBUG("[DUP_PRESENTATION_SYNC] surf_source(%p) presentation_sync_fd(%d) dup(%d)", + surf_source, surf_source->presentation_sync.fd, presentation_sync_fd); + g_mutex_unlock(&surf_source->presentation_sync.mutex); + return presentation_sync_fd; + } - TRACE_ASYNC_BEGIN(surf_source->presentation_sync_timestamp, "[PRESENTATION]"); + surf_source->presentation_sync.fd = eventfd(0, EFD_CLOEXEC); + if (surf_source->presentation_sync.fd == -1) { + TPL_ERR("Failed to create presentation_sync_fd. twe_surface(%p)", surf_source); + g_mutex_unlock(&surf_source->presentation_sync.mutex); + return -1; + } - surf_source->presentation_sync_req_cnt++; + presentation_sync_fd = dup(surf_source->presentation_sync.fd); + TRACE_MARK("[CREATE] presentation_sync_fd(%d) dup(%d)", + surf_source->presentation_sync.fd, presentation_sync_fd); + TPL_DEBUG("[CREATE_PRESENTATION_SYNC] surf_source(%p) presentation_sync_fd(%d) dup(%d)", + surf_source, surf_source->presentation_sync.fd, presentation_sync_fd); - g_mutex_unlock(&surf_source->pst_mutex); - return presentation_sync_fd; - } + g_mutex_unlock(&surf_source->presentation_sync.mutex); - return -1; + return presentation_sync_fd; } static int @@ -1570,11 +1567,6 @@ __cb_merge_sync_fds(void *private, int sync_fd1, int sync_fd2) return -1; } - if (surf_source->presentation_sync_timeline == -1) { - TPL_ERR("There is no timeline for any sync fd in surf_source(%p)", surf_source); - return -1; - } - merged_fd = tbm_sync_fence_merge(NULL, sync_fd1, sync_fd2); TPL_DEBUG("[FENCE_MERGE] surf_source(%p) fence1(%d) + fence2(%d) = merged(%d)", @@ -1649,11 +1641,25 @@ __cb_twe_buffer_free_callback(twe_wl_buffer_info *buf_info) if (buf_info->commit_sync_fd != -1) { int ret = _write_to_eventfd(buf_info->commit_sync_fd); if (ret == -1) - TPL_ERR("Failed to send commit_sync signal to fd(%d)", buf_info->commit_sync_fd); + TPL_ERR("Failed to send commit_sync signal to fd(%d)", + buf_info->commit_sync_fd); close(buf_info->commit_sync_fd); buf_info->commit_sync_fd = -1; } + if (buf_info->presentation_sync_fd != -1) { + int ret = _write_to_eventfd(buf_info->presentation_sync_fd); + if (ret == -1) + TPL_ERR("Failed to send presentation_sync signal to fd(%d)", + buf_info->presentation_sync_fd); + close(buf_info->presentation_sync_fd); + buf_info->presentation_sync_fd = -1; + + if (buf_info->presentation_feedback) + wp_presentation_feedback_destroy(buf_info->presentation_feedback); + buf_info->presentation_feedback = NULL; + } + if (buf_info->sync_timeline != -1) { close(buf_info->sync_timeline); buf_info->sync_timeline = -1; @@ -1887,6 +1893,9 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info->acquire_fence_fd = -1; buf_info->commit_sync_fd = -1; + buf_info->presentation_sync_fd = -1; + buf_info->presentation_feedback = NULL; + if (surf_source->in_use_buffers) { g_mutex_lock(&surf_source->surf_mutex); __tpl_list_push_back(surf_source->in_use_buffers, @@ -1974,6 +1983,9 @@ _twe_surface_set_wl_buffer_info(twe_wl_surf_source *surf_source, buf_info->release_fence_fd = -1; buf_info->acquire_fence_fd = -1; buf_info->commit_sync_fd = -1; + buf_info->presentation_sync_fd = -1; + buf_info->presentation_feedback = NULL; + wl_buffer_add_listener((void *)buf_info->wl_buffer, &wl_buffer_release_listener, tbm_surface); @@ -2049,6 +2061,11 @@ _twe_surface_trace_enqueue_buffer(twe_wl_surf_source *surf_source, TRACE_ASYNC_BEGIN(buf_info->commit_sync_fd, "[COMMIT_SYNC] bo(%d)", tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); g_mutex_unlock(&surf_source->commit_sync.mutex); + + g_mutex_lock(&surf_source->presentation_sync.mutex); + buf_info->presentation_sync_fd = surf_source->presentation_sync.fd; + surf_source->presentation_sync.fd = -1; + g_mutex_unlock(&surf_source->presentation_sync.mutex); } if (surf_source->in_use_buffers) { @@ -2386,79 +2403,100 @@ __cb_presentation_feedback_presented(void *data, TPL_IGNORE(seq_lo); TPL_IGNORE(flags); - struct feedback_info *feedback_info = (struct feedback_info *)data; - twe_wl_surf_source *surf_source = feedback_info->surf_source; - twe_wl_disp_source *disp_source = surf_source->disp_source; - - g_mutex_lock(&surf_source->pst_mutex); + tbm_surface_h tbm_surface = (tbm_surface_h)data; + twe_wl_buffer_info *buf_info = NULL; + twe_wl_surf_source *surf_source = NULL; - TPL_DEBUG("[FEEDBACK][PRESENTED] surf_source(%p) wl_surface(%p)", - surf_source, surf_source->surf); + tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO, + (void **)&buf_info); + if (!buf_info) { + TPL_ERR("Failed to get twe_wl_buffer_info from tbm_surface(%p)", + tbm_surface); + return; + } - if (surf_source->presentation_sync_timeline != -1 && - surf_source->presentation_sync_req_cnt > 0) { + surf_source = buf_info->surf_source; - surf_source->presentation_sync_ts_backup++; - surf_source->presentation_sync_req_cnt--; + g_mutex_lock(&surf_source->presentation_sync.mutex); - TRACE_ASYNC_END(surf_source->presentation_sync_ts_backup, "[PRESENTATION]"); + TPL_DEBUG("[FEEDBACK][PRESENTED] surf_source(%p) tbm_surface(%p) bo(%d)", + surf_source, tbm_surface, + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); - TPL_DEBUG("[PRESENTATION][INC] surf_source(%p) timeline(%d) timestamp(%d)", - surf_source, surf_source->presentation_sync_timeline, - surf_source->presentation_sync_ts_backup); - if (!tbm_sync_timeline_inc(surf_source->presentation_sync_timeline, 1)) { - TPL_ERR("Failed to increase timeline(%d)", - surf_source->presentation_sync_timeline); + if (buf_info->presentation_sync_fd != -1) { + int ret = _write_to_eventfd(buf_info->presentation_sync_fd); + if (ret == -1) { + TPL_ERR("Failed to send presentation_sync signal to fd(%d)", + buf_info->presentation_sync_fd); } + + TRACE_ASYNC_END(buf_info->presentation_sync_fd, + "[PRESENTATION_SYNC] bo(%d)", + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); + + close(buf_info->presentation_sync_fd); + buf_info->presentation_sync_fd = -1; } - if (presentation_feedback) - wp_presentation_feedback_destroy(presentation_feedback); + if (buf_info->presentation_feedback) + wp_presentation_feedback_destroy(buf_info->presentation_feedback); + + buf_info->presentation_feedback = NULL; - __tpl_list_remove_data(disp_source->presentation_feedbacks, feedback_info, - TPL_FIRST, (tpl_free_func_t)free); + __tpl_list_remove_data(surf_source->presentation_feedbacks, tbm_surface, + TPL_FIRST, NULL); - g_mutex_unlock(&surf_source->pst_mutex); + g_mutex_unlock(&surf_source->presentation_sync.mutex); } static void __cb_presentation_feedback_discarded(void *data, struct wp_presentation_feedback *presentation_feedback) { - struct feedback_info *feedback_info = (struct feedback_info *)data; - twe_wl_surf_source *surf_source = feedback_info->surf_source; - twe_wl_disp_source *disp_source = surf_source->disp_source; - - g_mutex_lock(&surf_source->pst_mutex); + tbm_surface_h tbm_surface = (tbm_surface_h)data; + twe_wl_buffer_info *buf_info = NULL; + twe_wl_surf_source *surf_source = NULL; - TPL_DEBUG("[FEEDBACK][DISCARDED] surf_source(%p) wl_surface(%p)", - surf_source, surf_source->surf); + tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO, + (void **)&buf_info); + if (!buf_info) { + TPL_ERR("Failed to get twe_wl_buffer_info from tbm_surface(%p)", + tbm_surface); + return; + } - if (surf_source->presentation_sync_timeline != -1 && - surf_source->presentation_sync_req_cnt > 0) { + surf_source = buf_info->surf_source; - surf_source->presentation_sync_ts_backup++; - surf_source->presentation_sync_req_cnt--; + g_mutex_lock(&surf_source->presentation_sync.mutex); - TRACE_ASYNC_END(surf_source->presentation_sync_ts_backup, "[PRESENTATION]"); + TPL_DEBUG("[FEEDBACK][DISCARDED] surf_source(%p) tbm_surface(%p) bo(%d)", + surf_source, tbm_surface, + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); - TPL_DEBUG("[PRESENTATION][INC] surf_source(%p) timeline(%d) timestamp(%d)", - surf_source, surf_source->presentation_sync_timeline, - surf_source->presentation_sync_ts_backup); - if (!tbm_sync_timeline_inc(surf_source->presentation_sync_timeline, 1)) { - TPL_ERR("Failed to increase timeline(%d)", - surf_source->presentation_sync_timeline); + if (buf_info->presentation_sync_fd != -1) { + int ret = _write_to_eventfd(buf_info->presentation_sync_fd); + if (ret == -1) { + TPL_ERR("Failed to send presentation_sync signal to fd(%d)", + buf_info->presentation_sync_fd); } + + TRACE_ASYNC_END(buf_info->presentation_sync_fd, + "[PRESENTATION_SYNC] bo(%d)", + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); + + close(buf_info->presentation_sync_fd); + buf_info->presentation_sync_fd = -1; } - if (presentation_feedback) - wp_presentation_feedback_destroy(presentation_feedback); + if (buf_info->presentation_feedback) + wp_presentation_feedback_destroy(buf_info->presentation_feedback); - if (disp_source->presentation_feedbacks) - __tpl_list_remove_data(disp_source->presentation_feedbacks, feedback_info, - TPL_FIRST, (tpl_free_func_t)free); + buf_info->presentation_feedback = NULL; - g_mutex_unlock(&surf_source->pst_mutex); + __tpl_list_remove_data(surf_source->presentation_feedbacks, tbm_surface, + TPL_FIRST, NULL); + + g_mutex_unlock(&surf_source->presentation_sync.mutex); } static const struct wp_presentation_feedback_listener feedback_listener = { @@ -2487,23 +2525,19 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source, version = wl_proxy_get_version((struct wl_proxy *)wl_surface); - g_mutex_lock(&surf_source->pst_mutex); - if (disp_source->presentation && - surf_source->presentation_sync_req_cnt > 0) { - struct feedback_info *feedback_info = - (struct feedback_info *)calloc(1, sizeof(struct feedback_info)); - if (feedback_info) { - feedback_info->feedback = wp_presentation_feedback(disp_source->presentation, - wl_surface); - feedback_info->surf_source = surf_source; - wp_presentation_feedback_add_listener(feedback_info->feedback, - &feedback_listener, feedback_info); - if (disp_source->presentation_feedbacks) - __tpl_list_push_back(disp_source->presentation_feedbacks, - (void *)feedback_info); - } + g_mutex_lock(&surf_source->presentation_sync.mutex); + if (disp_source->presentation && buf_info->presentation_sync_fd != -1) { + buf_info->presentation_feedback = + wp_presentation_feedback(disp_source->presentation, + wl_surface); + wp_presentation_feedback_add_listener(buf_info->presentation_feedback, + &feedback_listener, tbm_surface); + __tpl_list_push_back(surf_source->presentation_feedbacks, tbm_surface); + TRACE_ASYNC_BEGIN(buf_info->presentation_sync_fd, + "[PRESENTATION_SYNC] bo(%d)", + tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0))); } - g_mutex_unlock(&surf_source->pst_mutex); + g_mutex_unlock(&surf_source->presentation_sync.mutex); if (buf_info->w_rotated == TPL_TRUE) { wayland_tbm_client_set_buffer_transform( @@ -3040,24 +3074,37 @@ _twe_thread_wl_surf_source_destroy(void *source) g_mutex_lock(&surf_source->surf_mutex); - if (disp_source->presentation && disp_source->presentation_feedbacks) { - int num_feedbacks = __tpl_list_get_count(disp_source->presentation_feedbacks); - while (num_feedbacks) { - struct feedback_info *feedback_info = __tpl_list_pop_front(disp_source->presentation_feedbacks, NULL); - if (feedback_info && surf_source == feedback_info->surf_source) { - wp_presentation_feedback_destroy(feedback_info->feedback); - feedback_info->feedback = NULL; - feedback_info->surf_source = NULL; - - free(feedback_info); - } else { - __tpl_list_push_back(disp_source->presentation_feedbacks, feedback_info); + g_mutex_lock(&surf_source->presentation_sync.mutex); + if (disp_source->presentation && surf_source->presentation_feedbacks) { + while (!__tpl_list_is_empty(surf_source->presentation_feedbacks)) { + tbm_surface_h tbm_surface = + __tpl_list_pop_front(surf_source->presentation_feedbacks, NULL); + if (tbm_surface_internal_is_valid(tbm_surface)) { + twe_wl_buffer_info *buf_info = NULL; + tbm_surface_internal_get_user_data(tbm_surface, KEY_BUFFER_INFO, + (void **)&buf_info); + if (buf_info && buf_info->presentation_sync_fd != -1 && + buf_info->presentation_feedback) { + + _write_to_eventfd(buf_info->presentation_sync_fd); + close(buf_info->presentation_sync_fd); + buf_info->presentation_sync_fd = -1; + + wp_presentation_feedback_destroy(buf_info->presentation_feedback); + buf_info->presentation_feedback = NULL; + } } - - num_feedbacks--; } } + if (surf_source->presentation_sync.fd != -1) { + _write_to_eventfd(surf_source->presentation_sync.fd); + close(surf_source->presentation_sync.fd); + surf_source->presentation_sync.fd = -1; + } + g_mutex_unlock(&surf_source->presentation_sync.mutex); + g_mutex_clear(&surf_source->presentation_sync.mutex); + if (surf_source->in_use_buffers) { __tpl_list_free(surf_source->in_use_buffers, (tpl_free_func_t)__cb_buffer_remove_from_list); @@ -3163,11 +3210,6 @@ _twe_thread_wl_surf_source_destroy(void *source) surf_source->surf = NULL; } - if (surf_source->presentation_sync_timeline >= 0) { - close(surf_source->presentation_sync_timeline); - surf_source->presentation_sync_timeline = -1; - } - g_mutex_lock(&surf_source->commit_sync.mutex); g_mutex_unlock(&surf_source->commit_sync.mutex); g_mutex_clear(&surf_source->commit_sync.mutex); @@ -3263,10 +3305,12 @@ twe_surface_add(twe_thread* thread, source->commit_sync.fd = -1; g_mutex_init(&source->commit_sync.mutex); - source->presentation_sync_timeline = tbm_sync_timeline_create(); - source->presentation_sync_timestamp = 0; - source->presentation_sync_ts_backup = 0; - source->presentation_sync_req_cnt = 0; + source->presentation_sync.fd = -1; + g_mutex_init(&source->presentation_sync.mutex); + if (disp_source->presentation) + source->presentation_feedbacks = __tpl_list_alloc(); + else + source->presentation_feedbacks = NULL; if (!disp_source->is_vulkan_dpy) { struct wl_egl_window *wl_egl_window = @@ -3328,7 +3372,6 @@ twe_surface_add(twe_thread* thread, g_source_attach(&source->gsource, g_main_loop_get_context(ctx->twe_loop)); g_mutex_init(&source->surf_mutex); - g_mutex_init(&source->pst_mutex); g_mutex_init(&source->free_queue_mutex); g_cond_init(&source->free_queue_cond);