typedef struct _twe_wl_disp_source twe_wl_disp_source;
typedef struct _twe_wl_surf_source twe_wl_surf_source;
typedef struct _twe_wl_buffer_info twe_wl_buffer_info;
+typedef struct _twe_tdm_source twe_tdm_source;
struct _twe_thread_context {
int ref_cnt;
GThread *twe_thread;
GMainLoop *twe_loop;
- /*TDM*/
- tdm_client *tdm_client;
- int tdm_fd;
- GSource *tdm_gsource;
+ twe_tdm_source *tdm_source;
};
struct _twe_thread {
/* TODO : display list */
};
+struct _twe_tdm_source {
+ GSource gsource;
+ gpointer tag;
+ tdm_client *tdm_client;
+ int tdm_fd;
+};
+
struct _twe_wl_disp_source {
GSource gsource;
GPollFD gfd;
struct wl_egl_window *wl_egl_window;
int rotation;
tpl_bool_t rotation_capability;
- tpl_bool_t vblank_done;
tpl_object_t obj; /* for mutex lock */
tpl_list_t *committed_buffers;
tpl_list_t *in_use_buffers;
tdm_client_vblank *vblank;
+ tpl_bool_t vblank_done;
struct tizen_surface_shm_flusher *tss_flusher;
tbm_surface_queue_h tbm_queue;
twe_wl_disp_source *disp_source;
};
static twe_thread_context *_twe_ctx;
+static twe_tdm_source *
+_twe_thread_tdm_source_create(void);
static gpointer
_twe_thread_loop(gpointer data)
{
twe_thread_context *ctx = data;
+ char *env = getenv("TPL_WAIT_VBLANK");
+
+ if (env == NULL || atoi(env)) {
+ twe_tdm_source *tdm_source = _twe_thread_tdm_source_create();
+
+ if (tdm_source) {
+ g_source_attach(&tdm_source->gsource,
+ g_main_loop_get_context(ctx->twe_loop));
+ g_source_unref(&tdm_source->gsource);
+ }
+
+ _twe_ctx->tdm_source = tdm_source;
+
+ if (!ctx->tdm_source) {
+ TPL_WARN("Failed to create tdm_source. TPL_WAIT_VLANK:DISABLED");
+ }
+ }
g_main_loop_run(ctx->twe_loop);
}
static gboolean
-_twe_thread_tdm_source_dispatch(gpointer user_data)
+_twe_thread_tdm_source_dispatch(GSource *source, GSourceFunc cb, gpointer data)
{
- twe_thread_context* context = user_data;
+ twe_tdm_source *tdm_source = (twe_tdm_source *)source;
tdm_error tdm_err;
+ GIOCondition cond;
- TPL_LOG_T("WL_EGL", "tdm_dispatch| tdm_client(%p)", context->tdm_client);
- tdm_err = tdm_client_handle_events(context->tdm_client);
- if (tdm_err) {
- TPL_ERR("TDM_ERROR:%d context:%p, tdm_cleint:%p\n", tdm_err, context, context->tdm_client);
+ if (!source || g_source_is_destroyed(source)) {
+ TPL_ERR("TDM source(%p) already destroyed.", source);
return G_SOURCE_REMOVE;
}
+ cond = g_source_query_unix_fd(source, tdm_source->tag);
+
+ if (cond & G_IO_IN) {
+ tdm_err = tdm_client_handle_events(tdm_source->tdm_client);
+ if (tdm_err != TDM_ERROR_NONE) {
+ TPL_ERR("TDM_ERROR:%d tdm_client:%p\n",
+ tdm_err, tdm_source->tdm_client);
+ return G_SOURCE_REMOVE;
+ }
+ }
+
return G_SOURCE_CONTINUE;
}
static void
-_twe_thread_tdm_source_destroy(gpointer user_data)
+_twe_thread_tdm_source_finalize(GSource *source)
{
- twe_thread_context* context = user_data;
+ twe_tdm_source *tdm_source = (twe_tdm_source *)source;
+
+ TPL_LOG_T("WL_EGL", "tdm_destroy| tdm_source(%p) tdm_client(%p)",
+ tdm_source, tdm_source->tdm_client);
- TPL_LOG_T("WL_EGL", "tdm_destroy| tdm_gsource(%p) tdm_client(%p)",
- context->tdm_gsource, context->tdm_client);
- g_source_destroy(context->tdm_gsource);
- g_source_unref(context->tdm_gsource);
- context->tdm_gsource = NULL;
+ if (tdm_source->tdm_client) {
+ tdm_client_destroy(tdm_source->tdm_client);
+ tdm_source->tdm_client = NULL;
+ }
- tdm_client_destroy(context->tdm_client);
- context->tdm_client = NULL;
+ tdm_source->tdm_fd = -1;
+}
+
+static GSourceFuncs _twe_tdm_funcs = {
+ .prepare = NULL,
+ .check = NULL,
+ .dispatch = _twe_thread_tdm_source_dispatch,
+ .finalize = _twe_thread_tdm_source_finalize,
+};
+
+static twe_tdm_source *
+_twe_thread_tdm_source_create(void)
+{
+ twe_tdm_source *tdm_source = NULL;
+ tdm_client *client = NULL;
+ int tdm_fd = -1;
+ tdm_error tdm_err = TDM_ERROR_NONE;
+
+ client = tdm_client_create(&tdm_err);
+ if (!client || tdm_err != TDM_ERROR_NONE) {
+ TPL_ERR("TDM_ERROR:%d Failed to create tdm_client\n", tdm_err);
+ return NULL;
+ }
+
+ tdm_err = tdm_client_get_fd(client, &tdm_fd);
+ if (tdm_fd < 0 || tdm_err != TDM_ERROR_NONE) {
+ TPL_ERR("TDM_ERROR:%d Failed to get tdm_client fd\n", tdm_err);
+ tdm_client_destroy(client);
+ return NULL;
+ }
+
+ tdm_source = (twe_tdm_source *)g_source_new(&_twe_tdm_funcs,
+ sizeof(twe_tdm_source));
+ if (!tdm_source) {
+ TPL_ERR("Failed to create tdm_gsource\n");
+ tdm_client_destroy(client);
+ return NULL;
+ }
+
+ tdm_source->tdm_client = client;
+ tdm_source->tdm_fd = tdm_fd;
+ tdm_source->tag = g_source_add_unix_fd(&tdm_source->gsource,
+ tdm_fd,
+ G_IO_IN);
+
+ TPL_LOG_T("WL_EGL", "TPL_WAIT_VBLANK:DEFAULT_ENABLED");
+ TPL_LOG_T("WL_EGL", "tdm_source(%p) tdm_client(%p) tdm_fd(%d)",
+ tdm_source, client, tdm_fd);
+
+ return tdm_source;
+}
+
+static void
+_twe_thread_tdm_source_destroy(twe_tdm_source *tdm_source)
+{
+ if (!tdm_source || g_source_is_destroyed(&tdm_source->gsource)) {
+ TPL_ERR("TDM source(%p) already destroyed.", tdm_source);
+ return;
+ }
+
+ g_source_destroy(&tdm_source->gsource);
+ g_source_unref(&tdm_source->gsource);
}
twe_thread*
twe_thread_create(void)
{
twe_thread *thread;
- char *env = getenv("TPL_WAIT_VBLANK");
if (!_twe_ctx) {
GMainContext *context;
- tdm_error tdm_err = TDM_ERROR_NONE;
_twe_ctx = calloc(1, sizeof(twe_thread_context));
context = g_main_context_new();
_twe_ctx->twe_thread = g_thread_new("twe_thread", _twe_thread_loop,
_twe_ctx);
-
- 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");
- }
-
- 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,
- NULL,
- NULL);
- 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));
thread->ctx->ref_cnt--;
if (thread->ctx->ref_cnt == 0) {
- if (thread->ctx->tdm_gsource) {
- _twe_thread_tdm_source_destroy(thread->ctx);
+ if (thread->ctx->tdm_source) {
+ _twe_thread_tdm_source_destroy(thread->ctx->tdm_source);
+ thread->ctx->tdm_source = NULL;
}
g_main_loop_quit(thread->ctx->twe_loop);
}
static gboolean
-_twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer date)
+_twe_thread_wl_disp_dispatch(GSource *source, GSourceFunc cb, gpointer data)
{
twe_wl_disp_source *disp_source = (twe_wl_disp_source *)source;
surf_source->vblank_done = TPL_TRUE;
}
+static tdm_client_vblank*
+_twe_surface_create_vblank(tdm_client *tdm_client);
+
static void
_twe_thread_wl_surface_commit(twe_wl_surf_source *surf_source,
tbm_surface_h tbm_surface)
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) {
+ if (_twe_ctx->tdm_source && !surf_source->vblank) {
+ surf_source->vblank =
+ _twe_surface_create_vblank(_twe_ctx->tdm_source->tdm_client);
+ if (!surf_source->vblank) {
+ TPL_WARN("Failed to create vblank. surf_source(%p)",
+ surf_source);
+ }
+ }
+
+ if (_twe_ctx->tdm_source && surf_source->vblank) {
tdm_error tdm_err = TDM_ERROR_NONE;
tdm_err = tdm_client_vblank_wait(surf_source->vblank,
1, /* TODO: interval */
while (!surf_source->vblank_done) {
tdm_error tdm_err = TDM_ERROR_NONE;
- tdm_err = tdm_client_handle_events(_twe_ctx->tdm_client);
+ tdm_err = tdm_client_handle_events(_twe_ctx->tdm_source->tdm_client);
if (tdm_err != TDM_ERROR_NONE) {
TPL_ERR("Failed to tdm_client_handle_events.");
break;
}
static gboolean
-_twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer date)
+_twe_thread_wl_surface_dispatch(GSource *source, GSourceFunc cb, gpointer data)
{
twe_wl_surf_source *wl_surf_source = (twe_wl_surf_source *)source;
GIOCondition cond;
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 = NULL;
source->vblank_done = TPL_TRUE;
source->committed_buffers = __tpl_list_alloc();
source->in_use_buffers = __tpl_list_alloc();