From 14e97c17ce2c5ffd375999b51ac41e0291d57ace Mon Sep 17 00:00:00 2001 From: "joonbum.ko" Date: Thu, 4 May 2017 12:42:11 +0900 Subject: [PATCH] tpl_wayland_egl_thread: Added implementation about waiting vblank event. Change-Id: Idc206c2be1b410fdbeea30b6c5de138810a8fc14 Signed-off-by: joonbum.ko --- src/tpl_wayland_egl_thread.c | 136 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 115 insertions(+), 21 deletions(-) diff --git a/src/tpl_wayland_egl_thread.c b/src/tpl_wayland_egl_thread.c index 5cd4159..b4601c1 100644 --- a/src/tpl_wayland_egl_thread.c +++ b/src/tpl_wayland_egl_thread.c @@ -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; -- 2.7.4