tpl_wayland_egl_thread: Implemented the render sync feature. 48/219548/1
authorJoonbum Ko <joonbum.ko@samsung.com>
Tue, 12 Nov 2019 02:27:07 +0000 (11:27 +0900)
committerJoonbum Ko <joonbum.ko@samsung.com>
Fri, 6 Dec 2019 01:55:18 +0000 (10:55 +0900)
 - Create a timeline in surface units and create a sync fence to pass to the user.
 - The sync fence user get is signaled at the time of tpl surface enqueue.
 - This feature can help user sync by telling gpu render done,
  but this feature alone does not guarantee sync.
   Therefore, users should handle this sync_fence properly using poll or select.

Change-Id: If1c8a894fc8e103141b88d4479274f926753e52f
Signed-off-by: Joonbum Ko <joonbum.ko@samsung.com>
src/tpl_wayland_egl_thread.c

index dca6597..101cf8f 100755 (executable)
@@ -78,6 +78,7 @@ struct _twe_wl_disp_source {
        twe_del_source *disp_del_source;
        twe_thread *thread;
        GMutex wl_event_mutex;
+
        /* TODO : surface list */
 };
 
@@ -120,6 +121,10 @@ struct _twe_wl_surf_source {
        twe_wl_disp_source *disp_source;
        twe_del_source *surf_del_source;
 
+       tbm_fd render_sync_timeline;
+       int render_sync_timestamp;
+       unsigned int render_sync_fence_number;
+
        GMutex surf_mutex;
 
        GMutex free_queue_mutex;
@@ -1221,6 +1226,41 @@ __cb_set_window_serial_callback(struct wl_egl_window *wl_egl_window,
        }
 }
 
+static int
+__cb_create_render_sync_fd(struct wl_egl_window *wl_egl_window, void *private)
+{
+       TPL_ASSERT(private);
+       TPL_ASSERT(wl_egl_window);
+
+       struct tizen_private *tizen_private = (struct tizen_private *)private;
+       twe_wl_surf_source *surf_source = NULL;
+
+       tbm_fd render_sync_fd = -1;
+
+       surf_source = (twe_wl_surf_source *)tizen_private->data;
+       if (!surf_source) {
+               TPL_ERR("Invalid parameter. twe_surface(%p)", surf_source);
+               return -1;
+       }
+
+       if (surf_source->render_sync_timeline != -1) {
+               char name[32];
+               snprintf(name, 32, "%u", surf_source->render_sync_fence_number++);
+               render_sync_fd = tbm_sync_fence_create(surf_source->render_sync_timeline,
+                                                                                          name,
+                                                                                          surf_source->render_sync_timestamp + 1);
+               TPL_DEBUG("[RENDER_SYNC] surf_source(%p) timeline(%d) timestamp(%d) name(%s) sync_fence(%d)",
+                                 surf_source, surf_source->render_sync_timeline, surf_source->render_sync_timestamp,
+                                 name, render_sync_fd);
+
+               TRACE_ASYNC_BEGIN(surf_source->render_sync_timestamp + 1, "[SYNC_FENCE]");
+
+               return render_sync_fd;
+       }
+
+       return -1;
+}
+
 
 static void __cb_tss_flusher_flush_callback(void *data,
                struct tizen_surface_shm_flusher *tss_flusher)
@@ -1554,6 +1594,18 @@ _twe_surface_trace_enqueue_buffer(twe_wl_surf_source *surf_source,
                return;
        }
 
+       if (surf_source->render_sync_timeline != -1) {
+
+               surf_source->render_sync_timestamp++;
+               TRACE_ASYNC_END(surf_source->render_sync_timestamp, "[SYNC_FENCE]");
+
+               TPL_DEBUG("[RENDER_SYNC][INC] surf_source(%p) timeline(%d) timestamp(%d)",
+                                 surf_source, surf_source->render_sync_timeline, surf_source->render_sync_timestamp);
+               if (!tbm_sync_timeline_inc(surf_source->render_sync_timeline, 1)) {
+                       TPL_ERR("Failed to increase timeline(%d)", surf_source->render_sync_timeline);
+               }
+       }
+
        if (surf_source->in_use_buffers) {
                g_mutex_lock(&surf_source->surf_mutex);
                /* Stop tracking of this canceled tbm_surface */
@@ -2502,6 +2554,10 @@ twe_surface_add(twe_thread* thread,
 
        source->post_interval = 1;
 
+       source->render_sync_timeline = tbm_sync_timeline_create();
+       source->render_sync_timestamp = 0;
+       source->render_sync_fence_number = 0;
+
        if (!disp_source->is_vulkan_dpy) {
                struct wl_egl_window *wl_egl_window =
                        (struct wl_egl_window *)native_handle;
@@ -2521,6 +2577,7 @@ twe_surface_add(twe_thread* thread,
                                __cb_get_rotation_capability;
                        private->set_window_serial_callback = (void *)
                                __cb_set_window_serial_callback;
+                       private->create_render_sync_fd = (void *)__cb_create_render_sync_fd;
 
                        source->latest_transform = private->transform;