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;
};
twe_thread_create(void)
{
twe_thread *thread;
+ char *env = getenv("TPL_WAIT_VBLANK");
if (!_twe_ctx) {
GMainContext *context;
_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));
}
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)
{
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
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);
}
.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,
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;
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;