tpl_wayland_egl_thread: Added implementation about waiting vblank event. 86/134986/3
authorjoonbum.ko <joonbum.ko@samsung.com>
Thu, 4 May 2017 03:42:11 +0000 (12:42 +0900)
committerjoonbum.ko <joonbum.ko@samsung.com>
Wed, 21 Jun 2017 07:04:26 +0000 (16:04 +0900)
Change-Id: Idc206c2be1b410fdbeea30b6c5de138810a8fc14
Signed-off-by: joonbum.ko <joonbum.ko@samsung.com>
src/tpl_wayland_egl_thread.c

index 5cd4159..b4601c1 100644 (file)
@@ -74,6 +74,8 @@ struct _twe_wl_surf_source {
        struct wl_egl_window *wl_egl_window;
        int rotation;
        tpl_bool_t rotation_capability;
+       tpl_bool_t vblank_done;
+       tdm_client_vblank *vblank;
        tbm_surface_queue_h tbm_queue;
        twe_wl_disp_source *disp_source;
 };
@@ -136,6 +138,7 @@ twe_thread*
 twe_thread_create(void)
 {
        twe_thread *thread;
+       char *env = getenv("TPL_WAIT_VBLANK");
 
        if (!_twe_ctx) {
                GMainContext *context;
@@ -146,31 +149,44 @@ twe_thread_create(void)
                _twe_ctx->twe_loop = g_main_loop_new(context, FALSE);
                g_main_context_unref(context);
 
-               _twe_ctx->twe_thread = g_thread_new("twe_thread", _twe_thread_loop, _twe_ctx);
+               _twe_ctx->twe_thread = g_thread_new("twe_thread", _twe_thread_loop,
+                                                                                       _twe_ctx);
 
-               /*Connect to tdm server*/
-               _twe_ctx->tdm_client = tdm_client_create(&tdm_err);
-               if (!_twe_ctx->tdm_client) {
-                       TPL_ERR("Failed to create tdm_client\n");
-               }
-
-               _twe_ctx->tdm_fd = tdm_client_get_fd(_twe_ctx->tdm_client, &_twe_ctx->tdm_fd);
-               if (_twe_ctx->tdm_fd < 0) {
-                       TPL_ERR("Failed to get tdm_client fd\n");
-               } else {
-                       _twe_ctx->tdm_gsource = g_unix_fd_source_new(_twe_ctx->tdm_fd, G_IO_IN);
-                       if (!_twe_ctx->tdm_gsource) {
-                               TPL_ERR("Failed to create tdm_gsource\n");
+               if (env == NULL || atoi(env)) {
+                       /*Connect to tdm server*/
+                       _twe_ctx->tdm_client = tdm_client_create(&tdm_err);
+                       if (!_twe_ctx->tdm_client) {
+                               TPL_ERR("Failed to create tdm_client\n");
                        }
 
-                       g_source_set_callback(_twe_ctx->tdm_gsource,
-                                                               _twe_thread_tdm_source_dispatch,
-                                                               _twe_ctx,
-                                                               _twe_thread_tdm_source_destroy);
-                       g_source_attach(_twe_ctx->tdm_gsource, g_main_loop_get_context(_twe_ctx->twe_loop));
-                       TPL_LOG_T("WL_EGL", "tdm g_source(%p) attached to twe_loop(%p)",
-                                         _twe_ctx->tdm_gsource, _twe_ctx->twe_loop);
+                       TPL_LOG_T("WL_EGL", "TPL_WAIT_VBLANK:DEFAULT_ENABLED");
+
+                       _twe_ctx->tdm_fd = tdm_client_get_fd(_twe_ctx->tdm_client,
+                                                                                                &_twe_ctx->tdm_fd);
+                       if (_twe_ctx->tdm_fd < 0) {
+                               TPL_ERR("Failed to get tdm_client fd\n");
+                               tdm_client_destroy(_twe_ctx->tdm_client);
+                       } else {
+                               _twe_ctx->tdm_gsource = g_unix_fd_source_new(_twe_ctx->tdm_fd,
+                                                                                                                        G_IO_IN);
+                               if (!_twe_ctx->tdm_gsource) {
+                                       TPL_ERR("Failed to create tdm_gsource\n");
+                                       tdm_client_destroy(_twe_ctx->tdm_client);
+                               }
+
+                               g_source_set_callback(_twe_ctx->tdm_gsource,
+                                                                         _twe_thread_tdm_source_dispatch,
+                                                                         _twe_ctx,
+                                                                         _twe_thread_tdm_source_destroy);
+                               g_source_attach(_twe_ctx->tdm_gsource,
+                                                               g_main_loop_get_context(_twe_ctx->twe_loop));
+                               TPL_LOG_T("WL_EGL", "tdm g_source(%p) attached to twe_loop(%p)",
+                                               _twe_ctx->tdm_gsource, _twe_ctx->twe_loop);
+                       }
+               } else {
+                       TPL_LOG_T("WL_EGL", "TPL_WAIT_VBLANK:DISABLED");
                }
+
        }
 
        thread = calloc(1, sizeof(twe_thread));
@@ -469,6 +485,21 @@ __cb_tbm_queue_acquirable_callback(tbm_surface_queue_h surface_queue,
 }
 
 static void
+__cb_tdm_client_wait_vblank(tdm_client_vblank *vblank, tdm_error error,
+                                                       unsigned int sequence, unsigned int tv_sec,
+                                                       unsigned int tv_usec, void *user_data)
+{
+       twe_wl_surf_source *surf_source = (twe_wl_surf_source *)user_data;
+
+       if (!surf_source) {
+               TPL_ERR("Invalid parameter. user_data(%p)", user_data);
+               return;
+       }
+
+       surf_source->vblank_done = TPL_TRUE;
+}
+
+static void
 _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source,
                                                          tbm_surface_h tbm_surface)
 {
@@ -513,6 +544,19 @@ _twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source,
        TPL_LOG_T("WL_EGL", "[COMMIT] wl_buffer(%p) tbm_surface(%p) bo(%d)",
                          buf_info->wl_buffer, tbm_surface,
                          tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
+
+       if (_twe_ctx->tdm_client && surf_source->vblank) {
+               tdm_error tdm_err = TDM_ERROR_NONE;
+               tdm_err = tdm_client_vblank_wait(surf_source->vblank,
+                                                                                1, /* TODO: interval */
+                                                                                __cb_tdm_client_wait_vblank,
+                                                                                (void *)surf_source);
+
+               if (tdm_err == TDM_ERROR_NONE)
+                       surf_source->vblank_done = TPL_FALSE;
+               else
+                       TPL_ERR("Failed to tdm_client_vblank_wait. tdm_err(%d)", tdm_err);
+       }
 }
 
 static void
@@ -539,6 +583,16 @@ _twe_thread_wl_surface_acquire_and_commit(twe_wl_surf_source *surf_source)
                          tbm_surface,
                          tbm_bo_export(tbm_surface_internal_get_bo(tbm_surface, 0)));
 
+       while (!surf_source->vblank_done) {
+               tdm_error tdm_err = TDM_ERROR_NONE;
+
+               tdm_err = tdm_client_handle_events(_twe_ctx->tdm_client);
+               if (tdm_err != TDM_ERROR_NONE) {
+                       TPL_ERR("Failed to tdm_client_handle_events.");
+                       break;
+               }
+       }
+
        _twe_thread_wl_surface_commit(surf_source, tbm_surface);
 }
 
@@ -588,6 +642,38 @@ static GSourceFuncs _twe_wl_surface_funcs = {
        .finalize = _twe_thread_wl_surface_finalize,
 };
 
+static tdm_client_vblank*
+_twe_surface_create_vblank(tdm_client *tdm_client)
+{
+       tdm_client_vblank *vblank = NULL;
+       tdm_client_output *tdm_output = NULL;
+       tdm_error tdm_err = TDM_ERROR_NONE;
+
+       if (!tdm_client) {
+               TPL_ERR("Invalid parameter. tdm_client(%p)", tdm_client);
+               return NULL;
+       }
+
+       tdm_output = tdm_client_get_output(tdm_client, "primary", &tdm_err);
+       if (!tdm_output || tdm_err != TDM_ERROR_NONE) {
+               TPL_ERR("Failed to get tdm_client_output. tdm_err(%d)", tdm_err);
+               return NULL;
+       }
+
+       vblank = tdm_client_output_create_vblank(tdm_output, &tdm_err);
+       if (!vblank || tdm_err != TDM_ERROR_NONE) {
+               TPL_ERR("Failed to create vblank. tdm_err(%d)", tdm_err);
+               return NULL;
+       }
+
+       tdm_client_vblank_set_enable_fake(vblank, 1);
+       tdm_client_vblank_set_sync(vblank, 0);
+
+       TPL_LOG_T("WL_EGL", "[VBLANK INIT] vblank(%p)", vblank);
+
+       return vblank;
+}
+
 static tbm_surface_queue_h
 _twe_surface_create_tbm_queue(twe_wl_surf_source *source,
                                                          struct wayland_tbm_client *wl_tbm_client,
@@ -709,6 +795,8 @@ twe_surface_add(twe_thread* thread,
        source->disp_source = (twe_wl_disp_source *)twe_display;
        source->rotation = 0;
        source->rotation_capability = TPL_FALSE;
+       source->vblank = _twe_surface_create_vblank(_twe_ctx->tdm_client);
+       source->vblank_done = TPL_TRUE;
 
        wl_egl_window->private = (void *)source;
        wl_egl_window->resize_callback = (void *)__cb_resize_callback;
@@ -757,6 +845,12 @@ twe_surface_del(twe_surface_h twe_surface)
                surf_source->tbm_queue = NULL;
        }
 
+       if (surf_source->vblank) {
+               TPL_LOG_T("WL_EGL", "[VBLANK FINI] twe_wl_surf_source(%p) vblank(%p)",
+                                 surf_source, surf_source->vblank);
+               tdm_client_vblank_destroy(surf_source->vblank);
+       }
+
        /* TODO : surf_source will be removed from surfaces list in disp_source */
 
        surf_source->wl_egl_window = NULL;