re-implement presentation sync without using sync_timeline. 96/249896/1
authorJoonbum Ko <joonbum.ko@samsung.com>
Tue, 15 Dec 2020 10:53:09 +0000 (19:53 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Thu, 17 Dec 2020 07:44:18 +0000 (16:44 +0900)
Change-Id: I999a56996081ac7b1706ca6ba9226b36e9b6f3d5
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/tpl_wayland_egl_thread.c

index fa92a87..4c7f2f9 100755 (executable)
@@ -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);